Components, patterns and sh*t it’s hard to deal with @ Front Trends 2017

Components, patterns and sh*t it’s hard to deal with @ Front Trends 2017

Everyone has a pattern library or dreams about having one. We went through conversations and the codification of our visual dictionary and then we ended up with a beautiful living document.

But what happens when we need to re-use our components and they don’t fit in the design? How do we re-use our patterns in slightly different use cases?

We have all the tech to make a front end really modular, we have techniques and methodologies which enabled us avoiding the bad parts of the languages we use. Every part of the puzzle seems to be falling in the right place.

Yet, sometimes we are struggling in handling the variations of our patterns in a reliable and maintainable way. Our codebase is getting filled with exceptions and overrides and refactoring of base patterns becomes impossible. This talk will explain some techniques to get back control and why the might work or not in the way we’d expect.

3ca63d4e2f2be0ef47b841e63b564d18?s=128

Marco Cedaro

May 24, 2017
Tweet

Transcript

  1. Modular architecture

  2. Modular architecture Classes and components

  3. Modular architecture classes and Components and modifiers

  4. Modular architecture classes and Components, modifiers and overrides

  5. Modular architecture classes, modifiers and overrides Components, 
 patterns and

    sh*t it’s hard to deal with
  6. @cedmax Webmaster before it was cool 
 Lead engineer at

    Crowdcube
  7. Components,
 patterns and sh*t it’s hard to deal with

  8. or… How I came up with a good use of

    quotes from Lost in Translation Components,
 patterns and sh*t it’s hard to deal with
  9. Basically Lost in Translation?

  10. “This movie is an hour and some odd minutes of

    my life I will never get back.” JoeB. on Metacritic Disclaimer
  11. “Meaning is complex and often gets lost in translation. Everybody

    has their own mental model of things” Alla Kholmatova Lost in Translation
  12. Modular design

  13. 2015

  14. None
  15. Atomic design Brad Frost · October 2013

  16. Web components announced in November 2011

  17. 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
  18. ReactJS First release: March 2013

  19. Where are we at, today?

  20. Basically Frame the issue

  21. 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
  22. The issue

  23. “A common language is a first step towards communication across

    cultural boundaries. ” Ethan Zuckerman
  24. MISSING SLIDE ABOUT PATTERN LIBRARIES * * it's missing on

    purpose, I promise
  25. The issue How do we manage our code, to re-use

    patterns without making them too rigid for the day to day activities?
  26. The issue How do we re-use our patterns in slightly

    different use cases?
  27. Wish I could sleep

  28. It’s NOT about any specific tech stack*
 
 It’s about

    modularity at its core
 
 It’s about modules responsibilities
 
 It’s about maintainability
 (among other coding practices)
  29. Classname 
 injection I'll be in the bar for the

    rest of the week
  30. <IconButton className="content-actions__button" iconId="close" />

  31. <IconButton className="content-actions__button" iconId="close" />

  32. //_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; } } }
  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; } } }
  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; } } } How do these rules interact with the base button styles?
  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 role do these override play in the pattern library?
  36. This is the most flexible way to extend anything. What

    works
  37. What really doesn't 1. The base component style and the

    overrides live in different files. 2. The default style could be overridden in unexpected ways. 3. We are creating many variants of the original patterns.
  38. - You're too tall.
 - Anybody ever tell you you

    may be too small? Ad hoc BEM-like modifiers
  39. <Dialog className="dialog--user-intent"> <!-- [...] --> </Dialog>

  40. <Dialog className="dialog--user-intent"> <!-- [...] --> </Dialog>

  41. //_dialog.scss .dialog { //[...] &--user-intent { @include mappy-bp(medium) { width:

    43.75rem; height: auto; } } }
  42. //_dialog.scss .dialog { //[...] &--user-intent { @include mappy-bp(medium) { width:

    43.75rem; height: auto; } } }
  43. //_dialog.scss .dialog { //[...] &--wizard { @include mappy-bp(medium) { width:

    43.75rem; height: 35rem; } } &--game-intent { @include mappy-bp(medium) { width: 43.75rem; height: auto; } } &--save-results { @include mappy-bp(medium) { width: 23.75rem; height: auto; } } } How does this 
 practice scale?
  44. This practice allows for flexibility, giving a reasonable control and

    keeping all the variants in the same space. What works
  45. What really doesn't 1. The generic component css have knowledge

    of specific implementations. 2. The file size might be effected by unused code. 3. It doesn't scale
  46. Pre-defined modifiers I'm special

  47. <Dialog className="dialog--prompt"> <!-- [...] --> </Dialog>

  48. <Dialog className="dialog--prompt"> <!-- [...] --> </Dialog>

  49. //_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; } }
  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; } } The semantic value 
 of the modifiers is 
 really different.
  51. The patterns are at the centre: no special cases, but

    pre-defined flavours of the basic components. What works
  52. What really doesn't 1. It might drive to preemptive abstraction

    2. It doesn't necessarily work all the time
  53. <Dialog type="prompt" /> <Dialog className="dialog--prompt"> <!-- [...] --> </Dialog> <DialogPrompt

    />
  54. I still wish I could sleep 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 A good approach, but not applicable to all scenarios Classname 
 injection Ad hoc BEM-like modifiers Pre-defined modifiers
  55. Basically I'm stuck

  56. It's not that simple “It isn’t really that simple” Alla

    Kholmatova · June 2015
  57. The issue How do we re-use our patterns in slightly

    different use cases?
  58. What are we trying to solve?

  59. Arrangement within parent components

  60. <div className="game-intent__dialog"> <Dialog> <!-- [...] --> </Dialog> </div>

  61. <div className="game-intent__dialog"> <Dialog> <!-- [...] --> </Dialog> </div>

  62. //_dialog.scss .dialog { width: 100%; height: 100%; //[...] } //_game-intent.scss

    .game-intent { //[...] &__dialog { @include mappy-bp(medium) { width: 43.75rem; height: auto; } } }
  63. //_dialog.scss .dialog { width: 100%; height: 100%; //[...] } //_game-intent.scss

    .game-intent { //[...] &__dialog { @include mappy-bp(medium) { width: 43.75rem; height: auto; } } } Each component has its own responsibility
  64. This practices defines responsibilities in a neat way and it

    enables for specific implementations without invalidating patterns. What works
  65. <div className="custom-class"> <Dialog> <!-- [...] --> </Dialog> </div> <Dialog className="custom-class">

    <!-- [...] --> </Dialog>
  66. What really doesn't Potentially you might need a wrapper HTML

    element that could have been avoided.
  67. Space in relation to other components

  68. <Dialog className="space-max inner-space-min"> <!-- [...] --> </Dialog>

  69. <Dialog className="space-max inner-space-min"> <!-- [...] --> </Dialog>

  70. It reduces the need to come up with new class

    names and it moves the conversation regarding component relationships back to the pattern library. What works
  71. 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/
  72. <Dialog className="M(defSpace) P(defSpace)"> <!-- [...] --> </Dialog>

  73. "Open" components

  74. //_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] .icon { width:

    $content-block-icon-large-size; height: $content-block-icon-large-size; } }
  75. //_question-content-block.scss .question-content-block { //[...] &__icon-button { //[...] .icon { width:

    $content-block-icon-large-size; height: $content-block-icon-large-size; } }
  76. //_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; } }
  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; } }
  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; } } The responsibility of being flexible it back to the component itself
  79. 1. Every base component can be as flexible as it

    defines itself to be. 2. Developers always have control on what they expose. What works
  80. What really doesn't 1. This technique involves more complexity in

    the style files 2. How does an "open" component fit in the patterns?
  81. Basically Does it get easier?

  82. The more you know who you are and what you

    want, the less you let things upset you
  83. I just don't know what I'm supposed to be

  84. The issue How to understand - and convey - the

    meaning of an exception in our patterns?
  85. Learn what the pattern your 
 are building is supposed

    to be
  86. Get involved early

  87. Talk to people

  88. and remember that…

  89. marco@fromthefront.it http://cedmax.com @cedmax You are not hopeless