UI Development

ATOMIC DESIGN METHODOLOGY

Atomic design is a new methodology proposed by “Brad Frost” a web designer, speaker, consultant, writer, and musician from Pittsburgh, PA for building effective User Interfaces by breaking down the functionalities at the early stages of design process and building from the bottom up, using our childhood topics we learnt in our Chemistry classes.

Yes, what you read is absolutely correct “Chemistry classes” ??.

The chemical terminologies I’m speaking about are the Atomic Structure concepts we learnt in our childhood, basically atoms, molecules and their structural arrangement .These are related to Component development in User Interface.

A chemical reaction is represented by a  chemical equation, which often shows how atomic elements combine together to form molecules.These molecules combine together to form a much more complex structure.

In the example below, we see how hydrogen and oxygen combine together to form water molecules.

Now, let’s understand how these atomic structures are related to Atomic Design In UI perspective.

This methodology consisted of five distinct stages . All together will create unique interface design systems in a more predetermined and hierarchical manner.

The five stages of atomic design are:

  1. Atoms
  2. Molecules
  3. Organisms
  4. Templates
  5. Pages

Atoms:

Atoms are the most basic and smallest elements/modules in the entire system(forget about the subatomic particles ???).These could be a button, a label text,an image, and all basic html elements come in the category of atoms.

Molecules:

Molecules are relatively smaller groups of UI elements functioning together as a unit, these smaller groups are generally atoms.

i.e In most of the cases Atoms combine together to form a higher level molecule component.

For example let’s consider the input text field, search button,close icon (as shown in below image) are combined as a search form and are able to do something together.

Organisms:

The organisms are next higher level structures than atoms and molecules . Groups of molecules, atoms and/or other organisms are joined together to form a relatively complex and distinct section of a web page .

Unlike atoms and molecules, organisms are not directly included in the page we are designing .They are reusable components that can be easily distinguished with specific actions.

From the UI perspective, organisms are good elements for separating their HTML parts into fragments.

For example a search box with a navbar in the header forms an organism.

Templates:

Multiple organisms ( of course with atoms and molecules ) stitched together will create a template. Once when we are at a template level we could see the design of our page coming together and the layout is built .

Creating templates would reduce the duplication of code which helps the debugging task easier.

In the above template Header, Sidebar, Footer, Content are different components that when bonded together forms a template .

Pages:

Pages are the final stage in atomic design.Templates with final assets such as the text, images, videos that represent the final product will make a page.

These pages will be tested by the testers If they find any issues with any of the content in the page then the developer can modify the sub level components (atoms or molecules basically) to fix the issues.


Let’s have a real time explanation of using this methodology in applications built using React.

Let’s build a simple login page using Atomic Design.

Before we start developing the page, let’s identify different components(atoms,molecules and organisms) that might be used in the page.

Let’s have a look at the directory structure .

Components folder is created under src folder which consists of atoms molecules and organism folders,

Atoms, Molecules and Organisms folder consists of all js and their respective style files(css, scss or any) in it.

List of atoms used are:

  1. Heading text

Heading is a must component that is frequently used in all pages in any application.It is used to render header 1(h1) text on to the page.

 Props:

  1. content : content is the prop from the parent component that is sent to the child component to specify the content that is to displayed on the page.

 Diagram:

   

Heading.js
import React from 'react';
import PropTypes from 'prop-types';
import './Heading.scss';
const HeadingH1 = (props) => {
  const { customText, cname } = props;
  return (
    <>
      <h1 className={`${cname}`}>{customText}</h1>
    </>
  );
};
HeadingH1.propTypes = {
  customText: PropTypes.string.isRequired,
  cname: PropTypes.string,
};
HeadingH1.defaultProps = {
  cname: 'main-heading',
};
export default HeadingH1;

   2.Paragraph Text

Different content might be loaded on the page and lets load the text using this atom.

Props:

  1. content : content is the prop from the parent component that is sent to the child component to specify the content that is to displayed on the page.

  Diagram:

TextP.js
import React from 'react';
import PropTypes from 'prop-types';
import './TextP.scss';
const TextP = (props) => {
  const { customText, cname } = props;
  return (
    <>
      <p className={`${cname}`}>{customText}</p>
    </>
  );
};
TextP.propTypes = {
  customText: PropTypes.string.isRequired,
  cname: PropTypes.string.isRequired,
};
export default TextP;

  3.Input field

As we are developing forms Form input component is also to be developed

Props:

  1. placeholder: content is the prop from the parent component that is sent to the child component to specify the placeholder that is to displayed on the input field.
  2. type:type is the prop that defines the type of input field that is used it might a simple text field or password field or any other type.

Diagram:

InputFeild.js
import React from 'react';
import PropTypes from 'prop-types';
import './InputType.scss';

const InputType = (props) => {
  const { content, type, cname } = props;
  return (
    <>
      <div className="form-group">
        <input type={type} className={cname} name={content} placeholder={content} />
      </div>
    </>
  );
};

InputType.propTypes = {
  content: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
  cname: PropTypes.string.isRequired,
};
export default InputType;

  4.Button

Form requires a button component, so let’s develop a button component that can be reused in any molecule or atom.

 Props:

  1. label: lebel is a prop from the parent component that is sent to the child component to specify the content that is to displayed on the button.
  2. type:type is the prop that defines the type of button that is to be rendered on to the page.
  3. classname: Additional styling to the button are sent through this prop.

 Diagram:

Button.js
import React from 'react';
import PropTypes from 'prop-types';

