自作のデザインシステム
@gunjo/ui(群青/gunjo.jp(gunjo.jp を新しいタブで開く)) を、群青を一度も見たことのない 予備知識ゼロのAI に170画面組ませてきた連載のまとめ第2弾。「そのコンポーネントを作るべきか?」の判断根拠は、実は3段階の強さに分かれます。
デザインシステム設計者の一番難しい判断
「そのコンポーネント、本当に作るべきか?」
デザインシステムを持つ人が毎週向き合う質問です。作りすぎると、種類が増えて使う人が迷子になり、作らなさすぎると、手組みが増えて一貫性が崩れます。ちょうど良いラインを探すのが仕事の半分です。
170画面のコールドテストを回してきて分かったのは、「作るべき理由には強さの段階がある」ということでした。
3段の階段
「そのコンポーネントを作るべきか?」の判断根拠は、弱・中・強の3段の強さに分かれます。弱から強に進むほど「拡張では済まない=作るしかない」が確実になります。
| 段 | 判断根拠 | 何をするか |
|---|---|---|
| 弱 | コンポーネントが無い(手組みされた) | 3回確認まで待つ |
| 中 | 対応表が誤誘導する | 対応表の再整理で塞げることが多い |
| 強 | 既存コンポーネントではHTML構造上つくれない | 新設一択(拡張では原理的に無理) |
弱:コンポーネントが無い(手組みされた)
「あるべきコンポーネントが無い」。予備知識ゼロのAIが正直に「これは手組みしました」と報告します。1回だけだと、その画面固有かもしれません。だから弱い根拠です。
そのまま作りに走ると、次の5画面で誰も使わないコンポーネントが生まれます。群青のルールは「3回確認(3つの別々の画面で独立に手組みされる)まで待つ」。1回目は課題として記録、2回目は対応表の調整、3回目で初めて作ります。同じ「足りないコンポーネント」が3回顔を出すまで待つのは、形が安定するのを見届けるためです。
中:対応表が間違ったコンポーネントを勧める(誤誘導)
「あるはずと思って使ったら詰まった」。予備知識ゼロのAIが「対応表の誘導どおりXを使ったが、実際はYの形が必要でした」と書きます。これは弱よりずっと強い根拠です。
なぜか?「足りないコンポーネント」(弱い根拠)は「無いから手組みに向かう」で使う人を止めるだけですが、「誤誘導」(中)は「動くコンポーネントと思って配線 → 期待どおり動かない」で使う人を成功と勘違いさせるからです。発見が遅れる分、コストが重い。
例:Rating(星表示)は role="img" の表示専用なのに、対応表が「5段階評価」で誘導していました。予備知識ゼロのAIは onChange を配線し、テストで動かないことに気づくまで詰まりました。これは「無い」より「すり替わっている」方が危険な典型例です。
誤誘導の6パターンの詳細は「『ユースケース別の対応表』の落とし穴」で。
強:既存のコンポーネントではHTML構造上つくれない
階段の最上段。「既存のコンポーネントを拡張すれば良いのでは?」という反論が、物理的に成り立たないケースです。使う人がどう頑張っても組めない、作るしかない根拠です。
170画面で最も鮮やかにこの根拠が立ったのが、書類ダウンロード行(DocumentRow) でした。
実演:DocumentRow が ListCard を拡張しても作れなかった理由
背景:書類ダウンロードの行(給与明細・請求書・帳票・添付ファイルなど)は、次の3つの独立したタップ対象が必要です。
- 先頭の選択チェックボックス(複数選択で一括操作)
- ファイル名のタップ面(プレビューを開く)
- 末尾のダウンロードボタン(ダウンロードを直接叩く)
「ListCard を使えばいいのでは?」と多くの人が思います。実際、ListCard は先頭コントロール+タイトル+メタ+末尾スロットを持っていて、見た目はほぼ合う。
でも決定的に不可能な理由がひとつあります。
ListCard.onSelect は「カード全体を1つのボタン」にする
ListCard.onSelect は行全体を押せるようにする設計で、カード全体が <button> 要素(または role="button" のトグル)としてレンダリングされます。1つの押下対象を提供するコンポーネントとして、意味的に完結しています。
そこに独立したダウンロードボタンを入れ子にしようとすると、こうなります。
- ボタンの中にボタン=不正なHTML(HTML5仕様は
<button>の子孫に操作可能な要素を禁止している) - フォーカス順が壊れる(外側のボタンと内側のボタンで、Tabの期待動作が破綻する)
- スクリーンリーダーの読み上げが二重になる(内側ボタンのラベルが外側のラベルに混じる)
これは「ListCard を拡張すれば良い」では済みません。「拡張」の余地が、HTML仕様のレベルで潰れているからです。
タップして拡大表示クリックして拡大表示
#168帳票ダウンロード・#169月次レポートダウンロード・#171 HR書類ダウンロード の3画面で、予備知識ゼロのAIが独立に「ListCard は使えなかった、<div> で組んだ」と書きました。3回確認に到達して DocumentRow を新設。行は <div> で、内側に3つの独立したタップ対象を並べる設計です。ListCard の「1ボタン」設計とは根本的に両立しません。
「拡張」と「新設」の判断基準
3段の階段が定まると、「拡張で足りるか、新設が必要か」の判断が機械的になります。
- 弱(足りないコンポーネント) → 拡張で足りることが多い。既存コンポーネントのPropsを増やす、variantを追加する
- 中(誤誘導) → 対応表の再整理で塞げることが多い。コンポーネントを作らずに済むことが多い
- 強(HTML構造上つくれない) → 拡張では原理的に不可能なので、新設一択
例えば SegmentedControl は「弱(足りないコンポーネント)」で、既存の ToggleGroup を w-full justify-stretch [&>*]:flex-1 で全幅に強制配置するvariantとして実装できました。DocumentRow は「強(つくれない)」で、別コンポーネントにせざるを得ませんでした。同じ3回確認でも、階段のどこにいるかで拡張か新設かが決まります。
なぜ予備知識ゼロのAIがこの判断を助けるのか
面白いのは、この段の判定を、予備知識ゼロのAI自身ができることです。
- 「あるはずのコンポーネントが無い」→ 弱
- 「対応表を信じたら使い方が違った」→ 中
- 「既存コンポーネントではHTML構造上つくれない」→ 強
予備知識ゼロのAIは「動くコンポーネントと思って配線したら無反応だった」を具体的に言語化します(バグ報告として)。そこに、<button> の子孫に操作可能な要素は入れられない、というHTML仕様の知識が乗ると、「これは強の根拠だ」と自ら結論できるのです。
#171の振り返りで、予備知識ゼロのAIは次のように書きました。
ListCard.onSelectはカード全体を1つのボタンにするので、独立したダウンロードボタンを入れると、ボタンの中にボタンで不正なHTMLになる。だからListCardは構造的にこの行を持てない。ListCardを拡張すれば良い、では済まない。行は<div>で、内部に独立したボタン群を持つDocumentRowが必要。
この判断が立った瞬間、作るかどうかは迷いなく決まりました。「HTML構造上つくれない」という言葉が、最も反論の余地ない「作る理由」です。
まとめ
- 「そのコンポーネントを作るべきか?」の判断根拠は 3段の強さに分かれる
- 弱:コンポーネントが無い(手組みされた)→ 3回確認まで待つ
- 中:対応表が誤誘導する → 対応表の再整理で塞げることが多い
- 強:既存コンポーネントではHTML構造上つくれない → 新設一択、拡張では原理的に無理
DocumentRowを作ったのは「強」の根拠が立った瞬間だった- 予備知識ゼロのAIは「強」の根拠を言語化できる(HTML仕様上つくれない、という具体で)
使う人に「何を作ったか」だけでなく「なぜ作ったか」を言えるデザインシステムは、次の判断でも迷わないと思います。170画面で見えた、群青の一番わかりやすい設計軸でした。
関連
- 『ユースケース別の対応表』の落とし穴
- 作ってから再発見までの距離が縮む — まとめ連載の続き
- /cold-tests/why(考え方のページ)(gunjo.jp のコールドテストの記録を新しいタブで開く)
- /cold-tests/categories/accounting(会計・給与の扉ページ)(gunjo.jp のコールドテストの記録を新しいタブで開く) —
DocumentRowを含む - 総集編(Zenn)(Zenn を新しいタブで開く) — 170画面で見えた5つの法則
この記事はZennにも掲載しています。Zenn版(Zenn を新しいタブで開く)
この記事のもとになった記録は、本にまとめました
『あなたがAIにUIを作らせると、何が起きるか』
予備知識ゼロのAIに、実在する業種の業務UIを175枚作らせ続けた記録です。何が組めて、何が組めなかったか。全175回の採点と、生まれた26コンポーネントの年表を載せています。
- Zenn版(Zenn を新しいタブで開く)(序章と第7章は無料で読めます)
- Amazon Kindle版
この連載は、作者がAI(Claude)と協働で制作しています。実験・検証の設計、判断、公開前の事実確認は人間が行い、実作業と下書き執筆はAIが担っています。