The recently launched ABC Life is the first website product shipped on a new platform, which signifies the transition from product templates coupled to a CMS, to an API driven, component based front end architecture.

ABC Life homepage

Whilst this platform has many intersecting facets responsible for delivering products to the web, at the core of the front end is a component library, a modular set of product-agnostic building blocks. By taking a systematic approach to developing UI, we avoid the pitfalls of duplication and overrides in a parent-child template system and instead we can build composable, reusable, testable components which will serve as the foundation for many more products to come.

The Design System

The DLS composition metaphor

The component library is developed to the spec of our Design Language System (DLS). Similar to the Atomic Design methodology, the DLS defines design patterns, UX/UI principles and naming conventions – the language – along with a limited set of universal core components. The purpose of this system is to ensure a coherent functionality, visual identity and language, along with the most common usability and accessibility aspects.

Learning to Ship

Predating the current platform, the first attempt to build out the DLS was in the form of a living style guide. The practice of style guide driven development has become very popular over recent years, with many tools available for building a living style guide from an evolving codebase, however this approach ultimately failed for us because there was no direct pathway to get component code into products. Implementation was dependent on product teams writing markup to match the prescribed CSS and JavaScript conventions, which proved to be impractical and inefficient. We needed a better way to package and ship the components.

Betting on React

“React is a triumph of modular design” Laurie Voss, npm

Beginning as a greenfield project aimed at decoupling the front end from the content system, we chose to build this presentation layer with React. With one of the project’s goals being to build a mature set of universal components, React proved to be the best fit of all the options we considered, as it has popularised component based development and risen to dominate the front end space with its intuitive API for building applications.

As a content organisation, it was also critical for us to maintain rendering of content on the server. React ticked that box for us too, allowing us to work towards building isomorphic JavaScript applications.

Anatomy of Life

ABC Life is a product serving traditional pages of content. While the high level application layout is the responsibility of the product, under the hood we can see this layout is a composition of our core components.

The home page and topic pages are defined within the application as an “aggregation page” for displaying collections of articles. For any given section on this page, our (simplified) React tree looks something like this:

Each of these components encapsulates a single responsibility, some examples of which are:

SectionHeader : semantic header element with branded left border

: semantic header element with branded left border Bento : implements CSS Grid layout with a set of layout variants and border styles

: implements CSS Grid layout with a set of layout variants and border styles ContentCard : a key design pattern with a set of layout variants across three breakpoints

If we dive a little deeper into a ContentCard, the React tree looks something like this:

MediaObject : a layout pattern for the image + heading pair inside a link, with the heading first in source order

: a layout pattern for the image + heading pair inside a link, with the heading first in source order ContentImage : supports srcset for responsive images

: supports for responsive images Observer : implements the Intersection Observer API for enabling lazy loading of images

Each of these components is catalogued in our Storybook (more on this below) with examples and documentation, and can be reviewed and tested in isolation.

“If an object in the interface doesn’t have a name — a name that makes sense to your team, and is known and used by people on your team — then it doesn’t exist as a concrete, actionable module to work with.” The Language of Modular Design

Building the Components

Our previous system intended to use a parent template as a vehicle for sharing common code, however in reality each product shipped individual features which were never ported back upstream. Furthermore, there was no way to view UI components in isolation and reviewing how features rendered in the browser was a heavyweight process which typically required developers to checkout and run each others code locally.

We set out to build the components in a way that would make collaboration, code review and testing significantly more efficient.

Monorepo

At its inception, we chose to structure the project as a monorepo, using Lerna for managing the colocated packages. This allowed us to develop our component library as a self contained package, while simultaneously making them available to each application within the monorepo.

“Juggling a multi-module project over multiple repos is like trying to teach a newborn baby how to ride a bike.” Babel

npm

We also support teams external to the monorepo consuming the component library and other infrastructure pieces. We publish these packages to npm for other teams around the ABC to consume in other React projects, including iview, the beta search page and the user profile UI.

Component Catalogue

We adopted Storybook for developing and cataloguing our UI components. It provides an environment for developing each component in isolation, and a medium for testing and documentation.

Obligatory button example

The essence of Storybook is to create visual test cases – stories – where each represents a single state of a React component. Our use case pushes that boundary more towards a catalogue of component variants with examples,

documentation and code snippets.

Storybook Tools

While Storybook is an excellent tool for developing and testing, it is unopinionated about the presentation of stories. This led to inconsistency with how components were structured and documented, which undermined the cohesion of the library as a whole.

To bridge this gap, we built the Storybook Tools package; a set of template components to ensure that all stories are presented with a consistent layout and include key documentation such as a table of props and code snippets. We will dive deeper into this in a future post.

Component Primitives

Our component library includes some low level primitives such as Button, Link and Icon, which are composed into other more evolved components.

Typography is one such primitive component which encapsulates the DLS defined rulesets, designed to a scale with a vertical rhythm of 8px increments with a baseline of 1rem = 16px.

DLS heading specs

The props take integer values corresponding to their absolute pixel size, which gives us flexibility to add additional size definitions without being limited by a naming convention. A raw example usage would be:

This would render class names for CSS:

After adding props for lineHeight, marginBottom, fontWeight and a number of other options, we end up with a relatively large and complex API surface area, so we have kept Typography as a ‘private’ internal component and instead expose Text and Heading which hide this complexity to present a simpler API.

For example, Heading maps each of the DLS-defined sizes to Typography under the hood:

This component can be simply be composed as:

Accessibility

The ABC is committed to comply with the W3C’s Web Content Accessibility Guidelines (WCAG) 2.0 to ensure our web products are usable by all people, whatever their abilities or disabilities. A component based architecture allows us to build products on a foundation of modular parts with solid accessibility compliance.

The Card Pattern

Our design system includes the common ‘card’ pattern of an image with a heading displayed below, which together link to an article. It is best for screen readers to announce the link with the heading first, followed by image alt text. We encapsulate this structure in a component using Flexbox to position the elements in the correct visual order and test it across screen readers and visual browsers.

The card pattern / focus style

Heading comes first in source order

We also ensure the focus state is adequately presented, by styling the inner heading element when the outer <a> has focus.

These accessibility details are relatively simple to implement but are even more easily overlooked. If we get this right in one place, the benefit reaches far.

Diving Deeper with ARIA

Our SiteNavigation component implements the priority+ pattern, which will fit as many navigation items as the viewport width allows, and render any additional items into a drop down menu.

Priority+ Navigation Pattern

This presents more complex accessibility requirements to announce the interaction correctly in a screen reader. The snippet below demonstrates how the button and ul elements are associated with each other via pairing a unique id value with aria-controls and aria-labelledby attributes.

Furthermore, the dropdown button announces additional context via the aria-haspopup attribute (popup being synonymous with dropdown) and the aria-expanded attribute.

We can now encapsulate this accessibility implementation within this component to ensure that future consumers do not have to solve this problem again.

Conclusion

“Favour composition over inheritance” Design Patterns

This article has covered a cross section of the component library for our design system, highlighting the key concepts and tooling behind the scenes. By introducing the composition pattern to our product development, we can now work towards unifying our digital products across the breadth of the ABC through the propagation of a common set of robust building blocks. This can make product teams move faster and ultimately bring consistency to user experience.

Share this: Twitter

Facebook

LinkedIn

Email

Like this: Like Loading...