const Button= (props) => {
  const { content, type, cname } = props;
  return (
    <>
      <div className="form-group">
        <button className={cname} type={type}>{content}</button>
      </div>
    </>
  );
};
Button.propTypes = {
  content: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
  cname: PropTypes.string.isRequired,
};
export default Button;

  5. Image

  1. Based on the type of the image the image component is rendered on to the page.

     Props:

    1. source : It is the source url of the image that is passed as a prop to the component .
    2. type : type refers to the styling of the image that is called my the parent component.
    3. alternate : It displays the alt text that is to be displayed if the image is not loaded.

    Diagram:

Image.js
import React from 'react';
import PropTypes from 'prop-types';
//write your component specific styling in Image.scss file
import './Image.scss';
 
const Image = (props) => {
  // Destructuring props
  const {
    source,
    alt,
    classname,
  } = props;
  const ImageJsx = (
    <picture>
      <img className={classname} src={source} alt={alt} />
    </picture>
  );
 
  return (
    <>
      {ImageJsx}
    </>
  );
};

// props validation
Image.propTypes = {
  source: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  classname: PropTypes.string,
};
// default props
Image.defaultProps = {
  classname: '',
};
 
export default Image;

List of molecules used are:

  1. Nav links : Nav links is a collection of links These links would  be a collective set of text atoms.
    1. Atoms used to develop Nav link molecule are:
      1.  Paragraph text

 Props:

  1. type : type refers to the styling of the image that is called my the parent component.

      Diagram:    

Links.js
import React, { Component } from 'react';
import axios from 'axios';

//TextP is a paragragh text atom in atoms folder
import Text from '../../atoms/TextP_Folder/TextP';
 
//importing and Fetching data from external json file.
import dataJson from '../../../../assets/data/links.json';

import './links.scss';
 
class links extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activities: null,
    };
  }
 
  componentDidMount() {
    axios.get(dataJson)
      .then((response) => {
        this.setState({
          activities: response.data,
        });
      });
  }
 
 
  render() {
    const { activities } = this.state;
    if (!activities) {
      return (
        <>
        </>
      );
    }
    return (
      <>
        {activities.Links.map((activity) => (
          <a href={activity.url} label={activity.link_text}><Text cname="link-style" customText={activity.link_text} /></a>
        ))}
      </>
    );
  }
}
 
export default links;

2.Form

This molecule consists of all form level atoms that are required in the form.

Atoms used in Login form are:

  1. Input Text
  2. Button        

Props:

type : type refers to the styling of the image that is called my the parent component.

      Diagram: 

LoginForm.js
import React from 'react';
//import atom components from atoms folder
import Input from '../../atoms/Input_Folder/InputType';
import Button from '../../atoms/Button_Folder/Button';
 
class LoginForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
 
  render() {
    return (
      <form>
//calling input atom and sending the type to be as text
        <Input cname="input" type="text" className="input" content="Email" />
//calling input atom and sending the type to be as password
        <Input cname="input" type="password" className="input" content="Password" />
//calling buttonatom and sending the type to be as submit
        <Button cname=" btn-primary btn-lg btn-block" type="submit" content="Log In" />
        <Button cname="btn btn-outline-primary fb" type="submit" content="New User? SignUp" />
      </form>
    );
  }
}
 
export default LoginForm;

List of organisms used are:

  1. Header
    1. Header is an organism that stays at the top of the page and contains different molecules, atoms .Here header organism consists of :
      1. image (atom)
      2. links(molecule)

Props:

  1. classname: To add some additional styling to header classname is sent as a prop to header.

Diagram:

Header.js
import React, { Component } from 'react';
//importing required atoms and molecules
import Links from '../../molecules/NavLinks_Folder/Navlinks';
import Image from '../../atoms/Image/Image';
import './Header.scss';
 
//importing the assets needed for the image atom

import image from '../../../../assets/images/ta_Logo_B.png';

class Header extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
 
  render() {
    return (
      <>
        <div className="header">
          <Image source={image} classname="image__logo" alt="image not loded" />
          <div className="header-right">
            <Links />
          </div>
        </div>
      </>
    );
  }
}
 
export default Header;

  2. Login Form

  1. From is a composition many form elements
    LoginForm here consists of:

    1. heading (atom)
    2. Form(molecule)

Props:

             Login Form does not take any props.Additionally if required you can send additional styling class as a prop to the form.

Diagram:

Login.js
import React from 'react';

//importing required atoms and molecules 
import Heading4 from '../../atoms/Heading_Folder/Heading';
import LoginForm from '../../molecules/Form_folder/LoginForm';
//importing the scss styles for login
import './Login.scss';
 
class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
 
  render() {
    return (
      <div className="formstyle">
         //calling heading atom and send the text to diaplay as Login
        <Heading4 customText="Login" />
//calling loginform molecule with no props
        <LoginForm />
      </div>
    );
  }
}
 
export default Login;

The final code of importing organisms into a page is shown below

App.js
import React from 'react';

//importing bootstrap files for bootstrap styling
import './bootstrap/scss/bootstrap.scss';

//impoting atoms,molecules,oroganisms that are required in the page level
import TextP from './components/atoms/TextP_Folder/TextP';
import Login from './components/organisms/login_Folder/Login';
import HeadingH2 from './components/atoms/Heading_Folder/Heading';
import Header from './components/organisms/Header_Folder/Header';
 
const App = () => (
  <>
    <Header />
    <HeadingH2 customText="dashboard" cname="px-1 mb-5 text-uppercase template-heading" />
    <div className="row d-flex justify-content-center">
      <div className="col-md-4">
        <Login />
      </div>
    </div>
    <div className="row mt-4">
      <div className="col-md-12">
        <TextP customText="© Copyright BlogSite." cname="my-4 d-flex justify-content-center copyright" />
      </div>
    </div>
  </>
);
 
export default App;

The final output would be as  below shown figure

References:

  1. https://atomicdesign.bradfrost.com/chapter-2/

About The Author

Leave a Reply

*