Particle

Opinionated tools to build Design Systems
 

Christopher Bloom

Phase2 Technology

http://bit.ly/2DIO6r2

Navigating this deck yourself?

If you're working your way through these slides yourself, note a couple of things to help you along:

 

  1. This presentation has DOWN arrows to navigate, not just left/right arrows. Pay attention to the arrows to the lower right of the slides. You'll miss HUGE parts of the presentation if you don't navigate downward!
  2. The Particle repo is here: https://github.com/phase2/particle

TLDR

  • Some learnin'
  • Some installin'
  • Some codin'

* Codin' subject to bandwidth and technology not explodin'

Prerequisites

PHP 7+

Composer

Node

OSX w/ Homebrew

brew update
brew install php72
php --version
brew install composer
composer --version
nvm install node
nvm alias default node
node --version

Linux (Debian)

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.2-cli

OSX w/ Homebrew

Linux

OSX w/ NVM

Linux

<-- Use NVM

Install all prerequisites

# Install Homebrew, if not installed
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# Update Homebrew installed packages
brew update && brew upgrade

# Install PHP 7.2, if not installed
brew install php72

# Install Composer 1.6+, if not installed
brew install composer

# Install NVM, if not installed
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

# Modern Node
nvm install node && nvm alias default node

# NPM 6+
npm install -g npm@latest

# Get particle via starter script
npm create @phase2/particle particle && cd particle

# Install Particle dependencies. Run only once at the start of a project.
npm install && npm run setup

# Start Particle every time you want to work in Pattern Lab
npm start

Scenario

  1. You have to build a thing

  2. There are designs

  3. Those designs have to become code

  4. That code will be consumed by some final system

You are in Frontend Sprint 0

Old Way:

Frontenders couldn't theme before content types and servers and databases and features and designs were done. This meant frontend was usually the frantic end of a project.

New Way:

Frontenders work on design systems and tooling long before backend decisions, working in parallel to the rest of the build. Components are agnostic but "schema-driven".

Modern design implementation starts at the beginning of a project instead of the end.

We're not "Themers".

We're "Design System Appliers"

Design Systems

... a collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications."

Style Guide

  • Colors

  • Typography

  • Spacing

  • Grids

  • Image treatment

  • Iconography

Pattern Library

  • Application of Style Guide to many small UI components

  • Assemble like Lego to build more complex screens

  • Iteratable, evolving

  • REAL CODE (HTML, Twig, React)

  • UI interactive behaviors

+

Atomic Design

  • atomicdesign.bradfrost.com
  • A philosophy about the pieces that make up a design
  • Defines a design language for a site
  • Specifies various levels of complexity of patterns in the UI
  • Helps us answer "How are we going to turn this picture into code?"

We will use the principles of Atomic Design to break up designs into coded Twig files:

  • Atoms
  • Molecules
  • Organisms
  • Templates
  • Pages

Pattern Lab

patternlab.io

 

Simply a tool to apply Atomic Design principles to Twig components.

 

Renders all components to HTML.

 

Provides a UI to navigate the components.

 

Built on PHP (for now)

Particle

A bunch of tools to build design systems

https://github.com/phase2/particle

  • Starter-Kit = tools + examples
  • Drupal theme, Grav theme, Pattern Lab app
  • Strict Atomic Design component structure
  • Webpack bundling of all CSS, javascript, font, and static image assets for multiple targets
  • Webpack Dev Server for local hosting and auto asset injection into Pattern Lab and Drupal
  • pa11y accessibility testing
  • VueJS framework integration
  • Twig namespaced paths generated automatically. @atoms/thing.twig means the same thing to Drupal theme and Pattern Lab.
  • SVG icon auto-generation
  • Bootstrap 4 integration, used for all starting example components
  • Auto-linting against the AirBnB JS Style Guide and sane Sass standards
  • Prettier auto code formatting
  • All Webpack and Gulp files are fully configurable
  • Jest unit tests for all components

Particle

  1. Assets
    1. Twig
    2. ​CSS
    3. Javascript
    4. Fonts
    5. Static images
  2. Apps
    1. ​Pattern Lab
    2. Drupal theme
    3. Grav theme

Particle is Design Modules

  1. A folder of Twig, Sass, and Javascript
  2. Tied together with asset dependency via Javascript modules
  3. All pulled into a single Design System library

Dependency Chain

source/molecules/card

source/design-system

apps/pl

source/

node_modules/bootstrap

