ui-component-patterns について
再利用可能な UI コンポーネントの範囲や構成を判断する、フロントエンドチーム向けのスキルです。要点を絞った設計ブリーフを作成し、隣接する課題を他のスキルに振り分けます。
主な機能
- 01再利用コンポーネントの課題分類
- 02範囲を絞った設計パケットの選択
- 03共有範囲とローカル範囲の整理
- 04関連するフロントエンド課題の振り分け
活用シーン
- 01重複するボタンやダイアログの整理
- 02拡大したコンポーネント API のレビュー
- 03プリミティブとラッパーの選択
- 04コンポーネント例と検証方法の定義
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill ui-component-patternsインストール後、Claude Code で/ui-component-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
SKILL.toonevals/evals.jsonreferences/component-api-checklist.mdhandoff-boundaries.mdintake-packets-and-route-outs.md詳細
UI コンポーネントパターン
再利用可能なコンポーネントの課題を分類し、中心となるコンポーネントパケットを1つ選び、React パターンを大量に列挙するのではなく、簡潔なコンポーネントアーキテクチャの概要を残す場合に、このスキルを使用します。
考えられるあらゆるコンポーネントパターンを網羅することが目的ではありません。 目的は次のとおりです。
- まず、再利用可能なコンポーネントに関する課題を特定する
- 範囲を限定したパケットを1つ選ぶ
- 共有とローカル、および親とコンポーネントの所有権を明確にする
- 代替ルートのコンポジションを、より広範なシステムやアクセシビリティの作業と切り分ける
- 隣接するフロントエンドの課題を適切な担当先に振り分ける
まず、次の補足ドキュメントを読んでください。
- references/intake-packets-and-route-outs.md
- references/component-api-checklist.md
- references/handoff-boundaries.md
このスキルを使用する場合
- チームで似たようなボタン、カード、ダイアログ、フィールドラッパー、ナビゲーションパターンが増えすぎており、共有プリミティブまたはコンポーネントファミリーの境界を定める必要がある場合
- リクエストにバリアント、スロット、制御ありと制御なしの動作、ラッパー、ドキュメントへの期待が混在しており、実装前に振り分けが必要な場合
- 何かをプロダクト固有のままにするか、共有プリミティブにするか、プリミティブとラッパーに分けるかを判断する必要がある場合
- コンポーネント API に拡張用の抜け道が増えており、誠実な1つのパケットに整理する必要がある場合
- 難しい点が純粋なスタイリングではなく、代替ルートのコンポジション(
buttonとa/ルーターのLink、スロット化した子、カスタムラッパー)にある場合 - Storybook/サンプルはあるものの、状態、使用ルール、エッジケースに関するドキュメント/検証パケットがまだ不明確な場合
このスキルを使用しない場合
- 主な作業がトークンのガバナンス、ビジュアル言語のルール、プリミティブの命名方針、またはプロダクト横断のシステム方針である場合 →
design-system - 主な作業がキーボード/フォーカスの動作、セマンティクス、ラベル、アナウンス、コントラスト、または手動でのアクセシビリティ対応である場合 →
web-accessibility - 主な作業がビューポート/コンテナーへの適応、ブレークポイント戦略、リフロー、またはレスポンシブメディアである場合 →
responsive-design - 主な作業が、より広範なアプリ/ワークフローの状態の所有権、サーバー/クライアント境界、または画面間の状態連携である場合 →
state-management - 主な作業が再レンダリングの頻発、ハイドレーション、ルートのパフォーマンス、またはバンドル/ランタイムの動作である場合 →
react-best-practices - 再利用可能なコンポーネントの境界がすでに決まっており、実際の作業がその実装だけである場合。その場合はアーキテクチャの判断をやり直さず、直接実装してください
手順
ステップ 1:プロパティの名前を決める前に、再利用可能なコンポーネントの課題を整理する
まず、最小限の受付パケットをまとめます。
component_intake:
surface: button-action | form-field | dialog-overlay | nav-menu | card-list-item | table-toolbar | mixed | unknown
workflow_type: new-primitive | duplicate-cleanup | api-review | wrapper-split | docs-verification | unknown
primary_packet: primitive-boundary | slot-anatomy | controlled-ownership | alternate-root-composition | docs-verification | mixed | unknown
ownership_pressure: shared-vs-local | parent-state | wrapper-proliferation | type-safety | docs-drift | mixed | unknown
signal_source: repeated-components | bug-report | code-review | storybook-gap | design-review | migration | mixed | unknown
confidence: high | medium | low
ルール:「プロパティを追加する」ことから始めてはいけません。まず、再利用可能なコンポーネントに関する課題を分類してください。
ステップ 2:中心となるコンポーネントパケットを1つだけ選ぶ
references/intake-packets-and-route-outs.md のルーターを使用してください。
中心となるパケット:
primitive-boundaryslot-anatomycontrolled-ownershipalternate-root-compositiondocs-verification
現在の判断を解決するパケットを選びます。それ以外は、同等の共同担当ではなく、フォローアップとして列挙してください。
ステップ 3:不変条件を明確にする
重要な回答では、次のルールを必ず守ってください。
- 共有コンポーネントは、1つの画面向けにローカルなフレームワークを作るのではなく、繰り返し発生する作業を解決するものです
- プロダクト固有の文言、分析、ワークフロールール、レイアウトの癖は、通常プリミティブではなくラッパーに含めます
- バリアントは、画面固有の例外ではなく、安定した意味(
tone、size、density、state)を表すものにします - スロット/サブコンポーネントは、構造化された柔軟性を実現するために使います。混乱した API を隠すために使ってはいけません
- 制御ありと制御なしの両方の動作を提供する場合は、その契約を明示し、一貫性を保つ必要があります
- 代替ルートのコンポジションはセマンティクスとアクセシビリティに関する責任を変えるため、その点を明確にします
- Storybook/サンプルは根拠を示す場であり、コンポーネントの境界が適切であることの証明ではありません
ステップ 4:コンポーネントパケットを作成する
次の構造を返します。
# Component Architecture Packet
## Scope
- Surface:
- Workflow type:
- Primary packet:
- Confidence: high | medium | low
## Current signal
- Main symptom:
- Ownership pressure:
- What is already known:
- What still needs direct verification:
## Recommended first slice
1. ...
2. ...
3. ...
## Component decisions
- Shared vs local:
- Primitive / wrapper split:
- Variants or slots:
- Controlled vs uncontrolled:
- Alternate-root or wrapper rules:
## Docs and verification
- Stories/examples required:
- State / variant matrix:
- Accessibility follow-up:
- Responsive follow-up:
## Ownership and route-outs
- Primary owner:
- Adjacent skills / teams:
ステップ 5:膨大なパターン一覧ではなく、パケットを使う
references/intake-packets-and-route-outs.md からパケットを取得します。
パケットのルール:
primitive-boundary→ 共有スコープとローカルスコープ、プリミティブとラッパーの分割、共有 API の対象外とするものを明確にしますslot-anatomy→ 再利用可能な構造におけるサブコンポーネント/スロット、バリアントの境界、コンポジションのルール、アナトミーの要件を定義しますcontrolled-ownership→ 親の状態、ワークフローの状態、コンポーネント内のデフォルトのうち、どれがライフサイクルを所有するかを判断しますalternate-root-composition→ プリミティブを別の要素に合成する必要がある場合に、asChild/component/ラッパーのルート動作、プロパティのスプレッド、参照、セマンティクス上の制約に対処しますdocs-verification→ Storybook/サンプル、状態マトリクス、避けるべき使い方の注意点、コンポーネントファミリーに対する最小限かつ信頼できる検証範囲を定義します
ステップ 6:仕組みの選択と所有権の選択を分ける
本格的な回答では、次のように分けます。
- 仕組み — バリアント、スロット、サブコンポーネント、制御プロパティ、ポリモーフィックなルート、ラッパーの分割、ドキュメントのマトリクス
- 所有権 —
ui-component-patterns、design-system、web-accessibility、responsive-design、state-management、またはreact-best-practices
スクリーンショット、Storybook との不整合、コード差分から始まる依頼では、そうした成果物は完成したコンポーネントの判断ではなく、手がかりであることを明確に伝えます。
ステップ 7:関連作業への振り分けを明確にする
問題が境界をまたぐ場合は、次の振り分け先を使います。
- トークンのガバナンス、プリミティブの命名、コントリビューションポリシー、またはプロダクト横断のコンポーネント標準 →
design-system - キーボード/フォーカスの改善、ラベル/アナウンスの問題、ARIA、コントラスト、動きの軽減、または手動の a11y 検証 →
web-accessibility - ビューポート/コンテナーへの適応、リフロー、レスポンシブメディア、または高密度データのレイアウト戦略 →
responsive-design - アプリ/ワークフローの状態の所有権、サーバー/クライアント状態の境界、URL/フォーム/グローバルストアの判断 →
state-management - 再レンダーの頻発、ハイドレーション、バンドル/ランタイムのパフォーマンス、またはルートレベルのパフォーマンス動作 →
react-best-practices
複数の領域にまたがる依頼では、再利用可能なコンポーネントパケットには ui-component-patterns を適用し、振り分け先の追加作業を明示します。
ステップ 8:過度に汎用化されたプロパティより、誠実な境界を優先する
コンポーネントに真偽値、回避策、プロダクト固有のルールが増え続ける場合:
- API をプリミティブとラッパーに分割すべきか確認します。
- 意図せず増えたバリアントを、より小さな意味的なセットにまとめます。
- レイアウトまたはワークフロー固有の動作をプリミティブの外に移します。
- スキルの範囲を広げるのではなく、システム全体に及ぶ追加作業や改善負荷の大きい追加作業を外部に振り分けます。
例
例 1:ボタンファミリーのばらつき
入力:「ボタンの実装が 5 つあり、皆が独自のプロパティを追加し続けています。」
望ましい出力の方向性:
- 主なパケットとして
primitive-boundaryを選ぶ - 共有アクションプリミティブを 1 つ設け、必要であれば、より範囲を絞ったアイコン/ボタングループのラッパーを用意する
- 無秩序に増えた真偽値を、バリアント/トーン/サイズの小さなセットにまとめる
- 分析機能と画面固有のレイアウトラッパーはプリミティブの外に置く
- トークンの命名は
design-systemに振り分ける
例 2:モーダルの状態に関する混乱
入力:「モーダル自身が状態を管理すべきでしょうか。それとも、常に親のワークフローで制御すべきでしょうか?」
望ましい出力の方向性:
- 主なパケットとして
controlled-ownershipを選ぶ - モーダルを再利用可能な複合パターンとして分類する
- ワークフローの状態、ルーティング、または非同期の送信ロジックが関わる場合は、制御された所有権を推奨する
- 契約が明確なままであれば、非制御の簡易な利用方法も認める
- キーボード/フォーカスの改善に関する詳細は
web-accessibilityに振り分ける
例 3:リンクボタンの合成
入力:「デザインシステムのボタンを、ルーターリンクとしてレンダリングする必要がある場合があります。型やセマンティクスを損なわずに対応するには、どうすればよいですか?」
望ましい出力の方向性:
alternate-root-compositionを主要なパケットとして選択します- プロパティのスプレッド、ref のフォワーディング、セマンティクス/アクセシビリティ上の制約を明示します
- ルートレベルのナビゲーションポリシーやトークンのガバナンスは、プリミティブの判断の対象外とします
- 曖昧な「
asプロパティを追加すればよい」という回答ではなく、範囲を限定したラッパー/ルートの契約を残します
例 4:Storybook の乖離
入力:「コンポーネントは存在しますが、チームごとに使い方が異なり、Storybook にはエッジケースが不足しています。」
望ましい出力の方向性:
docs-verificationを主要なパケットとして選択します- 最小限の状態/バリアントのマトリクスとサンプルセットを定義します
- 望ましくない使い方に関する注意事項とラッパーの要件を追加します
- アクセシビリティのみ、またはレスポンシブ対応のみの追加作業は、別のパケットに振り分けます
ベストプラクティス
- ローカルなフレームワークを新たに作ることなく、繰り返しの作業を減らせる最小の再利用可能なプリミティブを優先します。
- パケットの選択を明示します。1 つのコンポーネントの判断に、ガバナンス、修正対応、レスポンシブ戦略、ランタイム調整を暗黙に含めないでください。
- スロットとサブコンポーネントは、責任の所在に関する判断を回避する手段ではなく、構造化された API ツールとして扱います。
- 制御あり/制御なしの動作は、偶然できた中途半端な状態のハイブリッドではなく、明示的な契約にします。
- 別のルートとの合成では、ref、プロパティのスプレッド、セマンティクスに関する仕様を明確にします。
- Storybook/サンプルを根拠の一部として活用しつつ、ドキュメント/検証のパケットについても記述します。
- 利用側が使うために回避策やアプリ固有のラッパーを繰り返し必要とする場合は、抽象化を見直します。