React.js-based Patternlab.io

• about 1,300 words

It’s an idea and all about components, patterns and composability

This morning, I was thinking of two things I wanted to try out when I got some free time (and a bit of inspiration): React.js and Pattern Lab. But I don’t want to experiment with them separately—because with a bit of imagination, they fit together perfectly.

This arti­cle was also pub­lished on Medium.

What are those?

React is a JavaScript library (by Face­book) to eas­ily cre­ate UI com­po­nents, which can be com­bined and nested. Tech­ni­cally fas­ci­nat­ing is the imple­men­ta­tion of the Vir­tual DOM that abstracts away to ren­der­ing of reg­u­lar HTML ele­ments to the browser’s DOM. This allows React to quickly re-ren­der a whole tree of nested com­po­nents when data changes and only update those parts of the view that are affected by the change. Addi­tion­ally, this makes it pos­si­ble to ren­der React com­po­nents on a server and use the ren­dered markup on the client.

Pat­tern Lab, on the other hand, is a sys­tem (mainly for web fron­tend devel­op­ers) to take com­po­nents writ­ten as mus­tache tem­plates and dis­play them in fash­ion of atomic web design. You should explore the demo to see how it works (try the eye icon on the top right to dis­play the markup and over­lay anno­ta­tions).

Atomic Web Design (as coined by Brad Frost) describes how the parts of a web page can divided into sev­eral lev­els of abstrac­tion, called atoms, mol­e­cules, organ­isms, tem­plates and pages. Com­bin­ing sev­eral small things forms a new larger thing. Two links and an image (i.e. three atoms) can make up a new mol­e­cule (e.g. a head­line). Tem­plates are full lay­outs, with dummy data. Pages are instances of tem­plates, with use­ful con­tent and maybe spe­cial ele­ments only vis­i­ble in cer­tain cases.

How is it the same?

Let’s take a look at some exam­ple code from Pat­tern Lab (from the demo):

<div class="page">
  {{> organisms-header }}
  <section role="main">
    <h1 class="section-title">Our Outdoor Blog</h1>
    <div class="l-main">
      {{> organisms-latest-posts }}
      {{> molecules-pagination }}
    </div>
    <aside class="l-sidebar">
      {{> organisms-recent-tweets }}
    </aside>
  </section>
  {{> organisms-footer }}
</div>

The organisms-header, that is included in the sec­ond line, is a par­tial (a snip­pet of code that gets injected) that may looks like this:

<header>
  {{> atoms-logo }}
  {{> molecules-primary-nav }}
  {{> molecules-search }}
</header>

As you can see, the pre­fixes of the par­tial names match the nam­ing con­ven­tions of atomic design. The nest­ing of par­tials allows a devel­oper to build com­plex parts (e.g. organisms-latest-posts) using already defined (and designed) smaller ele­ments (i.e. atoms and mol­e­cules in this case).

Now, com­pare this code to the fol­low­ing view in React:

/** @jsx React.DOM */
var React = require('react');
var Logo = require('../atoms/logo');
var PrimaryNav = require('../molecules/primary-nav');
var Search = require('../molecules/search');
var OrganismsHeader = React.createClass({
  render: function () {
    return (
      <header>
        <Logo/>
        <PrimaryNav/>
        <Search/>
      </header>
    );
  }
});
module.exports = OrganismsHeader;

Even though this is using the React-spe­cific JSX, I believe it’s not that hard to see this results in the same markup as the mus­tache tem­plate above. Instead of using {{> atoms-logo }} we use the Logo com­po­nent loaded in line four and ren­der it as first child of the <header> ele­ment.

(JSX is a JavaScript pre­proces­sor replac­ing the HTML tags with actual code. I don’t really like it. You can also write the same ren­der func­tion in plain JS, using meth­ods like React.DOM.div, or in a quite dif­fer­ent way like here, in Cof­fee­Script.)

Data

That was a nice dis­cov­ery to make, but what’s a bunch of markup with­out any con­tent? Where does the data come from?

Pat­tern Lab can use data defined in .json files exist­ing next to your .mustache files to add con­tent to your tem­plates (see the doc­u­men­ta­tion). Using this, one might be able to use it as a sta­tic site gen­er­a­tor, with the added ben­e­fit of also hav­ing access to an overview of all the pat­terns used on your final pages.

React com­po­nents have two ways of con­tain­ing data: props (prop­er­ties) that are set when the com­po­nent is instan­ti­ated, and state, that may change when the user inter­acts with the com­po­nent (e.g. when a but­ton is tog­gled).

The most straight-for­ward way to inte­grate these sys­tems would be to load the JSON data in the top-most React com­po­nent and use that to set the prop­er­ties of all nested com­po­nents.

Ran­dom Data

When defin­ing React com­po­nents, one can also add cus­tom val­i­da­tions for all pos­si­ble prop­er­ties (using Prop­Types). That means, instead of using fixed con­tent writ­ten once, we could use a library like Faker.js to dynam­i­cally cre­ate new data for each com­po­nent ren­dered.

This way, the demon­stra­tion of com­po­nents would not just show the cases the devel­op­ers thought of (reg­u­lar names, short texts), but also the edge-cases (extremely long head­lines, badly for­mat­ted texts). And just for the fun of it, there could also be a Shuf­fle but­ton next to each com­po­nent exam­ple to gen­er­ate new con­tent.

Update (21 Jul 2014): I recently imple­mented a small JS mod­ule called React­Prop­Schema, which imple­ments most of these aspects: Val­i­dat­ing that a given data struc­ture matches a schema and gen­er­at­ing fake data using the the same schema and Faker.js. It can also be eas­ily used to describe propTypes in React com­po­nents. You can find it on GitHub and npm.

Show­ing Depen­den­cies

One of the nicest fea­tures of Pat­tern Lab is that is explic­itly list the places where each par­tial is used and which other par­tials it includes. In the demo, the header organ­ism includes:

The organ­isms-header pat­tern con­tains the fol­low­ing pat­terns: atoms-logo, mol­e­cules-pri­mary-nav, mol­e­cules-search

The organ­isms-header pat­tern is included in the fol­low­ing pat­terns: tem­plates-home­page, tem­plates-blog, tem­plates-arti­cle, pages-blog

To recre­ate such a behav­ior in a React-based appli­ca­tion, one might have to build a depen­dency graph using the require() calls in each com­po­nent file (assum­ing one uses Com­monJS mod­ules and each React com­po­nent is in one file). It is prob­a­bly pos­si­ble to lever­age some of pro­cess­ing browser­ify does.

What about CSS?

Good ques­tion. I haven’t found a good solu­tion for han­dling stylesheets on a com­po­nent based level. I would like to use SCSS and be able to han­dle the imports of other stylesheets sim­i­lar to how a com­po­nent might require another com­po­nent it embeds. At the same time, the SCSS file would also need access to global vari­ables like col­ors and to mixin libraries like bur­bon.

For now, I’ll be happy if I can get a work­flow where I can edit my SCSS using Chrome’s Inspec­tor as described here.

Con­clu­sion

As of now (6 April 2014), this is all the­o­ret­i­cal. I’m not sure if or when I might imple­ment (some of) this as I need to find a pro­ject for which this is a good fit (Web appli­ca­tion based on React, design based on pat­terns, pos­si­ble with­out using Pho­to­shop first).

Do you think this would work? Would it be use­ful? Would you do it dif­fer­ently? It’d love to hear from you.