Slide 1
Slide 2
Slide 3
Modular architecture
Classes and components
Slide 4
Modular architecture classes and
Components and modifiers
Slide 5
Modular architecture classes and
Components, modifiers and overrides
Slide 6
Modular architecture classes, modifiers and overrides
Components, patterns and sh*t it’s hard to deal with
Slide 7
@cedmax Webmaster before it was cool
Tech Lead Condé Nast International
Slide 8
Components, patterns and sh*t it’s hard to deal with
Slide 9
Components, patterns and sh*t it’s hard to deal with
or… How
I came up with a good use of quotes from Lost in Translation
Slide 10
Lost in Translation? Basically
Slide 11
Disclaimer
“This movie is an hour and some odd minutes of my life I will never get back.” JoeB. on Metacritic
Slide 12
Lost in Translation
“Meaning is complex and often gets lost in translation. Everybody has their own mental model of things” Alla Kholmatova
Slide 13
Slide 14
Slide 15
Slide 16
Atomic design
Brad Frost · October 2013
Slide 17
Web components
announced in November 2011
Slide 18
Pattern Library “Pattern libraries are something I do a lot for client projects. It’s a technique I first saw Natalie Downe develop for client projects back in 2009” […]
[…]
Anna Debenham
Slide 19
MISSING SLIDE* ABOUT PATTERN LIBRARIES * on purpose, I promise
Slide 20
Pattern Library “Pattern libraries are something I do a lot for client projects. It’s a technique I first saw Natalie Downe develop for client projects back in 2009” […]
[…]
Anna Debenham
Slide 21
ReactJS
First release: March 2013
Slide 22
Slide 23
Frame the issue Basically
Slide 24
It's not that simple
“When you actually try to apply a modular approach to your day to day work, it isn’t really that simple” Alla Kholmatova · June 2015
Slide 25
Slide 26
The issue
How do we manage our code, to re-use patterns without making them too rigid for the day to day activities?
Slide 27
The issue How do we manage our code, to re-use patterns without making them too rigid for the day to day activities?
How do we re-use our patterns in slightly different use cases?
Slide 28
Slide 29
It’s NOT about any specific tech stack or module implementation: most of the patterns can be applied with BEM, styled components, css modules… * It’s about modularity at its core It’s about modules responsibilities It’s about maintainability (among other coding practices)
Slide 30
Classname injection
I'll be in the bar for the rest of the week
Slide 31
<IconButton className="content-actions__button" iconId="close" />
Slide 32
<IconButton className="content-actions__button" iconId="close" />
Slide 33
//_content-actions.scss .content-actions { //[...] &__button { flex: 1 0 auto; padding: 1rem; line-height: 1.5; &:hover, &:focus { background: $grey-1; } &:active { background: $grey-2; } } }
Slide 34
//_content-actions.scss .content-actions { //[...] &__button { flex: 1 0 auto; padding: 1rem; line-height: 1.5; &:hover, &:focus { background: $grey-1; } &:active { background: $grey-2; } } }
Slide 35
//_content-actions.scss .content-actions { //[...] &__button { flex: 1 0 auto; padding: 1rem; line-height: 1.5; &:hover, &:focus { background: $grey-1; } &:active { background: $grey-2; } } }
What's the effect on the base button?
Slide 36
//_content-actions.scss .content-actions { //[...] &__button { flex: 1 0 auto; padding: 1rem; line-height: 1.5; &:hover, &:focus { background: $grey-1; } &:active { background: $grey-2; } } }
Why is this button different from the pattern library ones?
Slide 37
What works
This is the most flexible way to extend anything.
Slide 38
What really doesn't
1.
The default style could be overridden in unexpected ways.
2.
We are creating many variants of the original patterns.
Slide 39
Ad hoc modifiers
- You're too tall. - Anybody ever tell you you may be too small?
Slide 40
<Dialog className="dialog--user-intent"> <!-- [...] --> </Dialog>
Slide 41
<Dialog className="dialog--user-intent"> <!-- [...] --> </Dialog>
Slide 42
//_dialog.scss .dialog { //[...] &--user-intent { width: 43.75rem; height: auto; } }
Slide 43
//_dialog.scss .dialog { //[...] &--user-intent { width: 43.75rem; height: auto; } }
Slide 44
//_dialog.scss .dialog { //[...] &--wizard { width: 43.75rem; height: 35rem; } &--game-intent { width: 43.75rem; height: auto; } &--save-results { width: 23.75rem; height: auto; } }
How many variants do we have to account for?
Slide 45
What works
This practice allows for flexibility, giving a reasonable control and keeping all the variants in proximity.
Slide 46
What really doesn't 1.
The generic component style have knowledge of specific implementations.
2.
The file size might be effected by unused code.
3.
It doesn't scale
Slide 47
Specialised patterns
I'm special
Slide 48
<Dialog className="dialog--prompt"> <!-- [...] --> </Dialog>
Slide 49
<Dialog className="dialog--prompt"> <!-- [...] --> </Dialog>
Slide 50
//_dialog.scss .dialog { //[...] &--prompt { display: block; overflow: hidden; max-width: map-get($dialog-prompt, max-width); height: auto; margin: map-get($dialog-prompt, margin); padding: 2rem 0 0; border-radius: 3px; } }
Slide 51
//_dialog.scss .dialog { //[...]
The semantic value of the modifiers is different from the ad-hoc ones.
&--prompt { display: block; overflow: hidden; max-width: map-get($dialog-prompt, max-width); height: auto; margin: map-get($dialog-prompt, margin); padding: 2rem 0 0; border-radius: 3px; } }
Slide 52
What works
The patterns are at the centre: no special cases, but pre-defined flavours of the basic components.
Slide 53
What really doesn't
1.
It might drive to preemptive abstraction
2.
It does account for a finite number of use cases
Slide 54
<Dialog className="dialog--prompt"> <!-- [...] --> </Dialog> <Dialog type="prompt" /> <DialogPrompt />
Slide 55
Classname injection
Ad hoc modifiers
Specialised patterns
A no go: it defies the point of having a pattern library
A code smell, it's an hack and it should be treated like one
The best approach, even though sometimes
I still wish I could sleep
Slide 56
Slide 57
It's not that simple
“It isn’t really that simple” Alla Kholmatova · June 2015
Slide 58
The issue
How do we re-use our patterns in slightly different use cases?
Slide 59
What am I trying to solve?
Slide 60
Arrangement within parent components
Slide 61
<div className="game-intent__dialog"> <Dialog> <!-- [...] --> </Dialog> </div>
Slide 62
<div className="game-intent__dialog"> <Dialog> <!-- [...] --> </Dialog> </div>
Slide 63
//_dialog.scss .dialog { width: 100%; height: 100%; //[...] } //_game-intent.scss .game-intent { //[...] &__dialog { width: 43.75rem; height: auto; } }
Slide 64
//_dialog.scss .dialog { width: 100%; height: 100%; //[...] } //_game-intent.scss .game-intent { //[...] &__dialog { width: 43.75rem; height: auto; } }
Each component has its own responsibility
Slide 65
What works
This practices defines responsibilities in a neat way and it enables for specific implementations without invalidating patterns.
Slide 66
<Dialog className="custom-class"> <!-- [...] --> </Dialog> <div className="custom-class"> <Dialog> <!-- [...] --> </Dialog> </div>
Slide 67
What really doesn't
Potentially you might need a wrapper HTML element that could have been avoided.
Slide 68
Space in relation to other components
Slide 69
<Dialog className="space-max inner-space-min"> <!-- [...] --> </Dialog>
Slide 70
<Dialog className="space-max inner-space-min"> <!-- [...] --> </Dialog>
Slide 71
What works
It reduces the need to come up with new class names and it moves the conversation regarding component relationships back to the pattern library.
Slide 72
What really doesn't 1.
The positional classes might get stale if not codified properly in the pattern lib.
2.
The flexibility of the helper classes is limited
3.
Do you like atomic css? https://acss.io/
Slide 73
<Dialog className="M(defSpace) P(defSpace)"> <!-- [...] --> </Dialog>
Slide 74
Slide 75
//_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] .icon { width: $content-block-icon-large-size; height: $content-block-icon-large-size; } }
Slide 76
//_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] .icon { width: $content-block-icon-large-size; height: $content-block-icon-large-size; } }
Slide 77
//_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] @include icon-size($content-block-icon-medium-size); } } //_icon.scss @mixin icon-size($size) { .icon { width: $size; height: $size; } }
Slide 78
//_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] @include icon-size($content-block-icon-medium-size); } } //_icon.scss @mixin icon-size($size) { .icon { width: $size; height: $size; } }
Slide 79
//_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] @include icon-size($content-block-icon-medium-size); } } //_icon.scss @mixin icon-size($size) { .icon { width: $size; height: $size; } }
The responsibility of being flexible it back to the component itself
Slide 80
Slide 81
What works
1.
Every base component can be as flexible as it defines itself to be.
2.
Developers always have control on what they expose.
Slide 82
What really doesn't 1.
This technique involves more complexity in thinking about the components
2.
It's a slippery slope
3.
How does an "open" component fit in the patterns?
Slide 83
Does it get easier? Basically
Slide 84
Slide 85
The more you know who you are and what you want, the less you let things upset you
Slide 86
I just don't know what I'm supposed to be
Slide 87
“A common language is a first step towards communication across cultural boundaries. ” Ethan Zuckerman
Slide 88
The issue
How to understand - and convey the meaning of an exception in our patterns?
Slide 89
Learn what the pattern your are building is supposed to be
Slide 90
Slide 91
Slide 92
Slide 93
You are not hopeless marco@fromthefront.it http://cedmax.com @cedmax