mcpField
P
phase-5-design-system

phase-5-design-system

github.com/ww-w-aiデザイン・UI60675 回インストール4 週間前に更新
リポジトリ

phase-5-design-system について

プラットフォームに依存しないデザインシステムを構築し、再利用可能なUIコンポーネントと共通ルールを整えるスキルです。Webとモバイルを対象に、トークン、コンポーネント、カスタマイズ、ドキュメントを扱います。

主な機能

  1. 01デザイントークンの定義
  2. 02基本・複合コンポーネントの設計
  3. 03コンポーネントのカスタマイズ
  4. 04Web・モバイル向け実装ガイド
  5. 05プラットフォーム間のトークン共有
  6. 06コンポーネントドキュメント

活用シーン

  1. 01プロジェクト内のUI規範の統一
  2. 02再利用可能なコンポーネントライブラリの構築
  3. 03複数プラットフォーム間でのトークン共有

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ww-w-ai/bkit-claude-code --skill phase-5-design-system

インストール後、Claude Code で/phase-5-design-systemを入力して読み込まれたか確認します。

詳細

フェーズ 5:デザインシステム

プラットフォームに依存しないデザインシステムを構築します

目的

再利用可能な UI コンポーネントライブラリを構築します。一貫したデザインと迅速な開発を実現します。


デザインシステムとは?

定義

デザインシステムとは、大規模な環境でも一貫したユーザー体験を構築できる、再利用可能なコンポーネントと明確な標準の集合です。

なぜ必要なのか?(フレームワーク非依存)
課題デザインシステムによる解決策
デザイナーと開発者の認識のずれ信頼できる唯一の情報源
コンポーネントの重複開発再利用可能なコンポーネントライブラリ
UI/UX の不統一統一されたデザイントークンとルール
メンテナンスコストの増加変更管理の一元化
新メンバーのオンボーディングの遅れ文書化されたコンポーネントカタログ
デザインシステムの 3 層
┌─────────────────────────────────────────────────────┐
│              Design Tokens                           │
│   Color, Typography, Spacing, Radius, Shadow, ...   │
├─────────────────────────────────────────────────────┤
│              Core Components                         │
│   Button, Input, Card, Dialog, Avatar, Badge, ...   │
├─────────────────────────────────────────────────────┤
│            Composite Components                      │
│   Form, DataTable, Navigation, SearchBar, ...       │
└─────────────────────────────────────────────────────┘
プラットフォーム固有の実装ツール
プラットフォーム推奨ツールデザイントークンの方式
Web(React/Next.js)shadcn/ui、RadixCSS Variables
Web(Vue)Vuetify、PrimeVueCSS Variables
FlutterMaterial 3、Custom ThemeThemeData
iOS(SwiftUI)ネイティブコンポーネントAsset Catalog、Color Set
Android(Compose)Material 3MaterialTheme
React NativeNativeBase、TamaguiStyleSheet + Theme

このフェーズで行うこと

  1. 基本コンポーネントのインストール:Button、Input、Card など
  2. カスタマイズ:プロジェクトのスタイルに合わせて調整します
  3. 複合コンポーネント:複数の基本コンポーネントを組み合わせます
  4. ドキュメント作成:コンポーネントの使用方法を文書化します

成果物

components/
└── ui/                     # shadcn/ui components
    ├── button.tsx
    ├── input.tsx
    ├── card.tsx
    └── ...

lib/
└── utils.ts                # Utilities (cn function, etc.)

docs/02-design/
└── design-system.md        # Design system specification

PDCA の適用

  • Plan:必要なコンポーネントの一覧
  • Design:コンポーネントの構造、バリエーションの設計
  • Do:コンポーネントの実装/カスタマイズ
  • Check:一貫性をレビュー
  • Act:仕上げてフェーズ 6 に進みます

レベル別の適用

レベル適用方法
Starter任意(シンプルなプロジェクトでは省略可能)
Dynamic必須
Enterprise必須(デザイントークンを含む)

shadcn/ui のインストール

# Initial setup
npx shadcn@latest init

# Add components
npx shadcn@latest add button
npx shadcn@latest add input
npx shadcn@latest add card

必要なコンポーネント一覧

基本
  • Button、Input、Textarea
  • Card、Badge、Avatar
  • Dialog、Sheet、Popover
フォーム
  • Form、Label、Select
  • Checkbox、Radio、Switch
