Small

Design Systems

for Developers

Alex Riviere

Senior Front-end Developer

What is a
Design System?

A design system is a series of design elements that can be leveraged to develop a set of products that are true to the Brand.

Lou Delgado

It defines everything that makes up a product – from type, layouts, grids, color, icons, components, coding conventions, and motion principles to voice, tone, style-guides, and documentation.

Mark Gallo

Operational tools for publishing in a digital world.

Andrew Walpole

OK but seriously,
what is it?

What
it isn't

Brand guidelines

Brand guidelines document the core visual and verbal elements of the brand, and provide visual examples of how the brand is expressed across various applications.

A UI kit

UI kits are only a part of the Design System. UI Kits help Designers to design faster and better.

A component library

A component library is a collection where you can browse examples and find code snippets to implement into a codebase. Component libraries help engineers to code faster and better

What
it is

Design System Overview

Design Tokens

Reference site or Sandbox

Visual Identity
Guidlines/Design
Language

UI Kit

Component Library

  • Site
  • App
  • Marketing
  • Social

WAT.

How do I
implement this?

Smallest use case:
Colors.

PHP

JS

CSS

PHP

JS

CSS

PHP

JS

CSS

JSON

PHP

JS

CSS

JSON
--color

PHP

JS

CSS

JSON
--color

Design Tokens

PHP

JS

CSS

JSON
--color

???

Design Tokens

Design Token Code Generators

  • Dragoman

  • Theemo

  • Mole

  • Theo

  • Style-Dictionary

{
  "colors": {
    "red": {
      "value": "#FF0000"
    },
    "blue": {
      "value": "#0000FF"
    },
    "green": {
      "value": "#00FF00"
    }
  }
}

A design token file

{
  "colors": {
    "black": { "value": "#000000" },
    "traina-purple-400": {  "value": "#8875e2" },
    "traina-purple-300": { "value": "#A897F8" },
    "traina-pink-400": { "value": "#DE706F" },
    "traina-pink-300": { "value": "#F98989" },
    "traina-green-400": { "value": "#5D9E70" },
    "traina-green-300": { "value": "#82C596" },
    "traina-gray-900": { "value": "#151515" },
    "traina-gray-800": { "value": "#232323" },
    "traina-gray-700": { "value": "#454545" },
    "traina-gray-600": { "value": "#636363" },
    "traina-gray-500": { "value": "#727272" },
    "traina-gray-400": { "value": "#8e8e8e" },
    "traina-gray-300": { "value": "#D0D0D0" },
    "traina-gray-200": { "value": "#e8e8e8" },
    "traina-gray-110": { "value": "#f5f5f5" },
    "traina-gray-100": { "value": "#fafafa" },
    "white": { "value": "#ffffff" },
    "error-red": { "value": "#852323" }
  }
}

tokens/colors.json

{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "scss": {
      "transformGroup": "scss",
      "buildPath": "build/",
      "files": [{
        "destination": "_vars.scss",
        "format": "scss/map-deep"
      }]
    },
    "json": {
      "transforms": [
        "attribute/cti", 
        "name/cti/pascal", 
        "color/hex", 
        "size/rem"
      ],
      "buildPath": "build/",
      "files": [{
        "destination": "tokens.json",
        "format": "json/nested"
      }]
    }
  }
}

config.json

npx style-dictionary build

Build the files

/**
 * Do not edit directly
 */

$colors-black: #000000 !default;
$colors-traina-purple-400: #8875e2 !default;
$colors-traina-purple-300: #A897F8 !default;
$colors-traina-pink-400: #DE706F !default;
$colors-traina-pink-300: #F98989 !default;
$colors-traina-green-400: #5D9E70 !default;
$colors-traina-green-300: #82C596 !default;
$colors-traina-gray-900: #151515 !default;
$colors-traina-gray-800: #232323 !default;
$colors-traina-gray-700: #454545 !default;
$colors-traina-gray-600: #636363 !default;
$colors-traina-gray-500: #727272 !default;
$colors-traina-gray-400: #8e8e8e !default;
$colors-traina-gray-300: #D0D0D0 !default;
$colors-traina-gray-200: #e8e8e8 !default;
$colors-traina-gray-110: #f5f5f5 !default;
$colors-traina-gray-100: #fafafa !default;
$colors-white: #ffffff !default;
$colors-error-red: #852323 !default;

$tokens: (
  'colors': (
    'black': $colors-black,
    'traina-purple-400': $colors-traina-purple-400,
    'traina-purple-300': $colors-traina-purple-300,
    'traina-pink-400': $colors-traina-pink-400,
    'traina-pink-300': $colors-traina-pink-300,
    'traina-green-400': $colors-traina-green-400,
    'traina-green-300': $colors-traina-green-300,
    'traina-gray-900': $colors-traina-gray-900,
    'traina-gray-800': $colors-traina-gray-800,
    'traina-gray-700': $colors-traina-gray-700,
    'traina-gray-600': $colors-traina-gray-600,
    'traina-gray-500': $colors-traina-gray-500,
    'traina-gray-400': $colors-traina-gray-400,
    'traina-gray-300': $colors-traina-gray-300,
    'traina-gray-200': $colors-traina-gray-200,
    'traina-gray-110': $colors-traina-gray-110,
    'traina-gray-100': $colors-traina-gray-100,
    'white': $colors-white,
    'error-red': $colors-error-red
  )
);

