Atomic Guide

Pattern guides are created in order to gain a perspective of the project’s parts and inner workings. This process helps developers arrive at an educated decision based on the project’s context. By working in this fashion authors can identify possible coding issues and collectively organize these shared principles across an interface.

Atomic Guide : A static site generator approach to building atomic structures with Assemble.io, Node and Gulp. Available on Github

Patterns & Partials

Establishing patterns/modules/components in isolation breeds reusable pieces that can be quickly distributed across a wide range of contexts (think Legos). A static site generator in this case will allow authors to structure bits of HTML into partials and templates. Partials are simply tiny chunks of HTML pulled into the document(s) during a build process. You could compare these to includes if you’re familiar with PHP. This philosophy in Web Development was originally pioneered by Brad Frost. If you’re not familiar with his philosophy you can read Brad’s book on the topic.

Atomic Installation

To begin, you’ll need Node, Bower and Gulp to run the Atomic Guide project locally on your machine. Node, Bower and Gulp installation is outside the scope of this article, but there are many links on the Web that exist to get you started should you need assistance.

npm install && bower install

Running the command above will install all dependencies required to run Atomic Guide. Inside the root directory of the project you should see a folder with the name “site.” This directory will contain all our template files including partials we’ll be creating in the next section.

Making Partials

Partials are the bits that help identify and build out components from a molecular level. The static site generator we’re using (Assemble) writes to .hbs files instead of .html. Again, these templates will be converted to HTML during the final build process. Begin by opening a text editor and creating an element of your choosing. For example purposes I’ll make a radio input that will contain a few states for styling and based on the user’s interaction.

<label for="radio" class="control radio">
  <input type="radio" id="radio" name="radio" value="radio">
  <span class="control__indicator"></span> Radio Input
</label>
site/templates/includes/atoms/input-radio.hbs

Importing The Partial

With the partial created we’ll need to pull that code into our primary document. By default, Atomic Guide provides you with an index.hbs file as a starting point.

{{> input-radio}}
site/templates/pages/index.hbs

This call above pulls in the radio partial we created prior and saved to site/templates/includes/atoms directory. Be mindful that any adjacent sub directories don’t include duplicated file names. For example, don’t place the input-radio partial within site/templates/includes/atom and another partial named once again input-radio that contains differing content inside site/templates/includes/molecules.

Compiling To Markup

Navigate to the root of the Atomic Guide project via the command-line and run npm start. This task will leverage the locally installed version of gulp to avoid installing the task manager globally to your system. For anyone with Gulp installed globally you can simply run gulp from the command-line. Running an instance in your shell will automatically fire up a server and load the guide into your browser. At this point localhost:4000 should be displaying the atomic guide and the radio input atom we previously created.

YAML For Variations

Assemble uses what’s called data files written in YAML that operate much like databases work to store information. YAML is a human friendly data serialization standard for all programming languages and simplistic enough to create by making a text document and giving it a .yaml file extension.

---
a:
  version: a
  modifierclass: active
  state: checked
b:
  version: b
  modifierclass: hidden
data/radio.yaml

We’ll create a file called radio.yaml and store this file in our data directory adjacent to the site directory.

Calling YAML Variations

With the data file authored and variations defined we can finally make the call from our atomic partial for the radio input.

<label for="radio{{version}}" class="control radio {{modifierclass}}">
  <input type="radio" id="radio{{version}}" name="radio" value="radio{{version}}" {{state}}>
  <span class="control__indicator"></span> Radio Input
</label>
site/templates/includes/atoms/input-radio.hbs

I’ve included the parts we wish to obtain in the YAML file for the radio input’s modifier class, version and state. With those bits ready to go we can write the calls from our atomic guide and provide a preview of the markup to those that will be using the guide as a reference.

{{> input-radio radio}}
{{> input-radio radio.a}}
{{> input-radio radio.b}}
site/templates/pages/index.hbs

The call on line 1 with no variation simply gives us a default radio input minus any modifications. The remaining two inputs use variations defined from the data file. This gives us the following output:

<label for="radio" class="control radio">
  <input type="radio" id="radio" name="radio" value="radio">
  <span class="control__indicator"></span> Radio Input
</label>

<label for="radioa" class="control radio active">
  <input type="radio" id="radioa" name="radio" value="radioa" checked>
  <span class="control__indicator"></span> Radio Input
