この技術でできること
- デザインシステムのパーツを 「実装可能・再利用可能」な単位で設計 できる
- 「似ているが違うUI」を、バリエーションではなく 合成で解決 できる
- エンジニアと コンポーネントのAPI(Props) について議論できる
例 : カレンダーの中の日付セルを「1つの塊」としてデザインするのではなく、「日付テキスト」「イベントドット」「背景ステート」の組み合わせとして設計することで、画面サイズが変わっても破綻しない実装が可能になる。
なぜ難しいか
デザイナーとエンジニアで 「分割の基準」が違う から。
デザイナーは「見た目のまとまり(レイヤー)」でコンポーネントを分けるが、エンジニアは「データと振る舞いの責務」で分ける。同じUIを見ても頭にある境界線が一致していないため、「デザイン通りに作ると使い回せない」「エンジニアに切り刻まれて見た目の管理が破綻する」といった問題が起きる。
コンポーネント設計のプロセス
責務の分離(単一責任)
どんな場面 : 巨大なカードUIやヘッダーをどこで分割するか決める時。
- UI分割の基準 : 「1つの独立した情報を表示しているか」「別のデータを流し込んでも成立するか」で判断する。
- データの境目 : 「ユーザーのプロフィール情報」と「そのユーザーが書いた記事リスト」は、見た目が隣接していても別のコンポーネントに分ける(データ取得タイミングが違うため)。
コンポーネントの合成(Composition)
どんな場面 : 似ているが中身が少し違うカードが複数ある時。
- バリエーションの限界 :
ArticleCard,ProductCard,UserCardを別々に作るとコードが重複する。 - 合成アプローチ :
<Card>という「枠」のコンポーネントを作り、その中に<CardImage>,<CardBody>をパズルのようにはめ込んで様々なカードを作る。
API(Props)の設計
どんな場面 : ボタンの色やサイズなど、外部から変えられる項目を決める時。
- 意味的命名 :
color="red"(見た目)ではなく、variant="danger"(意味)でPropsを定義する。 - デザイントークンとの連動 : Propsで指定できる値は、デザインシステムのトークン(Primary, Secondary, Small, Medium等)に限定する。
デザイン時の判断ポイント(Before/After)
パターン: propsの爆発を防ぐ
Before(現実の悪い例) : 汎用的なボタンを作ろうとして、Figmaでもコードでもプロパティを増やしすぎる。
<Button
bgColor="#FF0000"
textColor="#FFF"
icon="arrow"
iconPosition="right"
hasShadow={true}
borderRadius="8px"
>
→ 柔軟すぎるため、画面ごとに微妙に違うボタンが作られ、デザインシステムの意味がなくなる。
After(現実的な整理) : デザインシステムでバリエーション(種類)として定義し、それ以外は許容しない。
<Button variant="primary" size="large" iconRight="arrow">
→ デザイナーから見ても「この3つのバリエーションから選ぶ」という制約になり、一貫性が保たれる。
なぜこの制約で運用できるか : 例外的な見た目が必要な場合は、既存コンポーネントを無理に拡張するのではなく、別の一回限りの要素として作るかデザイン自体を見直すというルールにしているため。
アンチパターンと衝突(デザイナー × エンジニア)
❌ 「Figmaのコンポーネント構造=コードの構造」だという思い込み
デザイナーの視点 : Figma上で論理的に階層を作った。この通りに実装してほしいし、ツリー構造も揃えてほしい。(品質=完全な同期) エンジニアの視点 : Figmaのレイヤー構造は見た目の管理。コードはパフォーマンスやデータ通信の最適化のために構造を変える必要がある。(品質=実行効率と保守性)
なぜ衝突するか(品質の定義差) : デザイナーは「管理モデルの同期」を品質と考えるが、エンジニアは「データフローの適切さ」を優先する。
どう合意するか :
- 1:1で対応させる「UIコンポーネント(ボタン等)」と、対応しない「機能コンポーネント(データ取得等)」があることを理解する。
- デザイナーは「これはどうデータが入ってくるか」をセットでエンジニアに伝える。
❌ 共通化すべきでないものを共通化する(DRYの誤用)
デザイナーの視点 : ログイン画面の入力枠も、検索画面の入力枠も見た目は同じ。共通の <Input> にすべき。(品質=UIの統一)
エンジニアの視点 : 見た目は同じでも、バリデーションルールや送信時の挙動が全く違う。共通化すると後で破綻する。(品質=変更時の安全性)
なぜ衝突するか(品質の定義差) : 「見た目の類似」と「ドメイン(ビジネス上の意味)の類似」を混同している。
どう合意するか :
- 見た目だけの枠(UI)コンポーネントと、それを使う機能部分を明確に分ける。
- 「本当に同じ理由で変更が入るか?」を判断基準にする。片方だけ仕様変更されるなら別々に作る。
実践チェックリスト
最低ライン(Must)
[ ] Figmaで定義したProps(バリアント)が、デザインシステムの意味と合致している [ ] 「似ているが別の機能」を持つUIを、無理に1つのコンポーネントにまとめていない [ ] ボタンなど基本要素は、サイズや色を自由に指定させず選択式にしている
理想ライン(Better)
[ ] デザイン段階で「データがどこから来るか」を想定してパーツを分割している [ ] エンジニアと「枠(レイアウト)」と「中身(コンテンツ)」のコンポーネント分割について議論している [ ] 画面ごとに作られた不要な(再利用性のない)コンポーネントを棚卸しする機会がある
関連技術
前提となる技術
セットで使う技術
- 状態管理 — コンポーネント内のデータ保持
次に学ぶ技術
- 状態管理 — コンポーネント間でどうデータを渡すか
まとめ
- この技術の本質 : 画面の断片を「再利用可能な責任の単位」として切り出し、組み合わせる技術
- UXへの影響 : 使い回し可能な設計がシステムの一貫性を担保し、ユーザーの迷いをなくす
- 実務での判断軸 : 「ここに変更が入った時、他の画面も一緒に変わっていいか?」
- 次に学ぶべき技術 : 状態管理(細かく分けたコンポーネント間で、どうデータをやり取りするか)
目的別のおすすめ :
- どうデータを扱うか学ぶなら → 状態管理
- より大きなシステム構造を学ぶなら → アーキテクチャパターン