Tooling: Node.js!

  • Webpack: Now the heavy-lifter of our toolchain
    • "Bundling"
    • ES6
    • Sass
    • Linting
    • SVG icon generation
    • Fonts
    • Static image processing
    • Static site serving
  • Gulp: Down to few TASKS (not asset dependency management)
    • Helper tasks
    • "app tasks" (Pattern Lab, Drupal namespaces)

Webpack

slides.com/illepic/webpack

 

Most of a frontender's job is generating assets.
 

  1. BUNDLES assets
  2. Provides DEPENDENCY MANAGEMENT of assets
  3. Active development server

Webpack Inheritance

webpack.particle.js
webpack.design-system.js
webpack.drupal.js

DEV

PROD

DEV

PROD

Overall, shared config 

Design System-specific config

("Where are 'atoms'?")

App-specifc overrides

("Where is the bundle output?")

Gulp

gulpjs.com

 

The rest of a frontender's job is repetitive tasks.

 

  1. Run scripts when files change
  2. Orchestrate multiple scripts together using javascript syntax

Installation

npm create @phase2/particle particle
cd particle
npm install
npm run setup
npm start

Let's make a card!

Build this card: html5up.net/phantom

Deconstruct using

Atomic Design principles

Download the zip and extract:

html5up.net/phantom/download

 

Move html5up-phantom/

to

source/_patterns/00-protons/html5up-phantom/ 

 

Now edit:

source/_patterns/00-protons/index.js
import './_base.scss';

// Add this
import './html5up-phantom/assets/css/main.css';

// ...

(Sass errors? Delete html5up-phantom/assets/sass/)

Our active Pattern Lab running at http://localhost:8080/pl/ should look different!

 

Visit http://localhost:8080/pl/?p=molecules-cards for a sense of the difference.

 

The new CSS is being compiled in!

 

Now, let's make new molecule called

phantom-card

 

Create the following folder structure and empty files by running:

npm run new

What's going on here?

  • New molecule component: phantom-card
  • "demo" folder is what PL actually renders
  • Includes and shows off "pure" template
  • Data made available for the demo twig file
  • Styles for just this component
  • PURE twig template, usable by PL, Grav, Drupal
  • Javascript module pulling together logic/styles

Steal card markup from

source/_patterns/00-protons/html5up-phantom/index.html
and paste it into

_phantom-card.twig

<article class="style1">
  <span class="image">
    <img 
      src="https://www.fillmurray.com/353/326" 
      alt=""
    />
  </span>
  <a href="#">
    <h2>Magna</h2>
    <div class="content">
      <p>Sed nisl arcu euismod sit amet nisi
      lorem etiam dolor veroeros et feugiat.</p>
    </div>
  </a>
</article>

It's not pretty, but let's roll with it. Change img src and href to something generic for now.

 

Our card should show up in PL!

This looks gross because the CSS we inherited is ... not good.

<div class="tiles">
  {% include '@molecules/phantom-card/_phantom-card.twig' %}
</div>

In demo/phantom-cards.twig, surround the include with .tiles:

If we truly want to do this the RIGHT way, we'd

 

  1. BEM the heck out of it
  2. Pull the phantom styles into
    _phantom-card.scss
  3. Rewrite the ugly css to be much more modular, with lower specificity
<article class="phantom-card phantom-card--style1">
  <span class="phantom-card__image-wrapper">
    <img
      class="phantom-card__image"
      src="https://www.fillmurray.com/353/326" 
      alt=""
    />
  </span>
  <a href="#" class="phantom-card__link">
    <h2 class="phantom-card__title">Magna</h2>
    <div class="phantom-card__content">
      <p>Sed nisl arcu euismod sit amet nisi
      lorem etiam dolor veroeros et feugiat.</p>
    </div>
  </a>
</article>
.phantom-card {
  transition: transform 0.5s ease, opacity 0.5s ease;
  position: relative;
  width: calc(33.33333% - 2.5em);
  margin: 2.5em 0 0 2.5em;
}

.phantom-card__image-wrapper {
  transition: transform 0.5s ease;
  position: relative;
  display: block;
  width: 100%;
  border-radius: 4px;
  overflow: hidden;
}

.phantom-card__image {
  display: block;
  width: 100%;
}

// ...

Let's make our Twig files dynamic!

 

Add variables to _phantom-card.twig

 

Update demo/phantom-cards.yml to provide data automatically to twig.

 

Ta da!

 

Variables from .yml files are automatically provided to .twig files of the same base name.

<article class="phantom-card phantom-card--style1">
  <span class="phantom-card__image-wrapper">
    <img
      class="phantom-card__image"
      src="{{ phantom_card.image }}" 
      alt="{{ phantom_card.image_alt }}"
    />
  </span>
  <a href="{{ phantom_card.url }}" class="phantom-card__link">
    <h2 class="phantom-card__title">{{ phantom_card.title }}</h2>
    <div class="phantom-card__content">
      <p>{{ phantom_card.content }}</p>
    </div>
  </a>