</label>

<label for="radiob" class="control radio hidden">
  <input type="radio" id="radiob" name="radio" value="radiob">
  <span class="control__indicator"></span> Radio Input
</label>
The output markup for the partials used in the atomic guide

We now have one partial possessing each variation for us to use in the guide and requires authors to edit from minimal locations. If a class change was requested an author could simply edit the YAML file and have it bleed to the other parts of the project! Pretty cool huh?

Show Me The Markup!

By default, Atomic Guide uses Prism from Lea Verou. The build link for the Prism file packaged with Atomic Guide is included should you choose to add additional languages or remove the defaults.

{{> input-radio radio}}
<pre class="language-markup"><code>{{> input-radio radio}}</code></pre>
{{> input-radio radio.a}}
<pre class="language-markup"><code>{{> input-radio radio.a}}</code></pre>
{{> input-radio radio.b}}
<pre class="language-markup"><code>{{> input-radio radio.b}}</code></pre>
site/templates/pages/index.hbs

Typically with raw HTML we’d have to copy and paste our markup multiple times, but the beauty with compiling allows us to use these includes/partials and only write the atom from one location. That’s classy.

<label for="radio" class="control radio">
    <input type="radio" id="radio" name="radio" value="radio">
    <span class="control__indicator"></span> Radio Input
</label>
site/templates/pages/index.html

The Atomic Guide will display the result, automatically cleanse your code block and highlight the syntax on the fly using this custom script.

Show Me The JavaScript!

Maybe you’d like to show some JavaScript snippets in your atomic guide. To do so, the JS snippet and the components atomic guide placement need to follow correct order. For example, If you have a button that has an event listener and is displayed first in the atomic guide markup then your script sample(s) should also follow suite.

{{> button}}
<pre class="language-javascript"><code></code></pre>
site/templates/pages/index.hbs

I’m leaving the JS code block empty since a script will comb the content from the setup that follows.

<script class="atomic-js">var button = document.querySelector('button');
button.addEventListener('click', function() {
  console.log('hello world');
})</script>
site/templates/layout/default.hbs

The above will render this output in your compiled atomic guide…

<button>button</button>
var button = document.querySelector('button');
button.addEventListener('click', function() {
  console.log('hello world');
});
site/index.html

In the future I hope to remove this method and use something more clever like Node to read files and output the content in the correct position without concerns of order.

Color Swatch!

SVG color swatch in action

Out of the box Atomic Guide provides you with a color swatch using SVG rectangles giving users the ability to click on any color block and retrieve hex values and copy them to their clipboard.

{{> swatches}}
site/templates/pages/index.hbs

The swatches partial pulls in the required swatches for Atomic Guide’s primary document. Swatches can be added as needed from the swatches partial itself.

<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<br>

<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 100 100"><rect width="100" height="100"/></svg>
<br>
SVG Color Swatch : site/templates/includes/assembler/swatches.hbs

At any point you’d like to add more colors you can copy and paste the SVG rectangles as needed, but make sure you keep track of order to match the Sass map order controlling where colors are applied in the chain.

$atomic-colors: (
  white: #FFFFFF,
  athens-gray: #F4F5F6,
  gallery: #EEEEEE,

  indigo: #09A3CA,
  chambray: #006EA0,
  big-stone: #002A64
);
site/css/src/assembler/_atomic-globals.scss

The variable setup for swatches takes advantage of a Sass map containing the colors by name identifiers and separated by a space to match the rows outlined in the initial swatch partial.

#colors svg {
  width: 72px;
  height: 72px;

  @for $i from 1 through length($atomic-colors) {
    &:nth-of-type(#{$i}) {
      fill: nth(nth($atomic-colors, $i), 2);
    }
  }
}
site/css/src/assembler/_atomic-swatch.scss

A final loop lets us add as many colors dynamically! Sass leverages the power of the length() function to count your keys in the colors Sass map.

Fork It

Fancy on helping with changes and enhancements? Fork it on GitHub or start a discussion in the issue tracker.

Dennis Gaebel

Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.

Leave a Reply

Your email address will not be published. Required fields are marked *

show formatting examples
<pre class="language-[markup | sass | css | php | javascript | ruby | clike | bash]"><code>
…code example goes here…
</code></pre>

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview

  1. John Doe shouted this comment preview:
    2015/07/30