design-systems について
プロダクトデザインやフロントエンドチーム向けのデザインシステム実践ガイドです。トークン、コンポーネント、アクセシビリティ、文書化、運用を扱い、複数製品の一貫性と拡張性を支えます。
主な機能
- 01既存 UI の監査とパターン抽出
- 02色・間隔・文字のトークン定義
- 03再利用可能でアクセシブルなコンポーネント
- 04Storybook によるコンポーネント文書化
- 05ビジュアル回帰とアクセシビリティテスト
活用シーン
- 01複数のデジタル製品で共通システムを構築
- 02コンポーネントの状態・バリエーション・利用法を定義
- 03トークンやコンポーネントライブラリの変更を管理
- 04アクセシビリティとビジュアル回帰を検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill design-systemsインストール後、Claude Code で/design-systemsを入力して読み込まれたか確認します。
詳細
デザインシステムのベストプラクティス
デジタルプロダクト全体で、視覚的な一貫性、アクセシビリティ要件への準拠、スケーラブルなコンポーネントアーキテクチャを実現するデザインシステムの作成と維持に関するガイドラインです。
ワークフロー:デザインシステムのセットアップ
- 既存の UI を監査する — プロダクト全体の既存コンポーネント、色、タイポグラフィ、間隔を洗い出し、不整合や再利用可能なパターンを特定します。
- デザイントークンを定義する — プリミティブトークン(色、間隔、タイポグラフィ、シャドウ)を CSS カスタムプロパティまたはトークン形式(Style Dictionary など)で定義し、信頼できる唯一の情報源とします。
- 基盤となるコンポーネントを構築する — デザイントークンを使用するアトミックコンポーネント(Button、Input、Text、Icon)を作成し、TypeScript 型を備えた明確な props API を公開します。
- パターンとレイアウトを組み合わせる — アトミックコンポーネントを組み合わせて、より高次のパターン(フォーム、カード、ナビゲーション)を作成し、使用ガイドラインを文書化します。
- ドキュメントと Storybook をセットアップする — すべてのコンポーネントのバリアント、状態、アクセシビリティ注釈を含むストーリーを Storybook で設定します。継続的に更新されるスタイルガイドとして公開します。
- テストとガバナンスを統合する — ビジュアルリグレッションテスト(Chromatic など)、アクセシビリティの lint(axe-core など)、新しいコンポーネントのための貢献・レビューのプロセスを追加します。
- リリースして改善を重ねる — ライブラリをバージョン管理されたパッケージとして公開し、利用者からフィードバックを集め、アクセシビリティとパフォーマンスの監査を定期的に実施します。
基盤となる要素
カラーシステム
- プライマリ、セカンダリ、アクセントカラーを定義する
- 成功、警告、エラー、情報の状態に対応するセマンティックカラーを含める
- すべての色の組み合わせが WCAG のコントラスト要件を満たすようにする
- 色の使用に関するガイドラインとコンテキストを文書化する
- ライトモードとダークモードのバリアントを用意する
タイポグラフィ
- 一貫した比率で文字サイズのスケールを設定する
- 見出しと本文のフォントファミリーを定義する
- 行の高さと文字間隔の基準を設定する
- フォントウェイトとその使用方法を文書化する
- 画面サイズを問わず読みやすさを確保する
間隔システム
- 一貫した間隔のスケール(4px、8px、16px、24px など)を定義する
- 一般的なパターンのレイアウトプリミティブを作成する
- マージンとパディングの規則を文書化する
- レスポンシブな間隔の動作を確保する
- 保守性のために CSS カスタムプロパティを使用する
アイコンと画像
- アイコンのスタイルとサイズを一貫させる
- アイコングリッドと線幅を定義する
- アイコンの命名規則を文書化する
- ウェブパフォーマンスのためにアセットを最適化する
- 必要に応じて複数の形式(SVG、PNG)を用意する
コンポーネントアーキテクチャ
コンポーネントの構造
- アトミックで再利用可能なコンポーネントを作成する
- 明確なコンポーネント API(props/属性)を定義する
- バリアントと状態を文書化する
- デフォルトでアクセシブルなコンポーネントにする
- 明確な命名規則を定める
コンポーネントの状態
- デフォルト状態
- ホバー状態
- フォーカス状態(キーボードナビゲーション)
- アクティブ/押下状態
- 無効状態
- 読み込み状態
- エラー状態
コンポーネントのバリアント
- サイズのバリアント(小、中、大)
- 色/テーマのバリアント
- レイアウトのバリアント
- コンテキストに応じたバリアント
アクセシビリティ要件
- 最低限、WCAG 2.1 AA ガイドラインに準拠する
- セマンティックな HTML 要素を使用する
- 必要に応じて ARIA ラベルを指定する
- キーボードナビゲーションを確保する
- スクリーンリーダーでテストする
- 色のコントラスト比を維持する
- モーションの低減設定に対応する
ドキュメントの基準
コンポーネントのドキュメント
- 目的とユースケース
- Props/API リファレンス
- コード例
- 推奨事項と禁止事項
- アクセシビリティに関する注意事項
- 関連コンポーネント
パターンのドキュメント
- 使用するタイミング
- 構成要素の内訳
- 動作仕様
- レスポンシブ対応に関する考慮事項
- エッジケース
実装ガイドライン
CSS アーキテクチャ
- トークンには CSS カスタムプロパティを使用する
- 一般的なパターンにはユーティリティクラスを実装する
- BEM または同様の命名規則に従う
- 詳細度を管理可能な状態に保つ
- テーマ設定とカスタマイズに対応する
コンポーネントライブラリ
- 可能な限りフレームワークに依存しないこと
- ツリーシェイク可能なエクスポート
- TypeScript のサポート
- 包括的なテストカバレッジ
- Storybook との統合
ガバナンス
コントリビューションガイドライン
- 新しいコンポーネントの提案方法
- レビューと承認のプロセス
- バージョニング戦略
- 破壊的変更に関するポリシー
- 非推奨化のプロセス
メンテナンス
- 定期的なアクセシビリティ監査
- パフォーマンスのモニタリング
- ブラウザー互換性テスト
- ドキュメントの更新
- コミュニティからのフィードバックの反映
デザイントークン
トークンのカテゴリ
- 色
- タイポグラフィ(フォントサイズ、ウェイト、行の高さ)
- 間隔
- 角丸
- シャドウ
- ブレークポイント
- アニメーションの再生時間
- Z インデックス値
トークンの実装
:root {
/* Colors */
--color-primary-500: #0066cc;
--color-neutral-100: #f5f5f5;
/* Spacing */
--space-1: 4px;
--space-2: 8px;
--space-4: 16px;
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}
例:デザイントークンを使用した React ボタンコンポーネント
import React from "react";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary" | "danger";
size?: "sm" | "md" | "lg";
loading?: boolean;
}
const sizeStyles: Record<string, React.CSSProperties> = {
sm: { padding: "var(--space-1) var(--space-2)", fontSize: "var(--font-size-sm)" },
md: { padding: "var(--space-2) var(--space-4)", fontSize: "var(--font-size-base)" },
lg: { padding: "var(--space-3) var(--space-6)", fontSize: "var(--font-size-lg)" },
};
export const Button: React.FC<ButtonProps> = ({
variant = "primary",
size = "md",
loading = false,
disabled,
children,
...props
}) => (
<button
style={{
...sizeStyles[size],
backgroundColor: `var(--color-${variant}-500)`,
color: "var(--color-neutral-100)",
borderRadius: "var(--radius-md)",
boxShadow: "var(--shadow-sm)",
cursor: disabled || loading ? "not-allowed" : "pointer",
opacity: disabled ? 0.5 : 1,
}}
disabled={disabled || loading}
aria-busy={loading}
{...props}
>
{loading ? "Loading…" : children}
</button>
);
例:Storybook の設定
// .storybook/preview.ts
import type { Preview } from "@storybook/react";
import "../src/tokens.css"; // import design tokens globally
const preview: Preview = {
parameters: {
a11y: { element: "#storybook-root" },
backgrounds: {
default: "light",
values: [
{ name: "light", value: "#ffffff" },
{ name: "dark", value: "#1a1a1a" },
],
},
},
};
export default preview;
品質保証
- ビジュアルリグレッションテスト
- アクセシビリティの自動テスト
- クロスブラウザーテスト
- パフォーマンスのベンチマーク
- コンポーネントの単体テスト
- 統合テスト
デザインシステムを進化させる際は、変更が WCAG 2.1 AA に準拠していることを検証し、ビジュアルリグレッションテストを実施して、トークンの更新がすべての利用アプリケーションに正しく反映されることを確認してください。
コメント
Markdown 対応