アトミックデザインについてのメモ

更新日 : 2023/9/18

最近Reactについて少し勉強していたのですが、その際にアトミックデザインというものを知り、React以外でも使い道がありそうだと思ったので簡単に整理します。

アトミックデザインとは

そもそもアトミックデザインとは何かということですが、システムのデザイン設計手法のことのようです。
ReactやVueなどでよく使われる手法ですが、それらのフレームワークに限った手法ではありません。
ただ、画面上の要素をコンポーネントとして管理するフレームワークとの相性が良いので、それらのサービスとよく一緒に使われるんですね。
アトミックデザインでは、画面上の部品を大きく以下の5つに分類します。
  • Atom
  • Molecule
  • Organism
  • Template
  • Page
上から順に要素の枠としての大きさが大きくなっていきます。
次のセクションから1つ1つが何を表しているのか簡単に整理します。

アトミックデザインの各要素について

先程のセクションで5つの要素があると書きましたが、それぞれについて簡単にまとめます。

Atom

まずはAtomです。
日本語だと「原子」という意味で、アトミックデザインの中で一番小さな要素となります。
具体的な画面上の要素としては、「ボタン」や「入力ボックス」、「アイコン」、「単行テキスト」などが該当するのですが、この単位が最小のコンポートとなります。
Reactのコードで、ボタンと入力ボックスを書くと以下のような感じです。
Atombutton.js
1export const AtomButton = (children) => {
2    return <button>{children}</button>;
3};
AtomInput.js
1export const AtomInput = ({ placeholderText }) => {
2    return <input type="text" placeholder={placeholderText} />;
3};
そしてこのAtomの集まりで、次のmoleculeを構成します。

Moleculeとは

続いてMoleculeです。
日本語だと「分子」という意味で、 先程のAtomの集まった物がこのMoleculeです。
具体的な画面上の要素としては、「アイコン+メニュー名」や「検索テキスト入力欄+検索ボタン」、「サムネイル画像+題名」などが該当します。
さっき上で作成したAtomを使って、Reactのコードで書くと以下のような感じです。
MoleculeSearchComponent.js
1import { AtomButton } from "./atoms/button/AtomButton";
2import { AtomInput } from "./atoms/input/AtomInput";
3
4export const MoleculeSearchComponent = () => {
5    return (
6        <div>
7            <AtomInput placeholderText="検索文字を入力してください" />
8            <AtomButton>検索</AtomButton>
9        </div>
10    );
11};

Organismとは

続いてOrganismです。
同じパーツが繰り返し使われている要素を指すそうです。
具体的には、「記事一覧」や「商品一覧メニュー」、「サイドメニュー」などが該当するのですが、中にAtomやMoleculeを含むこともあります。
以下がReactを使って、記事のカードを作成した例です。(前のAtomとMoleculeで作成したパーツは使っていません。。)
OrganismCard.js
1export const PostCard = ( { thumbnailPath,  altText, title, postDate, updateDate, } ) => {
2    return (
3        <div>
4            <img
5                height={320}
6                width={320}
7                src={thumbnailPath}
8                alt={altText}
9            />
10            <dl>
11                <dt>記事タイトル</dt>
12                <dd>{title}</dd>
13                <dt>投稿日</dt>
14                <dd>{postDate}</dd>
15                <dt>更新日</dt>
16                <dd>{updateDate}</dd>
17            </dl>
18        </div>
19    );
20};
当然このままだとデザイン性がなさすぎて使い物にならないのですが、このようにpropsで受け取った値をループすることで同じコンポートネントを複製していくようなイメージですね。
また、サンプルなので全くAtomに細分化していないのですが、divタグ内の要素は別コンポーネントに分けたほうが良いのかもしれません。

Templateとは

続いてTemplateです。
このTemplateは、ページを構成する要素のうち、全てもしくはいくつかのページで共通するコンポーネントとなります。
具体的な例としては、ヘッダーやフッターなどですね。
一応Reactのコードで書こうとすると以下のようなものです。
TemplateLayout.js
1import { Header } from "./atoms/layout/Header";
2import { Footer } from "./atoms/layout/Footer";
3
4export const TemplateLayout = ({children}) => {
5    return (
6        <>
7            <Header />
8            { children }
9            <Footer />
10        </>
11    )
12}

Pageとは

最後はPageです。
ここまで出てきたAtom, Molecule, Organism, Templateを元に作成された、ユーザーから見える一つ一つのページとなります。
当たり前ですがページの内容はページによってまちまちなので、特にこれといったコードはありませんが、今書いているこのアトミックデザインの記事のような物が具体的な例になるかと思います。

最後に

以上、アトミックデザインについて簡単ですが整理しました。

実務のプロジェクトでは
「この考え方と完全に一致するように必ずコンポーネントを分割しましょう!」
という訳にはいかず、プロジェクト毎で分割の仕方は異なるかと思いますが、1つの参考として使えそうですね。

それでは!