Atomic Design with React

Atomic Design Process
Atomic Design Process

In 2015, Brad Frost introduced Atomic Design. It is a methodology for hierarchically designing user interfaces from the small components called atoms to the large components called templates. We can make specific instances called pages from templates by putting content into them.

There are steps for atoms to be templates. A group of atoms is called a molecule. A group of molecules and atoms is called an organism. A group of three of these is called a template.

You are free to read the book here, Atomic Design by Brad Frost. The book has five chapters. All links to resources of every chapter are documented enough in a single list that can be found here, Atomic Design Resources.

Summary of the book Atomic Design

I summarized all chapters here. You can read the book if my summary is not clear enough.

1. Designing Systems

Create design systems, not pages. This chapter tells about historical issues and how they influenced the importance and benefits of system design and pattern libraries. For example, thinking about redesigning a university website that has around 30,000 pages is a pain. But it is another perspective if we think about redesigning the design system.

2. Atomic Design Methodology

I think this chapter is the core of the book. It explains the methodology and the origin of its name. This chapter gave examples of all components of atoms, molecules, organisms, templates, and pages. It demonstrated how this methodology is applied in the native mobile app of Instagram.

3. Tools of the Trade

The author introduced the tool called Pattern Lab and a logicless templating language called Mustache. Pattern Lab is a static site generator tool for building atomic design systems. It is also a pattern starter kit for documentation and annotation tool. This chapter explained about effective style guides.

4. The Atomic Workflow

This chapter is about the process and creating design systems. It introduced interface inventories. An interface inventory is a comprehensive collection of the bits and pieces that make up your user interface.

5. Maintaining Design Systems

This chapter is about creating maintainable design systems. To set up your design system for long-term success, you need to:

  1. Make it official.
  2. Make it adaptable.
  3. Make it maintainable.
  4. Make it cross-disciplinary.
  5. Make it approachable.
  6. Make it visible.
  7. Make it bigger.
  8. Make it context-agnostic.
  9. Make it contextual.
  10. Make it last.

Hands-on with React

I didn't want to repeat the explanation of the method like what I found on Medium and YouTube here. You can read the second chapter of the book for that. What I want to show here is the hands-on of this method with React in a simple technical enough that make you understand the basics.

In this example, we are going to create a contact page. The contact page is a common page that most websites have. Our tools are React, TypeScript, and TailwindCSS.

Atoms

Let's start with atoms, the basic building blocks. We create a submit button, text and email input, text area, and page title.

ButtonSubmit.tsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
export default function ButtonSubmit() {
  return (
    <button
      type="submit"
      className="bg-cyan-400 hover:bg-cyan-700 px-8 py-2 text-white rounded-lg ease-linear duration-300 w-full"
    >
      Submit
    </button>
  )
}

InputEmail.tsx

1
2
3
4
5
6
7
8
9
export default function InputEmail() {
  return (
    <input
      type="email"
      placeholder="Email..."
      className="px-8 py-2 rounded-lg border-2 border-cyan-400 focus:border-cyan-700 w-full"
    />
  )
}

InputText.tsx

1
2
3
4
5
6
7
8
9
export default function InputText(props: any) {
  return (
    <input
      type="text"
      placeholder={props.placeholder}
      className="px-8 py-2 rounded-lg border-2 border-cyan-400 focus:border-cyan-700 w-full"
    />
  )
}

Textarea.tsx

1
2
3
4
5
6
7
8
9
export default function Textarea() {
  return (
    <textarea
      rows={8}
      placeholder="Message..."
      className="px-8 py-2 rounded-lg border-2 border-cyan-400 focus:border-cyan-700 w-full">
    </textarea>
  )
}

Title.tsx

1
2
3
export default function Title(props: any) {
  return <h1 className="text-3xl font-bold text-center my-8">{props.content}</h1>
}

Molecules

We wrap the atom to make a molecule of a form field.

FieldEmail.tsx

1
2
3
4
5
6
7
import InputEmail from "../atoms/InputEmail";

export default function FieldEmail() {
  return (
    <p className="my-8"><InputEmail /></p>
  )
}

FieldSubmit.tsx

1
2
3
4
5
6
7
import ButtonSubmit from "../atoms/ButtonSubmit"

export default function FieldSubmit() {
  return (
    <p className="my-8"><ButtonSubmit /></p>
  )
}

FieldText.tsx

1
2
3
4
5
6
7
import InputText from "../atoms/InputText";

export default function FieldText(props: any) {
  return (
    <p className="my-8"><InputText placeholder={props.placeholder} /></p>
  )
}

FieldTextarea.tsx

1
2
3
4
5
6
7
import Textarea from "../atoms/Textarea";

export default function FieldTextarea() {
  return (
    <p className="my-8"><Textarea /></p>
  )
}

Organics

Molecules of form fields are combined to form a contact form.

ContactForm.tsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import FieldSubmit from "../moleculs/FieldSubmit";
import FieldEmail from "../moleculs/FieldEmail";
import FieldText from "../moleculs/FieldText";
import FieldTextarea from "../moleculs/FieldTextarea";

export default function ContactForm() {
  return (
    <form method="post" className="max-w-md mx-auto">
      <FieldText placeholder="Name..." />
      <FieldEmail />
      <FieldTextarea />
      <FieldSubmit />
    </form>
  )
}

Templates

The basic components of a contact page are a page title, content, and a contact form.

Contact.tsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import Title from "../atoms/Title";
import ContactForm from "../organics/ContactForm";

export default function Contact(props: any) {
  return (
    <section className="max-w-lg mx-auto">
      <Title content={props.title} />
      {props.content}
      <ContactForm />
    </section>
  )
}

Pages

A page is a template with specific content. In this example, I hardcoded that title and content. In the real world, it comes from the repository/database/API.

Contact.tsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import TemplatesContact from '../templates/Contact';

export default function Contact() {
  return (
    <TemplatesContact
      title="Contact"
      content={
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eget consequat ligula, in tristique purus.</p>
      }
    />
  )
}

Our contact form has no action. In the real world, it will collect the data from its field and send them once the submit button is clicked.

Voila, we just created a contact page with Atomic Design methodology. You can get the completed code on GitHub, https://github.com/aristorinjuang/react-atomic-design.

Related Articles