ナビゲーション
  • Navigation Menu、Tabs
  • Breadcrumb、Pagination

カスタムテーマの構築

デザイントークンのオーバーライド

shadcn/ui は CSS 変数ベースのため、globals.css でテーマをカスタマイズします。

/* globals.css */
@layer base {
  :root {
    /* ===== Colors ===== */
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;      /* Brand main color */
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --accent: 210 40% 96.1%;
    --destructive: 0 84.2% 60.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;

    /* ===== Typography ===== */
    --font-sans: 'Pretendard', sans-serif;
    --font-mono: 'JetBrains Mono', monospace;

    /* ===== Spacing (rem units) ===== */
    --spacing-xs: 0.25rem;   /* 4px */
    --spacing-sm: 0.5rem;    /* 8px */
    --spacing-md: 1rem;      /* 16px */
    --spacing-lg: 1.5rem;    /* 24px */
    --spacing-xl: 2rem;      /* 32px */

    /* ===== Border Radius ===== */
    --radius: 0.5rem;
    --radius-sm: 0.25rem;
    --radius-lg: 0.75rem;
    --radius-full: 9999px;

    /* ===== Shadows ===== */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --primary: 217.2 91.2% 59.8%;
    /* ... dark mode overrides */
  }
}
Tailwind 設定の拡張
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: {
          50: 'hsl(var(--brand-50))',
          500: 'hsl(var(--brand-500))',
          900: 'hsl(var(--brand-900))',
        },
      },
      fontFamily: {
        sans: ['var(--font-sans)', 'system-ui'],
        mono: ['var(--font-mono)', 'monospace'],
      },
      spacing: {
        'xs': 'var(--spacing-xs)',
        'sm': 'var(--spacing-sm)',
        'md': 'var(--spacing-md)',
        'lg': 'var(--spacing-lg)',
        'xl': 'var(--spacing-xl)',
      },
      borderRadius: {
        'sm': 'var(--radius-sm)',
        'DEFAULT': 'var(--radius)',
        'lg': 'var(--radius-lg)',
        'full': 'var(--radius-full)',
      },
    },
  },
}
デザイントークンのドキュメント化

プロジェクトごとに docs/02-design/design-tokens.md を作成することをおすすめします。

トークン値用途
--primary221.2 83.2% 53.3%ブランドのメインカラー
--radius0.5remデフォルトの角丸
--font-sansPretendard本文のフォント

コンポーネントのカスタマイズ

// Extend default button to project style
const Button = React.forwardRef<
  HTMLButtonElement,
  ButtonProps & { isLoading?: boolean }
>(({ isLoading, children, ...props }, ref) => {
  return (
    <ButtonPrimitive ref={ref} {...props}>
      {isLoading ? <Spinner /> : children}
    </ButtonPrimitive>
  );
});

モバイルアプリのデザインシステム

Flutter:カスタムテーマの構築

Flutter では ThemeData を通じてデザイントークンを定義します。

// lib/theme/app_theme.dart
import 'package:flutter/material.dart';

class AppTheme {
  // ===== Design Tokens =====

  // Colors
  static const Color primary = Color(0xFF3B82F6);
  static const Color secondary = Color(0xFF64748B);
  static const Color destructive = Color(0xFFEF4444);
  static const Color background = Color(0xFFFFFFFF);
  static const Color foreground = Color(0xFF0F172A);

  // Spacing
  static const double spacingXs = 4.0;
  static const double spacingSm = 8.0;
  static const double spacingMd = 16.0;
  static const double spacingLg = 24.0;
  static const double spacingXl = 32.0;

  // Border Radius
  static const double radiusSm = 4.0;
  static const double radiusMd = 8.0;
  static const double radiusLg = 12.0;
  static const double radiusFull = 9999.0;

  // ===== Theme Data =====

  static ThemeData get lightTheme => ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: primary,
      brightness: Brightness.light,
    ),
    fontFamily: 'Pretendard',

    // Button Theme
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        padding: EdgeInsets.symmetric(
          horizontal: spacingMd,
          vertical: spacingSm,
        ),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(radiusMd),
        ),
      ),
    ),

    // Card Theme
    cardTheme: CardTheme(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(radiusLg),
      ),
    ),

    // Input Theme
    inputDecorationTheme: InputDecorationTheme(
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(radiusMd),
      ),
      contentPadding: EdgeInsets.all(spacingSm),
    ),
  );

  static ThemeData get darkTheme => ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: primary,
      brightness: Brightness.dark,
    ),
    fontFamily: 'Pretendard',
    // ... dark theme overrides
  );
}
Flutter:再利用可能なコンポーネント
// lib/components/app_button.dart
import 'package:flutter/material.dart';
import '../theme/app_theme.dart';

