$30 off During Our Annual Pro Sale. View Details »

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.

Marco Cedaro

May 24, 2017
Tweet

More Decks by Marco Cedaro

Other Decks in Programming

Transcript

  1. Modular
    architecture

    View Slide

  2. Modular architecture
    Classes and
    components

    View Slide

  3. Modular architecture
    classes and
    Components
    and modifiers

    View Slide

  4. Modular architecture
    classes and
    Components,
    modifiers
    and overrides

    View Slide

  5. Modular architecture
    classes,
    modifiers
    and overrides
    Components, 

    patterns and sh*t it’s
    hard to deal with

    View Slide

  6. @cedmax
    Webmaster
    before it was cool

    Lead engineer at
    Crowdcube

    View Slide

  7. Components,

    patterns and sh*t
    it’s hard to deal with

    View Slide

  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

    View Slide

  9. Basically
    Lost in Translation?

    View Slide

  10. “This movie is an hour and some
    odd minutes of my life I will never
    get back.”
    JoeB. on Metacritic
    Disclaimer

    View Slide

  11. “Meaning is complex and often gets
    lost in translation. Everybody has
    their own mental model of things”
    Alla Kholmatova
    Lost in Translation

    View Slide

  12. Modular design

    View Slide

  13. 2015

    View Slide

  14. View Slide

  15. Atomic design
    Brad Frost · October 2013

    View Slide

  16. Web components
    announced in November 2011

    View Slide

  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

    View Slide

  18. ReactJS
    First release: March 2013

    View Slide

  19. Where are we at, today?

    View Slide

  20. Basically
    Frame the issue

    View Slide

  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

    View Slide

  22. The issue

    View Slide

  23. “A common language is
    a first step towards
    communication across
    cultural boundaries. ”
    Ethan Zuckerman

    View Slide

  24. MISSING SLIDE ABOUT
    PATTERN LIBRARIES *
    * it's missing on purpose, I promise

    View Slide

  25. The issue
    How do we manage our code, to
    re-use patterns without making
    them too rigid for the day to day
    activities?

    View Slide

  26. The issue
    How do we re-use our patterns in
    slightly different use cases?

    View Slide

  27. Wish I could sleep

    View Slide

  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)

    View Slide

  29. Classname 

    injection
    I'll be in the bar for the rest of the week

    View Slide

  30. className="content-actions__button"
    iconId="close"
    />

    View Slide

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

    View Slide

  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;
    }
    }
    }

    View 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;
    }
    }
    }

    View 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;
    }
    }
    }
    How do these rules
    interact with the base
    button styles?

    View 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 role do these
    override play in the
    pattern library?

    View Slide

  36. This is the most flexible way to extend
    anything.
    What works

    View Slide

  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.

    View Slide

  38. - You're too tall.

    - Anybody ever tell you you may be too small?
    Ad hoc
    BEM-like
    modifiers

    View Slide

  39. className="dialog--user-intent">


    View Slide

  40. className="dialog--user-intent">


    View Slide

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

    View Slide

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

    View Slide

  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?

    View Slide

  44. This practice allows for flexibility, giving
    a reasonable control and keeping all
    the variants in the same space.
    What works

    View Slide

  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

    View Slide

  46. Pre-defined
    modifiers
    I'm special

    View Slide

  47. className="dialog--prompt">


    View Slide

  48. className="dialog--prompt">


    View Slide

  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;
    }
    }

    View 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;
    }
    }
    The semantic value 

    of the modifiers is 

    really different.

    View Slide

  51. The patterns are at the centre: no
    special cases, but pre-defined flavours
    of the basic components.
    What works

    View Slide

  52. What really doesn't
    1. It might drive to preemptive abstraction
    2. It doesn't necessarily work all the time

    View Slide

  53. type="prompt" />
    className="dialog--prompt">



    View Slide

  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

    View Slide

  55. Basically
    I'm stuck

    View Slide

  56. It's not that simple
    “It isn’t really that simple”
    Alla Kholmatova · June 2015

    View Slide

  57. The issue
    How do we re-use our patterns in
    slightly different use cases?

    View Slide

  58. What are we
    trying to solve?

    View Slide

  59. Arrangement
    within parent
    components

    View Slide

  60. className="game-intent__dialog">




    View Slide

  61. className="game-intent__dialog">




    View Slide

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

    View Slide

  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

    View Slide

  64. This practices defines responsibilities
    in a neat way and it enables for
    specific implementations without
    invalidating patterns.
    What works

    View Slide

  65. className="custom-class">




    className="custom-class">


    View Slide

  66. What really doesn't
    Potentially you might need a wrapper
    HTML element that could have been
    avoided.

    View Slide

  67. Space in
    relation to other
    components

    View Slide

  68. className="space-max inner-space-min">


    View Slide

  69. className="space-max inner-space-min">


    View Slide

  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

    View Slide

  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/

    View Slide

  72. className="M(defSpace) P(defSpace)">


    View Slide

  73. "Open"
    components

    View Slide

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

    View Slide

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

    View Slide

  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;
    }
    }

    View 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;
    }
    }

    View 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;
    }
    }
    The responsibility of
    being flexible it back to
    the component itself

    View Slide

  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

    View Slide

  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?

    View Slide

  81. Basically
    Does it get easier?

    View Slide

  82. The more you know who you are and what
    you want, the less you let things upset you

    View Slide

  83. I just don't know what I'm supposed to be

    View Slide

  84. The issue
    How to understand - and convey -
    the meaning of an exception in our
    patterns?

    View Slide

  85. Learn what the pattern your 

    are building is supposed to be

    View Slide

  86. Get involved early

    View Slide

  87. Talk to people

    View Slide

  88. and remember that…

    View Slide

  89. [email protected]
    http://cedmax.com
    @cedmax
    You are not hopeless

    View Slide