Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Design system - From a Developer Point-of-View

6e37e1a3a1089cc8a455a85e6b736af0?s=47 Yael Balla
April 04, 2019
130

Design system - From a Developer Point-of-View

Design Systems is something every UX team is working on, planning to work on, or at least is talking about. But what does it mean for a developer to implement a new design system for the company products? Is it also better for the developer? In the talk I will share my experience with implementing a design system. How to share design tokens in the organization? How to create a component library and separate the visual layer from business logic? How do you keep sync between design and code? In this talk I will answer these questions, using code examples and relevant tools.

Presented in YGLF confrence, April 2019

6e37e1a3a1089cc8a455a85e6b736af0?s=128

Yael Balla

April 04, 2019
Tweet

Transcript

  1. Design Systems: Developer Point of View Yael Balla @ YGLF,

    April 2019
  2. Hello! I am Yael Balla You can find me at

    yael.balla@gmail.com www.linkedin.com/in/yael-oshri-balla-6b56686 2
  3. None
  4. Design Systems? What’s in it for me? 4

  5. So, Let’s start with some definitions 5

  6. “ the complete set of design standards, documentation, and principles

    along with the toolkit (UI patterns and code components) to achieve those standards 6
  7. https://uxdesign.cc/can-design-systems-fix-the-relationship-between-designers-developers-eb12fc9329ab Design System Structure

  8. Design Systems Examples ▪ Salesforce - Lightning ▪ IBM -

    Carbon ▪ Google - Material Design ▪ Shopify - Polaris And many others… https://designsystemsrepo.com/design-systems/ 8
  9. None
  10. None
  11. None
  12. None
  13. None
  14. None
  15. “ Before this ... Designers and developers were trying their

    best to make good decisions about which components or patterns to use, but their main reference point was the existing product — which was decidedly inconsistent. Giorgio Lefeber, Xebia Studio
  16. Step #1 Conceptual change

  17. Work together Design Dev Product 17

  18. Understand the rules behind the design And how it affect

    visual layer 18
  19. Atomic Design Atoms Font Color Spacing Molecules Button Input Combo

    Box Organisms Search Box Table Date Picker
  20. Step #2 Design Tokens

  21. Meaningful CSS Variables My green -> success My grey ->

    body font color $color-pink: #f36; $color-green: #09baa6; $color-yellow: #ffb631; $color-gray: #dee0e4; $color-success: $color-green; $color-warning: $color-yellow; $color-brand: $color-pink;
  22. Meaningful CSS Variables $xxs: 4px; $xs: 8px; $s: 16px; $m:

    24px; $l: 32px; $xl: 48px; $xxl: 64px;
  23. Utilities CSS classes $sizes: (xxs:$xxs, xs:$xs, s:$s, m:$m, l:$l, xl:$xl,

    xxl:$xxl); @each $size, $value in $sizes { .u-m-#{$size} { margin: #{$value}; } .u-m-#{$size} { margin: #{$value}; } .u-mt-#{$size} { margin-top: #{$value}; } .u-mr-#{$size} { margin-right: #{$value}; } .u-mb-#{$size} { margin-bottom: #{$value}; } .u-ml-#{$size} { margin-left: #{$value}; } .u-mx-#{$size} { margin-left: #{$value}; margin-right: #{$value}; } .u-my-#{$size} { margin-top: #{$value}; margin-bottom: #{$value}; } ...
  24. Utilities CSS classes <Text className="u-m-s"> I have a text with

    small margin </Text>
  25. What is the best way to define these variables? It

    doesn’t matter - any technique that works for you ▪ CSS-in-JS ▪ SASS Variables ▪ React Components (like <Padded/>, <Title/>)
  26. No more ‘one ofs’ You have a signed contract with

    designers 26
  27. Step #3 Define Visual Components

  28. Seperate Your Visual Layer Let’s look on some example 28

  29. class List extends Component { componentDidCatch(error, info) { redirectToErrorPage(error, info);

    } render() { const { items, user } = this.props; reportMetrics(`items rendered`); const showDelete = isAuthorised(user); return ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} />
  30. class List extends Component { componentDidCatch(error, info) { redirectToErrorPage(error, info);

    } render() { const { items, user } = this.props; reportMetrics(`items rendered`); const showDelete = isAuthorised(user); return ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} />
  31. class List extends Component { componentDidCatch(error, info) { redirectToErrorPage(error, info);

    } render() { const { items, user } = this.props; reportMetrics(`items rendered`); const showDelete = isAuthorised(user); return ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} />
  32. class List extends Component { componentDidCatch(error, info) { redirectToErrorPage(error, info);

    } render() { const { items, user } = this.props; reportMetrics(`items rendered`); const showDelete = isAuthorised(user); return ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} />
  33. class List extends Component { ... render() { ... return

    ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} /> } { showDelete && <button onClick={() => deleteItem(item)}> Delete </button> } </div> ))} </ul> )
  34. class List extends Component { ... render() { ... return

    ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} /> } { showDelete && <button onClick={() => deleteItem(item)}> Delete </button> } </div> ))} </ul> )
  35. class List extends Component { ... render() { ... return

    ( <ul> {items.map((item) => ( <div> { item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} /> } { showDelete && <button onClick={() => deleteItem(item)}> Delete </button> } </div> ))} </ul> )
  36. Let’s start Separate between design system and application code 36

  37. import React, { Component } from 'react'; import redirectToErrorPage from

    "./errors" class ErrorBoundary extends Component { componentDidCatch(error, info) { redirectToErrorPage(error, info); } render() { return this.props.children; } } ErrorBoundary Parent Component
  38. Metrics Higher Order Component

  39. const metrics = (metric, WrappedComponent) => class MetricReport extends Component

    { render() { reportMetrics(metric); return <WrappedComponent {...this.props} />; } }; Metrics Higher Order Component
  40. Render Props

  41. class List extends Component { render() { const { items,

    itemRenderer } = this.props; return ( <ul> {items.map((item, index) => itemRenderer(item, index))} </ul> ) } } export default List; Render Props
  42. export const Item = ({ item }) => { return

    item.type === 'text' ? <LabelItem label={item.text} /> : <ImageItem image={item.image} /> }; Item code is part of Library
  43. Application List const ItemsList = (props) => { ... return

    ( <ErrorBoundary> <List items={items} itemRenderer={itemRenderer}/> </ErrorBoundary> ); }; export default metrics('items rendered', ItemsList);
  44. Application List const itemRendererCreator = (showDelete, onItemDelete) => (item) =>

    { return <div> <Item item={item} /> { showDelete && <button onClick={() => onItemDelete(item)}> Delete </button> } </div> }; const ItemsList = (props) => { const { items, user } = props; const showDelete = isAuthorised(user); const itemRenderer = itemRendererCreator(showDelete, deleteItem); return ( <ErrorBoundary>
  45. Result

  46. Customization? How to make our component reusable 46

  47. Customizing Visual Components Styles Props Render

  48. Customizing Visual Components Styles Props Render

  49. Customizing Visual Components Styles Props Render

  50. Customizing Visual Components Styles Props Render

  51. 51 Not every shared component should be part of the

    design library
  52. Step #4 Shared Library

  53. webpack.config.js module.exports = { … output: { path: path.resolve(__dirname, './dist/lib'),

    filename: 'index.js', library: 'MyDesignSystem', libraryTarget: 'commonjs' },
  54. webpack.config.js module.exports = { … output: { path: path.resolve(__dirname, './dist/lib'),

    filename: 'index.js', library: 'MyDesignSystem', libraryTarget: 'commonjs' },
  55. package.json { "name": "MyDesignSystem", "version": "1.0.0", "description": "Sample Design System

    lib", "main": "dist/lib/index.js", "scripts": { ... },
  56. package.json { "name": "MyDesignSystem", "version": "1.0.0", "description": "Sample Design System

    lib", "main": "dist/lib/index.js", "scripts": { ... },
  57. webpack.config.js const nodeExternals = require('webpack-node-externals'); module.exports = { ... output:

    { ... }, externals: [nodeExternals()], ... }
  58. Linking Repository $ cd ~/workspace/my-app $ npm link ../shared-lib

  59. Version Management

  60. Version Management with semantic-release package, releases are handled by commit

    messages. Examples: “fix(button): change over color“ => Patch Release “major(button): change property name“ => Major Release And you can also integrate it into your CI...
  61. Step #5 Sharing and Visibility

  62. If a tree falls in a forest and no one

    is around to hear it, does it make a sound?
  63. Website A simple static website that includes: - Design Principles

    - What resources provided - Real live components
  64. Storybook is a UI component development environment Allows you to

    define ‘stories’ for your components Generate static website with live components
  65. Getting Started > cd my-shared-lib > npx -p @storybook/cli sb

    init > npm run storybook
  66. Static Site Script to publish storybook as a static site

    is already added to your project "scripts": { … "build-storybook" : "build-storybook" }, package.json
  67. None
  68. What is a story? Each story represent one state But

    it is all up to you ▪ Render one component ▪ Combine few states for comparison ▪ Build a form
  69. Let’s now add a story import React from 'react'; import

    { storiesOf } from '@storybook/react '; import { action } from '@storybook/addon-actions '; import { Button } from '../index'; storiesOf('Button', module) .add('with default theme and some text' , () => ( <Button onClick={action('clicked')}>Hello Button</ Button> )) .add('with green theme' , () => ( <Button green onClick={action('clicked')}>Hello Button</ Button> )) stories/button.stories.js
  70. Let’s now add a story import React from 'react'; import

    { storiesOf } from '@storybook/react '; import { action } from '@storybook/addon-actions '; import { Button } from '../index'; storiesOf('Button', module) .add('with default theme' , () => ( <Button onClick={action('clicked')}>Hello Button</ Button> )) .add('with green theme' , () => ( <Button green onClick={action('clicked')}>Hello Button</ Button> )) stories/button.stories.js
  71. Default is nice but ... By default Storybook arrive very

    thin. To add functionality need to enable some add-ons
  72. Recommended Add-on Info - generate readme for each component Knobs

    - allow the user to edit in live mode Options - control the storybook default UI settings
  73. React components for the Carbon Design System http://react.carbondesignsystem.com

  74. React components for the Carbon Design System http://react.carbondesignsystem.com

  75. React components for the Carbon Design System http://react.carbondesignsystem.com

  76. React components for the Carbon Design System http://react.carbondesignsystem.com

  77. Code as source of truth Convert React to sketch https://github.com/airbnb/react-sketchapp

    Convert HTML to sketch https://github.com/brainly/html-sketchapp
  78. Visual Tests as part of your CI /CD

  79. Design Ops? Tools and processes for managing and scaling the

    design workflow 79
  80. Design Ops Tools for design, collaboration, developer hands off Assets

    management Training and onboarding Research & user testing [ Program managers ]
  81. None
  82. Useful links ▪ Design Systems: ▫ https://www.carbondesignsystem.com ▫ https://www.lightningdesignsystem.com ▫

    https://material.io/design/introduction/# ▪ Extra reading: ▫ https://uxdesign.cc/can-design-systems-fix-the-relationship-between-designers-developers-eb12fc9329ab ▫ https://medium.com/@nthgergo/lessons-learned-from-working-on-a-design-system-as-an-engineering-mana ger-2f199cd4aac2 ▫ http://bradfrost.com/blog/post/atomic-web-design/ ▫ https://www.designbetter.co/design-systems-handbook/introducing-design-systems ▫ https://medium.com/amplify-design/operationalizing-design-operations-7846a23bc99b 82
  83. Thanks!! Any questions? You can find me at yael.balla@gmail.com www.linkedin.com/in/yael-oshri-balla-6b56686

    83