enum AppButtonVariant { primary, secondary, destructive, outline }

class AppButton extends StatelessWidget {
  final String label;
  final VoidCallback? onPressed;
  final AppButtonVariant variant;
  final bool isLoading;

  const AppButton({
    required this.label,
    this.onPressed,
    this.variant = AppButtonVariant.primary,
    this.isLoading = false,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: isLoading ? null : onPressed,
      style: _getStyle(),
      child: isLoading
          ? SizedBox(
              width: 20,
              height: 20,
              child: CircularProgressIndicator(strokeWidth: 2),
            )
          : Text(label),
    );
  }

  ButtonStyle _getStyle() {
    switch (variant) {
      case AppButtonVariant.destructive:
        return ElevatedButton.styleFrom(
          backgroundColor: AppTheme.destructive,
        );
      case AppButtonVariant.outline:
        return ElevatedButton.styleFrom(
          backgroundColor: Colors.transparent,
          side: BorderSide(color: AppTheme.primary),
        );
      default:
        return ElevatedButton.styleFrom();
    }
  }
}
Flutter:プロジェクト構成
lib/
├── theme/
│   ├── app_theme.dart          # ThemeData + Design Tokens
│   ├── app_colors.dart         # Color constants
│   ├── app_typography.dart     # TextStyle definitions
│   └── app_spacing.dart        # Spacing constants
├── components/
│   ├── app_button.dart
│   ├── app_input.dart
│   ├── app_card.dart
│   └── app_dialog.dart
└── main.dart

クロスプラットフォームでのデザイントークン共有

デザイントークン JSON(プラットフォーム非依存)

Figma Tokens または Style Dictionary を使用して、トークンを一元管理します。

// tokens/design-tokens.json
{
  "color": {
    "primary": { "value": "#3B82F6" },
    "secondary": { "value": "#64748B" },
    "destructive": { "value": "#EF4444" }
  },
  "spacing": {
    "xs": { "value": "4px" },
    "sm": { "value": "8px" },
    "md": { "value": "16px" },
    "lg": { "value": "24px" }
  },
  "radius": {
    "sm": { "value": "4px" },
    "md": { "value": "8px" },
    "lg": { "value": "12px" }
  },
  "font": {
    "family": { "value": "Pretendard" },
    "size": {
      "sm": { "value": "14px" },
      "md": { "value": "16px" },
      "lg": { "value": "18px" }
    }
  }
}
プラットフォーム固有の変換
# Generate tokens for each platform with Style Dictionary
npx style-dictionary build

# Output:
# - build/css/variables.css      (Web)
# - build/dart/app_tokens.dart   (Flutter)
# - build/swift/AppTokens.swift  (iOS)
# - build/kt/AppTokens.kt        (Android)

デザインシステムのチェックリスト(プラットフォーム非依存)

必須項目
  • デザイントークンの定義

    • 色(プライマリー、セカンダリー、セマンティック)
    • タイポグラフィ(フォントファミリー、サイズ、ウェイト)
    • 余白(xs、sm、md、lg、xl)
    • 角丸
    • シャドウ/エレベーション
  • コアコンポーネント

    • ボタン(バリエーション:プライマリー、セカンダリー、アウトライン、破壊的操作)
    • 入力欄/テキストフィールド
    • カード
    • ダイアログ/モーダル
    • アバター
    • バッジ
  • 複合コンポーネント

    • フォーム(バリデーション付き)
    • ナビゲーション(ヘッダー、サイドバー、ボトムナビ)
    • データ表示(テーブル、リスト)
  • ドキュメント

    • コンポーネントカタログ(Storybook / Widgetbook)
    • 使用ガイドライン
    • 推奨事項と禁止事項

テンプレート

templates/pipeline/phase-5-design-system.template.md を参照してください。

次のフェーズ

フェーズ 6:UI の実装+API 連携 → コンポーネントの準備ができたので、実際の画面を実装します

コメント