atomic-design について
Atomic Designは、ユーザーインターフェースをアトム、モレキュール、オーガニズム、テンプレートに整理するスキルです。デザイントークンを使い、継承ではなくコンポジションで、再利用可能な表示コンポーネントをボトムアップに構築します。
主な機能
- 014段階のコンポーネント階層
- 02ボトムアップのコンポーネント構成
- 03表示コンポーネントの責務境界
- 04視覚属性を管理するデザイントークン
- 05継承ではなくコンポジション
活用シーン
- 01UIコンポーネントライブラリの整理
- 02小さな要素から再利用可能なページレイアウトを構築
- 03表示処理をデータ取得やビジネスロジックから分離
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jwilger/ agent-skills --skill atomic-designインストール後、Claude Code で/atomic-designを入力して読み込まれたか確認します。
詳細
アトミックデザイン
価値: シンプルさとコミュニケーションです。名前が付いた小さな部品を組み合わせて UI を構築することで、チームの誰もがインターフェースを理解しやすくなり、モノリシックなコンポーネントから生じる複雑さを防げます。
目的
複雑さが段階的に増す階層(アトム、モレキュール、オーガニズム、テンプレート)に UI コンポーネントを整理する方法を説明します。各レベルには明確な責務と構成ルールがあります。これにより、すべての部品が再利用可能で、単独でテストでき、共通の語彙で名前が付けられたコンポーネントシステムを実現します。
プラクティス
4 つのレベルでボトムアップに構築する
最小の再利用可能な要素から始め、上位の要素を組み立てます。レベルを飛ばしてはいけません。
4 つのレベル:
-
アトム: 分割できない UI 要素です。ボタン、入力欄、ラベル、アイコンなどです。視覚要素は 1 つ、責務も 1 つです。アトムのすべての視覚プロパティ(色、余白、タイポグラフィ)にはデザイントークンを使用します。
-
モレキュール: ひとまとまりの機能を持つ、アトムの小さなグループです。フォームフィールド(ラベル + 入力欄 + エラーメッセージ)、検索バー(入力欄 + ボタン + アイコン)などです。モレキュールごとにインタラクションパターンを 1 つ持たせます。
-
オーガニズム: インターフェースの独立したセクションを構成する、モレキュールとアトムで作られた複雑なコンポーネントです。ナビゲーションヘッダー、フォーム全体、データテーブルなどです。オーガニズムごとに機能領域を 1 つ持たせます。
-
テンプレート: オーガニズムを配置して完全なビューを構成する、ページレベルのレイアウトです。ダッシュボードテンプレート、一覧・詳細テンプレートなどです。テンプレートでは、特定のデータではなく構造とコンテンツのスロットを定義します。
例:
Atom: Button, Input, Label, ErrorMessage
Molecule: FormField (Label + Input + ErrorMessage)
Organism: LoginForm (FormField + FormField + Button)
Template: AuthPage (Header + LoginForm + Footer)
推奨事項:
- 新しい UI を構築するときは、アトムから始める
- 表示するデータではなく、コンポーネントが何であるかに基づいて名前を付ける
- アトムは 50 行未満、モレキュールは 100 行未満に保つ
禁止事項:
- 生のマークアップから直接オーガニズムを構築しないでください。まずアトムを抽出します
- システム内のアトムを組み合わせていないモレキュールを作成しないでください
- オーガニズムが存在する前にテンプレートへ進まないでください
コンポーネントをプレゼンテーショナルに保つ
コンポーネントは UI を描画します。データは props として受け取ります。データの取得やビジネスロジックの管理、アプリケーションの状態の保持は行いません。
- すべてのデータを props または同等の手段で渡します
- ユーザー操作のイベントを発行し、副作用は処理しません
- データコンテナーとプレゼンテーショナルコンポーネントを分離します
例:
Presentational (good):
UserCard({ name, email, avatar }) -> renders UI
Container (separate):
UserCardContainer() -> fetches data, passes to UserCard
禁止事項:
- アトム、モレキュール、オーガニズム内に API 呼び出しを記述しないでください
- コンポーネントを特定のデータソースに結び付けないでください
- 同じコンポーネント内で描画ロジックとビジネスロジックを混在させないでください
すべての視覚プロパティにデザイントークンを使用する
色、余白、タイポグラフィ、影、角の丸みなど、あらゆるデザイン上の決定を名前付きトークンとして抽出します。コンポーネントは生の値ではなく、必ずトークンを参照します。
- 新しいデザインシステムでは、最初の手順としてトークンを定義します
- コンポーネント内のすべての色、余白の値、フォントサイズは、トークンに由来する必要があります
- トークンを変更すると、そのトークンを参照するすべてのコンポーネントが更新されます
例:
/* Tokens */
--color-primary: #0066cc;
--spacing-sm: 8px;
--spacing-md: 16px;
/* Component uses tokens, not values */
.button { background: var(--color-primary); padding: var(--spacing-sm); }
禁止事項:
- コンポーネント内に
#0066ccや8pxをハードコードしないでください - 1 つのコンポーネント専用のトークン名を作成しないでください
- 使用されないトークンを定義しないでください(トークンは必要とされるものでなければなりません)
継承ではなく、組み合わせる
より複雑なコンポーネントは、よりシンプルなコンポーネントをネストして構築します。クラス継承や、深い props 転送チェーンでベースコンポーネントを拡張しないでください。
- レイアウトを組み立てるために children またはスロットを渡します
- コンポーネントツリーはフラットに保ち、深いネストより兄弟要素を優先します
- バリアントが必要な場合は、既存のモレキュールにフラグを追加するのではなく、アトムから新しいモレキュールを組み立てます
推奨事項:
IconButton = Icon + Button(コンポジション)Card > CardHeader + CardBody(スロット)
禁止事項:
FancyButton extends Button(継承)- 15 個のバリアント用 props を持つ単一の Button コンポーネント
適用に関する注記
すべてのモードで推奨されます。コンポーネント階層とトークンの規律は、開発者自身で徹底してください。
厳守事項:
- トークンのみを参照し、コンポーネントで生の値は使用しないでください:[RP]
制約
- 「レベルを飛ばさない」:実際には分子(複数の視覚要素で構成されるもの)であるアトムは、「アトム」と名付けてもレベルを飛ばしています。分類は、コンポーネントがどのディレクトリにあるかではなく、コンポーネントが何であるかに基づきます。「アトム」にレイアウトロジックを持つ内部要素が3つあるなら、それは分子です。
- 「生の値を使わない」:すべての固有値にトークンを定義しても、そのトークンを再利用しないのでは意味がありません。トークンは再利用と一貫性のために存在します。あるトークンを一度しか使わない場合は、ほかのコンポーネントと値を共有すべきかを検討してください。共有すべきなら、そのトークンは適切です。そうでなければ、より汎用的なトークンから値を取得するべきでしょう(例:
card-header-padding-topではなくspacing-mdを使う)。 - プレゼンテーション層の境界:プレゼンテーションとは、データを props で受け取り、コールバックでイベントを出力することです。表示用のデータのフィルタリングはプレゼンテーションに含まれます(ビューに関する処理です)。データの取得、状態の変更、API の呼び出しはプレゼンテーションに含まれません。判断基準は、そのコンポーネントがモックの props を使った Storybook のストーリーで同じようにレンダリングできるかどうかです。実行中のバックエンドが必要なら、プレゼンテーションではありません。
検証
このスキルに沿って作業した後、次の点を確認してください。
- すべての UI 要素がアトムにたどり着く(オーガニズムやテンプレートに生のマークアップがない)
- デザイントークンが定義され、コンポーネントがそれらを参照している(ハードコードされた値がない)
- 各コンポーネントが、そのレベルに適した単一の責務を担っている
- コンポーネントがプレゼンテーションに徹している(データを受け取り、イベントを出力する)
- 階層が文書化されているか、ディレクトリ構造から明確にわかる
いずれかの基準を満たしていない場合は、作業を進める前に該当するプラクティスを見直してください。
依存関係
このスキルは単独で動作します。ワークフローを強化するため、次の要素と連携できます。
- design-system: デザインシステムの仕様には、このスキルをコードで実装するためのトークン定義、コンポーネントカタログ、階層が含まれます。
- domain-modeling: ドメインのリードモデルにより、コンポーネントが props として受け取るデータを定義します。
- tdd: 各レベルでコンポーネントを個別にテストします(アトムのテスト、分子のテスト、オーガニズムのテスト)。
- event-modeling: イベントモデリングのセッションで作成したワイヤーフレームから、必要なコンポーネントを特定します。
依存関係が見つからない場合は、次のコマンドでインストールしてください。
npx skills add jwilger/agent-skills --skill tdd