Atomic Components: Managing Dynamic React Components using Atomic Design — Part 1

Designed by Brad Frost and Dave Olsen, atomic design is a wonderful “methodology for creating design systems” backed by Pattern Lab with five distinct levels or ‘building blocks’, which, when combined, create semantic, contextual relationships between interface objects.

In this two-part series, we’re going to explore how these organizing principles are a natural fit for building interfaces in React, and how with a few tweaks we can begin to contextualize entire interfaces semantically and intuitively.

In Part 1, I’ll be describing how we can apply Atomic principles to interface components, and in Part 2 I’ll be constructing a small interface in React to show how one might apply these principles to a project.


Why do we need tweaks?

In Atomic Design, organisms may compose many things. Consider the ‘product grid’ organism as described on Pattern Lab which composes a series of like-item molecules, each with product title, product description, product image, etc. After utilizing the encapsulation principles organisms provide us, Atomic Design suggests a pivot to implementation:

Now that we have organisms defined in our design system, we can now break our chemistry analogy and apply all these components to something that resembles a Web page!

In traditional Atomic Design, the organism relates to other organisms only in the that they co-exist in visual space alongside one another on the template or page. We lack an atomic principle to describe groups of organisms in communication with one another.

Atomic Design’s five major stages — atoms -> molecules -> organisms -> templates -> pages — map incredibly well to static domains, i.e. crafting mockups and document-oriented, pre-SPA web pages. This is exemplified by the naming convention it chooses to model its last two stages, templates and pages, where a template is a yet-to-be implemented page whose primary purpose is to “articulate the design’s underlying content structure” usually through a wireframe or a sketch. This gives an overview of how organisms and molecules are going to be organized without the specific implementation details the pages provide..

Can we extend the Atomic metaphor in useful ways such that we are able to describe components which have a dynamic lifecycle of their own inside of an abstract environment and do not easily map to static mediums?

Pattern Lab is designed to be flexible with regards to naming and structure. There’s really no One Right Way to do this, and we think that’s just fine. Name things as you please, and we’ll leave the hair-splitting out of things.

Cool. Let’s come up with an approach.


What are the tweaks?

When using React to build interfaces, it is rare to think in terms of pages. Instead, what would traditionally be a webpage or document is now simply a stateless, dynamic abstraction inside of which our components render, disappear, confirm, reject, reveal, hide, and so on.

When designing single-page applications, the physical page metaphor breaks down — there is only one — and we’re left with a need for something that is capable of not only encapsulating component interactivity, but also has the potential to facilitate the stateful and communication-oriented aspect of component design.

To address this, we extend the biochemical metaphor even further and introduce the ecosystem and environment.

Icons made by Yannick, Freepik from www.flaticon.com

Ecosystem

Ecosystems are container components which are composed of multiple organism components. In React, we can use these container components to organize, manage, and delegate messages to organism components as well as communicate with other ecosystems through a shared environment.

We compose multiple ecosystems into a single environment, the application.

Let’s take a social network UI example:

This might seem pretty complex or overwhelming at first, but have no fear! As soon as we begin organizing components according to Atomic principles, we can very easily understand the whole of the application in manageable chunks.

Ecosystems should semantically represent the major core components and ideas the interface is trying to communicate, which, typically, correlate to visual space — this helps with styling. In this example, three major ecosystems stand out at first glance: a chat ecosystem, a header/orientation ecosystem, and a profile ecosystem.

You may be wondering, “Could the profile ecosystem be its own, fourth ecosystem? I think it seems distinct enough that we can separate it,” and the answer is “absolutely.” However, I did not in this case because I could just as well not consider it to be a critical component of the profile ecosystem, and better described as something that has a relationships with the profile… which bring me to an important point:

As in nature, ecosystems can be nested.

The notification portion of the profile ecosystem is distinct enough from the profile image and status portion that we can separate them into two separate ecosystems, both still under one, main, ‘profile’ ecosystem. The chat ecosystem is separated into a friend-list nested ecosystem to allow for the eventual implementation of another peer ecosystem that shares a relationship with the chat functionality, but is not best described by the ‘list’ ecosystem, just like our profile — Perhaps we wish to add the actual dialog interface and components necessary to chat with our friends in that negative space.

Keep in mind that nested ecosystems should never be conceptually independent from the parent ecosystem, and when communicating, a nested ecosystem should never directly communicate to another nested ecosystem— Let the parents do the talking.

Once we begin populating our ecosystems with organisms — in yellow, our app really starts taking shape and becomes less difficult to fully conceptualize.

Ecosystems provide context and organization principles for organisms who share a relationship with one another. They also provide an interface for communication between similar organisms, as well as with organisms in other ecosystems.

Environment

There is only one environment, and in React, this is the top-level <App /> component. Because there are typically no pages in React, the environment represents the whole within which all ecosystems, organisms, molecules, and atoms compose one another and communicate.


Folder Structure

When React first launched, most components were thrown together in a single component folder and imported into one another using a relative paths from the parent component.

components/
-- Copyright.js
-- Footer.js
-- Header.js
-- Logo.js
-- Login.js
-- Profile.js
-- ProfileAvatar.js
-- ProfileHeaderImage.js
-- ProfileImages.js
-- SocialMedia.js
-- Status.js

Soon after, we began to adopt organization principles taken from other SPA frameworks, such as Angular or Ember, and organize our components with a specific implementation or module pattern in mind.

components/
-- header/
---- Header.js
---- Logo.js
---- Login.js
-- profile/
---- Profile.js
---- ProfileAvatar.js
---- ProfileImages.js
---- ProfileHeaderImage.js
---- Status.js
-- footer/
---- Copyright.js
---- Footer.js
---- SocialMedia.js

With Atomic Components, instead of organizing our project structure around implementation details, we instead rely on a flat folder structure, relying on the inherently semantic hierarchical relationships between Atomic Components when we compose our interfaces.

//example for Profile
components/
-- atoms/
---- ProfileAvatar.js
---- ProfileHeaderImage.js
-- ecosystems/
-- environment/
-- molecules/
---- ProfileImages.js
-- organisms/
---- Profile.js

This allows us to swap, reuse, and navigate to components easily in various scenarios, granted they are well-composed.

//Profile.js
import { ProfileImages } from '../molecules/ProfileImages'
//ProfileImages.js
import { ProfileAvatar } from '../atom/ProfileAvatar'
import { ProfileHeaderImage } from '../atom/ProfileHeaderImage'

Conclusion

Atomic Design provides semantic rules and principles of organization for interface elements. When applying these principles to components in inherently dynamic environments, we need to rethink the static page metaphor and substitute elements which well-represent dynamic components.

With the addition of ecosystems and the environment, we are able to provide a language and infrastructure for dynamic components, as well as give further context to organisms who may at times need to cross-communicate in ways the page/template metaphor doesn’t easily allow.

In part 2, I will be constructing a small interface in React to show how these Atomic Components can improve workflow when designing interfaces.