build/_vars.scss

{
  "colors": {
    "black": "#000000",
    "traina-purple-400": "#8875e2",
    "traina-purple-300": "#A897F8",
    "traina-pink-400": "#DE706F",
    "traina-pink-300": "#F98989",
    "traina-green-400": "#5D9E70",
    "traina-green-300": "#82C596",
    "traina-gray-900": "#151515",
    "traina-gray-800": "#232323",
    "traina-gray-700": "#454545",
    "traina-gray-600": "#636363",
    "traina-gray-500": "#727272",
    "traina-gray-400": "#8e8e8e",
    "traina-gray-300": "#D0D0D0",
    "traina-gray-200": "#e8e8e8",
    "traina-gray-110": "#f5f5f5",
    "traina-gray-100": "#fafafa",
    "white": "#ffffff",
    "error-red": "#852323"
  }
}

build/tokens.json

Recap

  • Created a version we can use in PHP and JS

  • Created a version that can be used in CSS or JS in the browser 

  • More export options available!

But wait!

There's more....

Let's make a
WordPress plugin

<?php

// Set this once here, so we can cache this value for later.
$__DESIGN_TOKENS = null;

function tcp_return_design_tokens()
{
    global $__DESIGN_TOKENS;
    if (!is_null($__DESIGN_TOKENS)) {
        return $__DESIGN_TOKENS;
    }
    $plugin_dir = WP_PLUGIN_DIR . '/traina-color-picker';
    $__DESIGN_TOKENS = json_decode(
        file_get_contents($plugin_dir . '/build/tokens.json'), 
        true
    );
    return $__DESIGN_TOKENS;
}


// gutenberg custom color palette
function tcp_change_gutenberg_color_palette()
{
    $design_tokens = tcp_return_design_tokens();

    // creates an array to store our color variables from css file
    $color_palette = [];

    foreach ($design_tokens['colors'] as $color_slug => $color_hex){
        $color_name = trim(
            ucwords(
                str_replace('-', ' ', $color_slug)
            )
        );
        $color_palette[] = [
            'name' => $color_name,
            'slug' => $color_slug,
            'color' => $color_hex
        ];
    }

    if ($color_palette) {
        add_theme_support('editor-color-palette', $color_palette); 
    }
}
add_action('after_setup_theme', 'tcp_change_gutenberg_color_palette');

traina-color-picker.php

@use "./build/vars" as v;
@use "sass:map";


@each $name, $color in map.get(v.$tokens,colors){
    .has-#{$name}-color{
        color: #{$color};
    }
}

main.scss

<?php

function tcp_enqueue_styles(){
	wp_enqueue_style('tcp_styles', plugins_url().'/traina-color-picker/build/main.css');
}

add_action('init', 'tcp_enqueue_styles');
add_action('admin_enqueue_scripts', 'tcp_enqueue_styles');


// Set this once here, so we can cache this value for later.
$__DESIGN_TOKENS = null;

function tcp_return_design_tokens()
{
    global $__DESIGN_TOKENS;
    if (!is_null($__DESIGN_TOKENS)) {
        return $__DESIGN_TOKENS;
    }
    $plugin_dir = WP_PLUGIN_DIR . '/traina-color-picker';
    $__DESIGN_TOKENS = json_decode(
        file_get_contents($plugin_dir . '/build/tokens.json'), 
        true
    );
    return $__DESIGN_TOKENS;
}


// gutenberg custom color palette
function tcp_change_gutenberg_color_palette()
{
    $design_tokens = tcp_return_design_tokens();

    // creates an array to store our color variables from css file
    $color_palette = [];

    foreach ($design_tokens['colors'] as $color_slug => $color_hex){
        $color_name = trim(
            ucwords(
                str_replace('-', ' ', $color_slug)
            )
        );
        $color_palette[] = [
            'name' => $color_name,
            'slug' => $color_slug,
            'color' => $color_hex
        ];
    }

    if ($color_palette) {
        add_theme_support('editor-color-palette', $color_palette); 
    }
}
add_action('after_setup_theme', 'tcp_change_gutenberg_color_palette');

traina-color-picker.php

Thank you.

Questions?

  • Slides: slides.com/fimion/connect-tech-2022
  • Code: github.com/fimion/traina-color-picker

 

  • Twitter: @fimion
  • Mastodon: @fimion@notacult.social
  • Blog: alex.party

WeAreTraina.com

Small Design Systems for Developers

By Alex Riviere

Small Design Systems for Developers

  • 297