</article>
phantom_card:
  image: https://www.fillmurray.com/353/326
  image_alt: Picture of Bill Murray
  url: '#'
  title: PNWDS2018!
  content: Lorem ipsum dolor sit amet.

Integration to Drupal

1. In Drupal, install and enable Component Libraries module.

2. Enable Particle theme and set as default.

3. See:

apps/drupal/templates/content/node--article--teaser.html.twig
{% set article_card = {
  card_border: 'none',
  card_title: label,
  card_text: content.body,
  button: {
    button_element: 'a',
    button_color: 'secondary',
    button_text: 'View details »'|t,
    button_link: url,
  }
} %}

{% include '@molecules/card/_card.twig' with article_card %}

Namespace Generation

particle.info.yml

  1. Gulp task reads filesystem on change of twig files and writes out yaml for Drupal (and PL, and Grav, etc)
  2. Any application that understands Twig namespaces is compatible with some work, ie all Symfony apps.
  3. Gulp task editable at:

    tools/tasks/gulp-twig-namespaces.js

Integration to Drupal

  1. Node view modes

  2. Views content and fields

  3. Paragraphs

  4. Field templates

  5. Entities

  6. Blocks

  7. Menus

  8. Custom theme hooks

  • MODEL: Drupal data provided to a hook

  • VIEW: The actual Particle twig component

  • PRESENTER: The intermediate Drupal "translator" between Drupal data and the  Particle Twig component, ie: node--article--teaser.html.twig

Drupal hooks

Drupal View of Article Teasers

Drupal Libraries: TNG

core:
  css:
    theme:
      /themes/particle/dist/assets/app-drupal.styles.css:
        preprocess: true
  js:
    /themes/particle/dist/assets/app-drupal.js:
      preprocess: true
  dependencies:
    - particle/jquery
    - particle/lodash
    - core/drupal
    - core/drupalSettings
jquery:
  js:
    /themes/particle/dist/assets/drupal-jquery.js: {
      minified: true, weight: -20 
    }

lodash:
  js:
    /themes/particle/dist/assets/drupal-lodash.js: { 
      minified: true, weight: -20 
    }

particle.libraries.yml

# ...
libraries:
  - particle/core
libraries-override:
  core/jquery: particle/jquery
  core/underscore: particle/lodash
# ...

particle.info.yml

!!!!!!

Testing

  1. Javascript unit testing with Jest

  2. Accessibility testing with pa11y

  3. Visual regression testing with Backstop (soon)

  4. End-to-end testing with Cypress.io (soon)

Jest Unit Testing

We write A LOT of JavaScript on client projects.

 

NONE OF IT IS TESTED. Until now.

 

Write your JavaScript in such a way that it CAN be tested. Stop storing state in the DOM. Make your functions pure. Use libraries (like Redux) that move logic away from HTML.

Accessibility testing with pa11y

Use pa11y automated accessibility testing against a running Pattern Lab prototype to catch most issues early.

 

Start up your local PL:

 

In another session, install then run pa11y:

 

 

See ./tools/tests/accessibility/pa11y.js:

 

ALL Pattern Lab urls are automatically tested!

npm start
npm install pa11y
npm run test:pa11y

Backstop (coming soon)

VueJS + Particle

  1. "The best parts of React and Angular6 with no boilerplate." 

  2. Industry-leading virtual DOM and Reactivity Engine

  3. Simple to learn, incredible resources

  4. All tooling preconfigured in Particle, use .vue files immediately

  5. Never build another widget in jQuery again

  6. Starter examples and guide at @molecules/vue-widgets

  7. Non-trivial Phase2 client app here.

Current: v10.1.0

Next: v10.2.0

  • MULTIPLE DESIGN SYSTEMS for multiple apps

  • Simpler, unified commands

  • Easier to add and remove features

  • Backstop

Contributors

  • Christopher Bloom

  • Yugi Nali

  • Mike Potter

  • Kenny Black

  • Brigette Eckert

  • Daniel Lemay

  • Frederick Engelhardt

Thank you!

Copy of Particle: Build Your Own Design Systems

By Jorge Ram

Copy of Particle: Build Your Own Design Systems

We'll learn how the following features of the project fit together to build Design Systems that are independent of any application or CMS: Webpack bundling Webpack dev server Gulp Iconfont auto-generation Bootstrap 4 integration Javascript and Sass linting Design systems integration to a Drupal and Pattern Lab "app"

  • 662