既存のDesign Systemを壊さずにコントリビュートする方法
火曜日のスタンドアップで、こういう話は終わりを迎えます。Figmaで3日間かけてきれいな日付範囲ピッカーのバリアントを作り上げたと思ったら、DSリードが共有リンクをちらっと見て、背もたれにもたれながら言います:「そのコンポーネント、もうありますよ」。頭の中でそろばんを弾きます。3日間の作業が無駄になるか、急いで作った場当たり的なバリアントがリリースされて誰も管理しなくなり、8か月後に別のデザイナーが「4回目の同じものを作る」か。
どちらの結果も良くありません。ただ、その差はプロセスの問題であってスキルの問題ではありません。ICデザイナーが2週間で成熟したシステムにコントリビュートするのを見てきた一方で、シニアの人物がボタンのバリアントを1人のゲートキーパーに通そうとして6か月を費やすのも見てきました。違いはほとんどの場合、成果物の品質ではありませんでした。ほぼ常にコントリビューションモデルの問題でした。
これが、そのモデルの実践版です。
なぜ今これが重要なのか
分散したシステムは、遅いシステムよりコストがかかります。この問題で悩むチームすべてに見られる2つの失敗パターンがあります。見た目は正反対ですが、同じ結果をもたらします。
1つ目はゲートキープされたシステムです。DSチームがすべてを管理します。コントリビューションには3つの承認と四半期ロードマップへの掲載が必要です。ICは2回目の却下の後から試みをやめます。ライブラリは硬直します。新しいパターンはシステムの外で構築されます。速いからです。こうしてあなたには、実質的に美術館と化したdesign systemができ上がります。
2つ目は制限のない自由参加です。誰でも何でも公開できます。6か月後には、製品スクワッドごとに独自のドロップダウンコンポーネントがあり、微妙に違う3種類の「プライマリ」ボタンがあり、「TEMP, 使用禁止」と書かれたFigmaページを全員が使っています。これが分散税のコストです。
私が監査する典型的な製品チームは、2年目までに「同じ」ボタンの3〜7バージョンを持っています。誰もそれを望んでいたわけではありません。コントリビューションフローが厳しすぎるか緩すぎるかのどちらかで、最も抵抗が少ない道はローカルで作ってシステムに戻さないことだったからです。
以下のモデルは中間の道です。コントリビューションは政治的なスキルではなく職人的なスキルであり、クリーンなDS作業をリリースするICの方が、プライベートコンポーネントライブラリを構築するICより早く影響力を積み上げるという前提に立っています。
DSを使うべきか、新しいコンポーネントを作るべきか
「新しいコンポーネントが必要だ」という議論のほとんどは、「80/20テスト」を実施した瞬間に終わります。問いは2つです。
- 既存のコンポーネントにプロパティやバリアントを加えることで、このケースの80%をカバーできるか?
- これを追加したとき、6か月以内に少なくとも20%のチームがそれを使うか?
1番の答えが「はい」なら、新しいコンポーネントは不要です。バリアントかプロパティが必要なだけで、それはより小さく、速く、コストの低いコントリビューションです。1番が「いいえ」で2番も「いいえ」なら、それは場当たり的なものです。ローカルに留め、ライブラリを汚染しないでください。
新しいコンポーネントが正当化されるのは、両方の答えが適切な方向を向いているときだけです。既存のキットでそのケースをカバーできず、かつ複数のチームが再利用する見込みがある場合です。
最もよく見かける罠は、私が**「あと少しで合う」の罠**と呼んでいるものです。デザイナーが70%合致するコンポーネントを見つけます。インスタンスをデタッチし、パディングを調整し、トークンを入れ替え、既存のものを「ベースにした」として出荷します。6か月後には7つの目に見えない方向に乖離し、design systemのオーナーにはそれが起きたという記録がありません。「あと少しで合う」は、ゼロから作ることより始末が悪いです。再利用しているふりをしているからです。
シンプルな判断ツリー(優先順位順):
- 既存コンポーネント、変更なし → そのまま使う。
- 既存コンポーネント、新しいプロパティや状態が必要 → 既存のものへのバリアントを提案する。
- 既存コンポーネントだが基本的な動作が間違っている → フォークではなくリファクタリングを提案する。
- 本当に新しいパターンで複数チームが必要としている → 新しいコンポーネントを提案する。
- 本当に新しいパターンだが自分のチームだけが必要としている → ローカルで構築し、ローカルであることを明記し、90日後に再評価する。
最後の選択肢は問題ありません。ローカルコンポーネントは罪ではありません。ローカルコンポーネントをシステムコンポーネントのように見せかけることが問題です。
コントリビューションフロー:RFC → レビュー → リリース → ドキュメント
追加する価値があると判断したら、フローは4つのステージで構成されます。それぞれに時間の上限があります。通常のコントリビューションであれば全体で2週間以内に完了するはずです。それ以上かかるなら、コンポーネントではなくプロセスに問題があります。
ステージ1、RFC(1〜2日)。 1ページです。課題、提案する解決策、検討した代替案、アクセシビリティのメモ、そしてスケッチ1枚。モックアップ6枚ではありません。私が長年犯してきた失敗は、会話を始める前に精度への投資をしすぎることでした。スケッチ1枚であれば、DSオーナーは3日分のピクセル作業を守らなければならないという状況を作ることなく方向性についてフィードバックを返せます。
RFCはまた、依存関係を明確にする場でもあります。新しいトークン、新しいアイコン、既存コンポーネントに影響する動作など。これを機能させるために新しいカラートークンが必要だと気づいたなら、それはRFCの一部であって、8日目の驚きではありません。
ステージ2、DSオーナーとのレビュー(1〜3日)。 非同期優先、行き詰まれば同期。レビューは承認のパフォーマンスではありません。共同デザインのセッションです。DSオーナーはあなたの障害物ではありません。あなたがリリースしたものを最終的に維持する人物です。命名、プロパティ、エッジケースに関する彼らのフィードバックは、スタイルではなく構造に関するものです。
RFCを持って臨み、3つのことを確認します。これはシステムに属するか、提案された形は既存のパターンと合致するか、エンジニアリング面で見落としていることは何か。可否の判断または修正が必要という回答と、最終PRをレビューするDSサイドの担当者を1名確定して退出します。
ステージ3、フラグの後ろでリリース(3〜5日)。 Figmaで構築し、Storybookで構築し、ReactまたはVueなどのコンポーネントをフィーチャーフラグか公開ライブラリのbetaチャンネルにリリースします。フラグの後ろでリリースすることが重要なのは、本番キットに入る前に1〜2名のアーリーアダプターとAPIの圧力テストができるからです。APIのほとんどの問題はRFCではなく最初の実際の使用時に現れます。
ステージ4、ドキュメントと昇格(1日)。 ストーリーを公開し、使用方法ドキュメントを書き、何かを置き換える場合は廃止予告を記載し、DSチャンネルで「どんなときに使うか」の1段落つきでアナウンスします。次のライブラリリリースでbetaからGAに昇格させます。
どのステージでも上限時間を超えたら、それはサインです。ステージ1が延びるなら問題が明確でない。ステージ2が延びるなら、DSオーナーに構造的な懸念があり、別の修正ではなく本物の会話が必要です。ステージ3が延びるなら、APIが間違っていてパッチを当てようとしています。ステージ4は延びません。省略しているなら、それを本物にする部分を省略しています。
生き残る命名規則
命名はコントリビューションの地味な半分で、ほとんどのコントリビューションが静かに失敗するところです。BigBlueBtnと呼ばれるコンポーネントは皮肉を込めてちょうど1チームだけが使い、そして二度と使われません。Button/Primary/Largeと呼ばれるコンポーネントは採用されます。名前が何であるか、どこに位置するか、残りとどう関係するかを伝えているからです。
時間の経過に耐える命名階層はトークン → コンポーネント → バリアント → 状態です。
- トークン:
color/primary/600 - コンポーネント:
Button - バリアント:
Primary、Secondary、Ghost - サイズ:
Small、Medium、Large - 状態:
Default、Hover、Disabled、Loading
上から下に読むと、Button/Primary/Large/Hoverは曖昧さがなく、並べ替えができ、FigmaのコンポーネントパネルとStorybookのナビゲーションでの表示方法と一致します。
体に染み込ませたい3つのルール:
- 固有名詞は使わない。
BobsButton、Q3Modal、MarketingHeroは不可。名前は依頼者ではなく対象物を表す。 - 5文字未満の略語は使わない。
Btnは何も節約せず検索性を損ないます。NotifはNotificationより悪いです。 - スケール上にないサイズ形容詞は使わない。 「大きい」はサイズではありません。
Largeがサイズです。スケールがS/M/Lなら、最初にシステム全体でスケールに追加せずにXLGを導入しないでください。
名前の衝突(特に大きなシステムでは必ず起きます)については、より一般的な名前はより一般的なユースケースに属するというルールがあります。マーケティングがスタイリッシュなヒーローカード用にCardを望み、システムにすでに汎用コンテンツコンテナとしてのCardがある場合、マーケティングのコンポーネントはCard/HeroまたはHeroCardになります。ベース名はベースの動作と共にあります。
アクセシビリティの最低基準:WCAG AAをフロアとして
コンポーネントはアクセシビリティテストとともにリリースされるか、そうでなければリリースされません。これは目標ではありません。WCAG AAは天井ではなくフロアであり、それがフロアである理由はその下にあるものを出荷すると、法的にも倫理的にもユーザーを除外するコンポーネントになるからです。
マージ前にすべてのコンポーネントがクリアしなければならない最低基準:
| チェック項目 | 基準 | テスト箇所 |
|---|---|---|
| 本文テキストのコントラスト | 背景に対して4.5:1以上 | Storybookのa11yアドオン、Figmaのコントラストプラグイン |
| 大きなテキスト(18pt以上または14pt太字)のコントラスト | 3:1以上 | 同上 |
| UI要素・アイコンのコントラスト | 3:1以上 | 同上 |
| キーボードナビゲーション | タブで入退出可能、トラップなし | 手動 + Storybookのplay関数 |
| フォーカスインジケーター | 可視のリング、最小2px、コントラスト比3:1 | 視覚的 + 自動化 |
| スクリーンリーダーラベル | すべてのインタラクティブ要素にアクセシブルな名称 | axe-core、手動によるVoiceOver・NVDAチェック |
| 色の独立性 | 色のみで情報を伝えない | 手動確認、RFCチェックリスト |
| タッチターゲット | モバイルで最小44×44px | 仕様 + モバイルQA |
これらすべてに自動化ツールがあります。CI内のaxe-coreが構造的な問題を検出します。Storybookのa11yアドオンが明らかなコントラストとARIAの問題を検出します。ただし自動化が検出できないこと(そしてICが実際に行う必要があること)は、キーボードトラップのテストです。モーダルオープン、ドロップダウン展開、エラー状態を含むすべての状態をタブキーで確認してください。キーボードトラップは最もよく見られる失敗パターンで、最も簡単にテストできます。
コンポーネントが合格するかわからない場合、レビューに送る前にテストを通してください。DSオーナーがステージ2でコントラスト不合格を指摘することは、あなたが作業をしていなかったと判明することを意味します。アクセシビリティに問題なく届いたコントリビューションは、承認が速くなります。
Figmaライブラリの衛生管理
Figmaは注意を払わないと、コントリビューションが静かに劣化していく場所です。重要なのは2点です。
公開 vs. ローカル。 公開コンポーネントはチームライブラリに存在し、それを参照するすべてのファイルに伝播します。ローカルコンポーネントは作業中のファイルに存在し、どこにも伝播しません。よくある間違いは、プロトタイプ作業にローカルコンポーネントを使い、削除するか昇格させるか忘れることです。6か月後にそのファイルが開かれ、形が正しいからという理由で誰かがローカルのものをコピーします。
ルール:ローカルコンポーネントは2週間以内に公開ライブラリに昇格させるか、削除するかのどちらかです。第3の状態はありません。
デタッチされたインスタンスは問題のサイン。 デザイナーがインスタンスをデタッチするとき、「このコンポーネントが必要だが少し違う形が必要で、システムに対処したくなかった」と言っています。それはシグナルです。バリアントを追加するのが正解の場合もあります。基礎のコンポーネントを修正するのが正解の場合もあります。デザイナーが急いでいただけの場合もあります。しかしすべてのデタッチされたインスタンスはデータであり、月次スウィープでそれを追跡すべきです。
スウィープ自体はメカニカルです:月に一度、Figmaのインスタンス監査(またはInstance Finderのようなプラグイン)を実行し、デタッチされたインスタンスを一覧化し、担当デザイナーと確認します。再アタッチ、バリアントの提案、または削除のいずれかを選択します。30分の作業で3か月間の分散を防ぎます。
コードとデザインの一致(Storybook)
すべてのFigmaコンポーネントにStorybookのストーリーがあるか、そうでなければ本物ではありません。これが壁に貼るルールです。
Storybookはデザインとコードが同一の成果物として共存する唯一の場所です。Figmaはコンポーネントがどう見えるべきかを示します。Storybookは実際にどうであるかを示します。両者が乖離するとき(必ず乖離します)、Storybookが正解です。ユーザーが目にするのはそちらだからです。
コントリビュートされたコンポーネントの本物のStorybookストーリーには次が必要です:
- すべてのバリアントのレンダリング(
Primary、Secondary、Ghostなど) - すべての状態のレンダリング(
Default、Hover、Focus、Disabled、Loading、Error) - レビュアーがプロパティをライブで切り替えられるコントロールパネル
- キーボードインタラクションを実行するplay関数
- 違反なしのa11yアドオンレポート
- コミット済みのビジュアルリグレッションベースライン(Chromatic、Percy、または独自構築)
CIのビジュアルリグレッションがPMより先に乖離を検出します。誰かがButtonコンポーネントを更新してパディングトークンが40のストーリー全体で2px変わると、差分がPRに表示されます。DSオーナーが承認または却下します。本番環境で予期しない破損は起きません。
これがなければ、顧客がTwitterでフォームのずれのスクリーンショットを投稿したときに乖離を知ることになります。
廃止のサイクル
リリースしたものはいずれ正解でなくなります。廃止の規律が、美術館状態のシステムという問題を避ける方法です。
推奨するサイクル:
- 四半期ごとのレビュー。 四半期ごとに、DSチームと2〜3名のICデザイナーがライブラリを確認し、利用頻度が低い(コードベース全体で5インスタンス未満)、新しいバリアントに置き換えられた、またはアクセシビリティや視覚標準と合致しなくなったコンポーネントにフラグを立てます。
- 2リリースの廃止ウィンドウ。 コンポーネントにフラグが立ったら、Storybookで
@deprecatedとマークし、Figmaコンポーネントに廃止バナーを追加し、代替品(または移行パス)をリリースします。削除前に2リリースサイクル(通常2か月)の猶予を与えます。 - コードモッドを提供する。 これはチームが省略する部分です。200か所で使用されているコンポーネントを廃止する場合、「移行してください」は計画ではありません。コードモッド(
<OldButton>を<Button variant="primary">に自動書き換えする小スクリプト)をリリースすれば、移行が数週間ではなく数分で完了します。コードモッドなしでは廃止が無視され、古いコンポーネントが永遠に残ります。
よくある失敗パターン
コントリビューションが失敗する4つの方法(おおよその頻度順):
- 単独でデザインし、完成品を売り込む。 Figmaで3日間費やした後、DSオーナーには30秒の文脈があり、6つのモックアップへの承認を求められます。通りません。スケッチは早い段階で、完成品は後から持参してください。
- 最も近い既存コンポーネントをコピーして「少し調整する」。 「あと少しで合う」の罠です。本物のバリアントにするか、新しいものを作るかのどちらかにしてください。調整されたデタッチをシステムコンポーネントとして出荷しないでください。
- 「開発者がやってくれるから」とStorybookのストーリーをスキップする。 やってくれないか、デザインの意図を知らないため質の低いものを作ります。ストーリーはあなたの仕様です。FigmaコンポーネントがそうであるのとW同じように。書かなければ、開発者の解釈が真実になります。
- DSオーナーを障害物ではなく共著者として扱わない。 これが最大の思考上の間違いです。DSオーナーは今後何が来るか、何が廃止されるか、どのチームが何を必要とするかについて、あなたより多くの文脈を持っています。早い段階で巻き込めばコントリビューションを加速させます。遠ざければ、彼らがあなたの推論を逆算しなければならないため遅くなります。
テンプレートとツール
手元に置いておきたい3つの成果物:
1ページのRFCテンプレート。 課題(最大3文)、提案する解決策(スケッチ1枚 + 箇条書き3点)、検討した代替案(2〜3点、採用しない理由つき)、アクセシビリティメモ、依存関係、影響を受ける関係者。1ページに収まらないなら、コントリビューションのスコープが絞りきれていません。
コンポーネントチェックリスト。 使用トークン、定義済みバリアント、全状態のデザイン完了、アクセシビリティテスト合格、コントロールとplay関数つきのStorybookストーリー公開、使用方法ドキュメント作成、ビジュアルリグレッションベースラインコミット、何かを置き換える場合は廃止予告記載。モニターの横に貼っておきましょう。
廃止予告テンプレート。 廃止対象、代替品、移行ガイドへのリンク、コードモッドコマンド、削除日。DSチャンネルで告知し、Storybookページに追加し、FigmaコンポーネントにバナーをО。
成功の測定
モデルが機能していることは、以下の状況でわかります:
- コントリビューションがRFCから2週間以内に公開ライブラリに収まる。それ以上かかるなら、フローのどこかが壊れています。
- 30日後にあなたのコンポーネントのデタッチされたインスタンスがゼロ。表示されているなら、APIがユースケースをカバーしていません。
- Storybookのストーリーが存在し、play関数があり、アクセシビリティ違反がゼロ。
- 別のチームがあなたに聞かずにコンポーネントを採用する。これが本物のシグナルです。再利用が自然に起きるとき、システムに単に追加しただけでなく、本当にコントリビュートしたことになります。
クリーンなDS作業をリリースするICは、プライベートコンポーネントライブラリを構築するICより早く影響力を積み上げます。クリーンなコントリビューションひとつひとつが次のコントリビューションを速くするからです。自分にとっても、他の誰にとっても。
関連記事

Principal Product Marketing Strategist