Copy environment

Overview

The following will try to explain the structure & logic of our UI pattern library code, located in src/patterns.

We use Fractal as our style guide engine, so please read the Fractal docs first.

Quick Start

Development

Run npm run dev:styleguide. This will compile all assets, start a local server, and starts watching for changes.

Build

Run npm run build:styleguide. This will build a static styleguide to app/styleguide/build.

Tests

We run HTML validation tests against all components and their variants in the pattern library.

To run the tests locally, run npm t.

Structure

The file structure can be visualized like this:

patterns/
├── components/
├── modules/
├── views/
├── preview/
├── index.fractal.ts
├── index.ts
└── public-path.ts

Let’s go through the list:

  • patterns/components directory includes all reusable components.

  • patterns/modules directory includes all reusable modules.

  • patterns/views directory includes all reusable view templates.

  • patterns/preview directory includes all preview templates. See more below.

  • public-path.ts sets the path from where to load dynamic assets from our JavaScript bundles. You should not need to change this file.

  • index.ts is our main entry file.

    Its purpose is to:

    • Set the public path for loading dynamic assets via import './public-path';.
    • Import necessary JavaScript polyfills. You can add additional polyfills if necessary.
    • Priority-import some components/modules whose styles should be applied first. Add some more if necessary.
    • Collect, require and export all components, modules and views found in our pattern library.
  • index.fractal.ts is our main entry file when developing or building the pattern library. You should not need to change this file.

    It primarily carries the same function as index.ts - the file re-exports all components, modules and views.

    Additionally, it:

    • imports the iframe-resizer script that’s used for automatic resizing of component previews
    • imports styles that are necessary for demoing some components in the pattern library
  • styles.fractal.scss includes styles that are intended to be used only for demo purposes in the pattern library and should never be included in application environments.

    For example, we use the sg-box class to visualize aspects of Grid component.

Preview templates

Please read the Fractal docs for preview layouts.

There are two preview templates provided out of the box: @preview and @preview-container.

@preview

The default preview template that is automatically used for all components, modules and views. It does the necessary setup for including necessary assets - styles, scripts, favicon etc.

If it is deemed necessary to edit the template, keep in mind that the same preview template is used in both Fractal and WordPress, so be mindful of the differences.

@preview-container

A secondary preview template that does everything the default template also does, and in addition, wraps the component in h-container element.

Use this template when:

  • a component preview uses grid and thus makes the page horizontally scrollable if not wrapped in a container.
  • a component preview is too ugly (ha!) when used without container - for example, when text blocks are too wide.

Usage - set the preview key in component config:

{
    "preview": "@preview-container"
}

Components, modules and views

A quote from the Fractal docs:

Pattern libraries are a way of designing and building websites in a modular fashion, breaking up the UI into small, reusable chunks that can then later be assembled in a variety of ways to build anything from larger components right up to whole pages.

This is our methodology as well (which is a part of why we’re using Fractal).

To extend that mindset, we have split our patterns to three major categories:

  • components - small, reusable chunks of HTML, CSS and JavaScript that can include other components.
  • modules - full-width page blocks that should be constructed from components, or use custom HTML and styles.
  • views - full page templates that should be put together from modules.

If you’re confused about whether a pattern should be a component or a module - if the pattern can be included directly into a view with no extra markup, it’s a module. Otherwise, it’s a component.

Overview of a component

Note: to make this more confusing, “component” refers to a pattern in the Fractal sense - all our components, modules and views are “components” for Fractal.

To start, here’s an example structure of a component:

button/
├── button.config.json
├── button.twig
├── button.ts
└── button.scss

A component consists of the following files:

  • [name].twig - a template file with all the view logic and HTML. This file is required.
  • [name].config.json - a configuration file that is in 99.9% of cases required for style guide demo purposes.
  • [name].scss - an optional Sass file that should include all and only the styles necessary to render the component.
  • [name].ts - an optional TypeScript file that should import the Sass file (if applicable) and include all necessary JavaScript logic that the component requires. Read more.
  • Additionally, there may be some more assets (for example, images) that the component requires - these should also be kept in the component directory. If there are a lot of additional assets, organize them into subdirectories.

[name].twig

If you need to include another component/module/view, include it via the Fractal handle: {% include '@button' %}. To find out the handle, visit the “Info” tab on your component page in the style guide.

If you need to link to an external asset from the template, use the path filter: {{ '/inc/img/image.jpg'|path }}. This will make sure the asset path is correct in both local and built style guide and also in the WordPress theme.

Keep in mind that you can’t use the only keyword that exists in Twig since using that will break passing of some Fractal environment variables that are necessary for the path filter to work. Additionally, keep in mind that top-level variables are not scoped to the specific component but rather passed down to child includes, so it may be necessary to define top-level variables as empty strings in some cases.

Please refer to our HTML & Twig Code Style Guide and the official Twig docs for more granular explanation.

[name].config.json

When defining context data, keep in mind that most of the values should be defined in a nested data object. This is a requirement of our architecture. In general, all context data should be in that nested object, except data that should be configured on a component/module/view level, for example modifier or class.

Keep in mind that the data defined in this file is important for the theme developer who needs to build admin interfaces, so keep it clear and concise. If there are variations of the data, be sure to define different variants.

Please refer to the official Fractal docs for a more granular explanation.

[name].scss

If a component depends on an external CSS file, import it in your script file instead of in here. That way, if multiple components depend on the same external CSS, the styles will not be duplicated in the final bundle.

Please refer to our CSS & Sass Code Style Guide and the official Sass docs for a more granular explanation.