mcpField
N
nextjs-shadcn-builder

nextjs-shadcn-builder

github.com/ovachiever開発56262 回インストール48 週間前に更新
リポジトリ

nextjs-shadcn-builder について

Next.jsアプリの新規作成や、既存フロントエンドのNext.jsとshadcn/uiへの移行を支援するスキルです。分析、コンポーネント対応付け、段階的な変換、検証を、デザイントークン、レスポンシブ設計、アクセシビリティを軸に進めます。

主な機能

  1. 01App Routerを使ったNext.jsの初期化
  2. 02フロントエンドコードとコンポーネントの分析
  3. 03コンポーネント移行の計画と分割
  4. 04UIをshadcn/uiコンポーネントに対応付け
  5. 05テスト、レスポンシブ設計、アクセシビリティの検証

活用シーン

  1. 01Next.jsアプリの新規構築
  2. 02Reactフロントエンドの移行
  3. 03VueやAngularのUI変換
  4. 04移行中のスタイル統一

MCP 対応

ワークフローではshadcn MCPサーバーを使い、コンポーネント、ドキュメント、ブロック、チャート、デザイントークンの情報を検索します。サーバーの利用可否を確認し、利用できない場合の初期化方法も示します。

インストール

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

$npx skills add https://github.com/ovachiever/droid-tings --skill nextjs-shadcn-builder

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
assets/
theme-example-oklch.css
assets/component-templates/
complex-form.tsx
example-feature-card.tsx
example-user-profile.tsx
responsive-dashboard.tsx
responsive-data-table.tsx
responsive-navigation.tsx
references/
accessibility-best-practices.md
advanced-shadcn-components.md
react-to-nextjs.md
responsive-design-patterns.md
shadcn-component-mapping.md
styling-migration.md
vue-to-nextjs.md
scripts/
analyze-codebase.py
detect-hardcoded-values.sh
generate-migration-report.py
init-nextjs-shadcn.sh

詳細

Next.js + shadcn/ui ビルダー&移行ツール

厳格な設計原則とベストプラクティスに従って、本番環境に対応した Next.js アプリケーションを構築するか、既存のフロントエンドを体系的に Next.js + shadcn/ui に移行します。

概要

このスキルでは、次の 2 つの主要なワークフローを扱います。

  1. 新しい Next.js アプリケーションの作成 - Next.js 15+(App Router)、shadcn/ui、適切なデザインシステム設定でプロジェクトを初期化します
  2. 既存フロントエンドの移行 - あらゆるフロントエンドのコードベース(React、Vue、Angular、vanilla JS)を分析し、体系的に Next.js + shadcn/ui に変換します

基本方針:shadcn/ui の設計原則に 100%準拠します。

  • すべてのテーマ設定に CSS 変数を使用します(色、間隔、タイポグラフィ)
  • 標準の shadcn/ui コンポーネントのみを使用します(カスタム UI コンポーネントは使用しません)
  • ハードコードされた値は使用しません(色、間隔、フォント)
  • アプリケーション全体で一貫したデザイントークンを使用します
  • すべてのデバイス(スマートフォン、タブレット、デスクトップ)に対応するモバイルファーストのレスポンシブデザイン
  • WCAG 2.1 レベル AA のアクセシビリティ準拠
  • https://ui.shadcn.com のベストプラクティス

ワークフロー決定ツリー

User Request
    ├─ Creating New Next.js App
    │   └─ Follow "Creating New Application" workflow (Phase 3 onwards)
    │
    └─ Migrating Existing Codebase
        ├─ Phase 1: Codebase Analysis
        ├─ Phase 2: Migration Planning
        ├─ Phase 3: Next.js + shadcn Setup
        ├─ Phase 4: Systematic Conversion
        └─ Phase 5: Verification & Cleanup

移行の大まかなワークフロー

フェーズ 1:コードベースの分析

既存のフロントエンドを自動分析し、範囲と複雑さを把握します。

手順:

  1. フレームワークとバージョンの検出
  2. コンポーネントの一覧作成と分類
  3. ハードコードされた値の検出(色、間隔、カスタムコンポーネント)
  4. スタイリング手法の分析(CSS、SCSS、CSS-in-JS、Tailwind など)
  5. 状態管理とルーティングのパターンの特定
  6. 詳細な分析レポートの生成

成果物:

  • フレームワーク分析レポート
  • コンポーネント一覧(JSON)
  • ハードコードされた値のレポート
  • 複雑さの評価
フェーズ 2:移行計画の作成

優先順位を付けたバッチで、体系的な変換計画を作成します。

手順:

  1. 既存のコンポーネントを shadcn/ui の同等コンポーネントに対応付ける
  2. カスタム開発が必要なコンポーネントを特定する
  3. 変換をバッチに分割する(1 バッチあたり 5~10 個のコンポーネント)
  4. バッチごとにリスクと複雑さを評価する
  5. 詳細な移行計画を作成する

成果物:

  • コンポーネント対応表
  • バッチ分割された変換計画
  • リスク評価
  • コンポーネントごとの複雑さの見積もり
フェーズ 3:Next.js + shadcn のセットアップ

既存のコードベースに併設するか置き換える形で、Next.js のインフラストラクチャを初期化します。

手順:

  1. ドキュメントにアクセスできるよう、shadcn MCP サーバーを確認/インストールする
  2. App Router と TypeScript を使用して Next.js 15+ を初期化する
  3. Tailwind CSS をインストールして設定する
  4. shadcn/ui の初期化を実行する
  5. CSS 変数とデザイントークンをセットアップする
  6. パスエイリアス(@/)を設定する
  7. 必須の shadcn コンポーネントをインストールする
  8. デザインシステムのドキュメントを作成する

成果物:

  • 設定済みの Next.js プロジェクト
  • デザイントークンシステム(CSS 変数)
  • コンポーネントライブラリのセットアップ
  • 設定済みのパスエイリアス
フェーズ 4:体系的な変換

バッチごとにコンポーネントを変換し、各バッチの後にテストします。

手順:

  1. バッチ 1:レイアウトと構造(ヘッダー、フッター、レイアウトラッパー)
  2. バッチ 2:シンプルな UI コンポーネント(ボタン、カード、バッジ、アラート)
  3. バッチ 3:フォームコンポーネント(入力、セレクト、チェックボックス、フォーム)
  4. バッチ 4:複雑なコンポーネント(テーブル、ダイアログ、コマンドメニュー、データの可視化)
  5. バッチ 5:スタイリングの標準化(ハードコードされた値を削除し、CSS 変数を適用)
  6. バッチ 6:ページとルート(ページを変換し、Next.js のルーティングをセットアップ)

バッチごとのワークフロー:

  1. 関連するコンポーネントを 5~10 個選択する
  2. MCP を使用して適切な shadcn コンポーネントを見つける
  3. shadcn のパターンに従ってコンポーネントを変換する
  4. ハードコードされた値を CSS 変数に置き換える
  5. 機能をテストする
  6. 視覚的な一貫性を確認する
  7. 次のバッチに進む

成果物:

  • 移行済みコンポーネント(バッチごと)
  • CSS 変数を使用したスタイルの更新
  • Next.js App Router のページ
  • バッチごとのテスト合格
フェーズ 5:検証とクリーンアップ

最終テスト、最適化、古いコードの削除を行います。

手順:

  1. テストスイート全体を実行します
  2. ビジュアルリグレッションテストを行います
  3. レスポンシブデザインをテストします(モバイル、タブレット、デスクトップ)
  4. パフォーマンス監査を行います
  5. アクセシビリティ監査を行います(WCAG 2.1 レベル AA 準拠)
  6. 古いフレームワークのコードを削除します
  7. ドキュメントを更新します
  8. 完了レポートを生成します

成果物:

  • テスト結果
  • レスポンシブデザインの検証レポート
  • パフォーマンス指標
  • アクセシビリティ監査レポート(WCAG 2.1 AA)
  • クリーンなコードベース
  • 移行の概要

フェーズ 1:コードベース分析(詳細な手順)

1.1 フレームワークの検出

自動分析スクリプトを実行します:

python ./scripts/analyze-codebase.py /path/to/existing/codebase

このスクリプトは以下を実行します:

  • フレームワークを検出します(React、Vue、Angular、Svelte、vanilla JS など)
  • フレームワークのバージョンを特定します
  • ビルドツールを検出します(Vite、Webpack、Parcel など)
  • package.json の依存関係を確認します
  • ディレクトリ構成をマッピングします

出力: フレームワークのメタデータを含む codebase-analysis.json

1.2 コンポーネントの一覧作成

分析スクリプトは、以下を含むコンポーネントの一覧を自動生成します:

  • コンポーネント名とファイルパス
  • コンポーネントの種類(関数型、クラス型、Vue SFC など)
  • Props/入力
  • State の使用状況
  • 子コンポーネント
  • 外部依存関係

出力: component-inventory.json

構造の例:

{
  "components": [
    {
      "name": "UserCard",
      "path": "src/components/UserCard.tsx",
      "type": "functional",
      "complexity": "simple",
      "shadcn_equivalent": "Card",
      "hardcoded_values": ["#3b82f6", "16px padding"],
      "dependencies": ["react", "styled-components"]
    }
  ]
}
1.3 ハードコードされた値の検出

検出スクリプトを実行します:

bash ./scripts/detect-hardcoded-values.sh /path/to/existing/codebase

このスクリプトは以下を検出します:

  • ハードコードされた色: #hex、rgb()、rgba()、hsl()、色名
  • インラインのスペーシング: margin: 20px、padding: 1rem
  • カスタムフォントの宣言: 標準以外のフォント
  • マジックナンバー: コンポーネント内の任意の値
  • インラインスタイル: style={{...}}
  • 標準外のパターン: Tailwind を使用すべき CSS-in-JS、styled-components

出力: 違反項目をカテゴリ別にまとめた hardcoded-values-report.md

1.4 分析レポートの生成

レポート生成ツールを実行します:

python ./scripts/generate-migration-report.py

これにより、すべての分析データを包括的な Markdown レポートにまとめます:

出力: migration-analysis-report.md

# Frontend Migration Analysis Report

## Executive Summary
[One-paragraph overview: framework, size, complexity]

## Current State Analysis
- **Framework**: React 18.2.0
- **Build Tool**: Vite 4.3.0
- **Component Count**: 47 components
- **Styling**: styled-components + custom CSS
- **State Management**: Redux Toolkit
- **Routing**: React Router v6

## Hardcoded Values Detected
- Colors: 142 instances across 34 files
- Spacing: 89 instances across 28 files
- Custom fonts: 3 non-standard fonts
- Inline styles: 67 instances

## Component Categorization
- **Simple (shadcn mapping exists)**: 28 components
- **Moderate (requires adaptation)**: 13 components
- **Complex (custom development needed)**: 6 components

## Recommended Migration Plan
1. Phase 3: Setup Next.js + shadcn infrastructure
2. Phase 4.1: Convert layout components (Header, Footer, Layout)
3. Phase 4.2: Convert simple UI (Button, Card, Badge → shadcn equivalents)
4. Phase 4.3: Convert forms (Input, Select → shadcn/ui Form components)
5. Phase 4.4: Convert complex components (DataTable, Charts)
6. Phase 4.5: Styling standardization (CSS variables)
7. Phase 4.6: Pages and routing
8. Phase 5: Verification and cleanup

## Estimated Effort
- **Total Components**: 47
- **Batches**: 9-10 batches
- **Complexity**: Moderate

フェーズ 2:移行計画(詳細な手順)

2.1 コンポーネントのマッピング戦略

component-inventory.json を確認し、shadcn コンポーネントのリファレンスを使用してマッピング表を作成します。

非常に重要:MCP を使用して shadcn コンポーネントを確認してください

マッピングの前に、shadcn MCP サーバーが利用可能か確認します:

# Check if MCP server is available
# Try accessing https://ui.shadcn.com/docs/mcp

MCP が利用できない場合は、インストールします:

npx shadcn@latest mcp init --client claude

MCP を使用して利用可能なコンポーネントを検索します:

  • 「ボタンにはどの shadcn コンポーネントがありますか?」
  • 「shadcn のフォームコンポーネントを表示してください」
  • 「モーダル/ダイアログに相当する shadcn コンポーネントは何ですか?」
  • 「shadcn で利用できるデータ表示コンポーネント」

コンポーネントマッピング表のテンプレート:

既存のコンポーネントshadcn の相当コンポーネント複雑さ優先度備考
CustomButtonButton低1Props はほぼ互換性があります
ModalDialog中2API が異なり、Radix を使用します
DataTableTable + DataTable高3カスタムフックが必要です
DropdownDropdownMenu低1直接マッピングできます
DatePickerCalendar + Popover中2コンポジションパターン

フレームワーク固有の移行ガイドを読み込みます:

  • React の場合:./references/react-to-nextjs.md を読みます
  • Vue の場合:./references/vue-to-nextjs.md を読みます
  • Angular の場合:./references/angular-to-nextjs.md を読みます
  • スタイリングの場合:./references/styling-migration.md を読みます
2.2 バッチの編成

以下の原則に従って、コンポーネントをバッチに編成します。

バッチ戦略:

  1. 種類ごとにグループ化(レイアウト、フォーム、データ表示、ナビゲーション)
  2. シンプルなものから複雑なものへ(簡単に対応できるものから始めます)
  3. 依存関係の順序(依存先を先に変換します)
  4. バッチのサイズ:バッチあたり5~10個のコンポーネント

バッチ計画の例:

バッチ1:レイアウトと構造(優先度:重大)

  • ヘッダー
  • フッター
  • MainLayout
  • Container
  • Sidebar

バッチ2:シンプルなUIコンポーネント(優先度:高)

  • Button → shadcn Button
  • Card → shadcn Card
  • Badge → shadcn Badge
  • Alert → shadcn Alert
  • Avatar → shadcn Avatar

バッチ3:フォームコンポーネント(優先度:高)

  • Input → shadcn Input
  • Select → shadcn Select
  • Checkbox → shadcn Checkbox
  • RadioGroup → shadcn RadioGroup
  • フォームのバリデーション → shadcn Form + react-hook-form

バッチ4:ナビゲーション(優先度:中)

  • NavBar → shadcn NavigationMenu
  • パンくずリスト → shadcn Breadcrumb
  • Tabs → shadcn Tabs
  • ページネーション → shadcn Pagination

バッチ5:データ表示(優先度:中)

  • Table → shadcn Table
  • DataGrid → shadcn DataTable(並べ替え、フィルタリング機能付き)
  • List → shadcn のカスタム合成
  • Accordion → shadcn Accordion

バッチ6:オーバーレイとモーダル(優先度:中)

  • Modal → shadcn Dialog
  • Tooltip → shadcn Tooltip
  • Popover → shadcn Popover
  • DropdownMenu → shadcn DropdownMenu

バッチ7:複雑なコンポーネント(優先度:低)

  • グラフ → shadcn Charts(Recharts との統合)
  • カレンダー/DatePicker → shadcn Calendar
  • CommandPalette → shadcn Command
  • DataVisualization → shadcn プリミティブを使ったカスタム実装

バッチ8:スタイルの標準化(優先度:重大)

  • ハードコードされたすべての色を抽出 → CSS 変数
  • 余白を Tailwind クラスに変換
  • タイポグラフィを標準化
  • テーマシステムを一貫して適用

バッチ9:ページとルーティング(優先度:重大)

  • ページを Next.js App Router に変換
  • Next.js の layout.tsx でレイアウトを設定
  • ルーティングパターンを実装
  • ローディング状態とエラー状態を追加
2.3 リスク評価

各バッチについて、リスクを特定します。

  • API の違い:API が大きく異なるコンポーネント
  • 機能の不足:旧コンポーネントにあり、shadcn にはない機能
  • 状態管理:リファクタリングが必要な複雑な状態
  • 依存関係:置き換えが必要な外部ライブラリ
  • カスタムロジック:UI と密接に結び付いているビジネスロジック

リスクの軽減策:

  • 変換前に API の違いを文書化します
  • 必要に応じてアダプター/ラッパーコンポーネントを作成します
  • 移行前にテストを作成します
  • 移行中は古いコンポーネントを一時的に残します
2.4 詳細な移行計画の作成

詳細な計画書 migration-plan.md を生成します。

# Next.js + shadcn Migration Plan

## Project: [Project Name]
## Date: [Current Date]
## Estimated Timeline: [X batches]

## Migration Strategy

### Approach
- Incremental migration with parallel running old and new code
- Batch-based conversion (5-10 components per batch)
- Test after each batch before proceeding
- Feature flag new components during transition

### Success Criteria
- All components use shadcn/ui or shadcn patterns
- Zero hardcoded colors/spacing (CSS variables only)
- 100% TypeScript coverage
- Passing test suite
- Lighthouse score >= 90
- No accessibility violations

## Detailed Batch Plan

[Include all batches from 2.2 with specific components listed]

## Timeline

Batch 1: Layout & Structure (Days 1-2)
Batch 2: Simple UI (Days 3-4)
[etc.]

## Notes and Considerations
[Any special requirements, blockers, or dependencies]

フェーズ3:Next.js + shadcn のセットアップ(詳細手順)

3.1 shadcn MCP サーバーの確認/インストール

重大:shadcn コンポーネントの検索には常に MCP を使用してください

  1. MCP サーバーにアクセスできるか確認します。

    • https://ui.shadcn.com/docs/mcp のドキュメントにアクセスしてみます
    • MCP 経由で shadcn コンポーネントを照会できるか確認します
  2. 利用できない場合は、MCP サーバーをインストールします。

npx shadcn@latest mcp init --client claude

これにより、以下が可能になります。

  • shadcn のドキュメントにリアルタイムでアクセス
  • コンポーネントの検索と探索
  • ブロックとグラフのテンプレートの探索
  • テーマとデザイントークンの参照

開発中の MCP の使用方法:

  • 「[ユースケース]で利用できるコンポーネントは何ですか?」
  • 「shadcn Button の props を見せてください」
  • 「shadcn で利用できるグラフの種類は何ですか?」
  • 「バリデーション付きで shadcn Form を使用する方法を教えてください」
3.2 Next.js プロジェクトの初期化

初期化スクリプトを実行します。

bash ./scripts/init-nextjs-shadcn.sh [project-name]

または、手動で初期化します。

# Check Node.js version (18+ required)
node -v

# Create Next.js project with App Router
npx create-next-app@latest [project-name] \
  --typescript \
  --tailwind \
  --app \
  --src-dir \
  --import-alias "@/*" \
  --no-turbopack

cd [project-name]
3.3 shadcn/ui のインストールと設定
# Initialize shadcn/ui
npx shadcn@latest init

# Configuration prompts:
# - TypeScript: Yes
# - Style: Default
# - Base color: Choose from slate/gray/zinc/neutral/stone
# - CSS variables: Yes (CRITICAL - required for theming)
# - Import alias: @/components

これにより、以下が作成されます。

  • components.json 設定ファイル
  • cn() ヘルパーを含む lib/utils.ts
  • shadcn テーマで更新された tailwind.config.ts
  • app/globals.css 内の CSS 変数
3.4 デザイントークン(CSS 変数)の設定

非常に重要:テーマ設定には必ず CSS 変数を使用してください

カラー形式:OKLCH(推奨)

このスキルでは、知覚上の均一性と色の正確性を高めるため、HSL ではなく OKLCH(OKLab 明度・彩度・色相)色空間を使用します。

OKLCH のメリット:

  • 知覚上均一です(同じ変化量が同じ知覚差になります)
  • グラデーションの補間に優れています
  • 明度をより予測しやすくなります
  • アクセシビリティに適しています(コントラスト比をより正確に把握できます)

app/globals.css を編集して、デザインシステムを定義します。

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --radius: 0.65rem;

    /* Background - Pure white */
    --background: 1 0 0;
    --foreground: 0.141 0.005 285.823;

    /* Card */
    --card: 1 0 0;
    --card-foreground: 0.141 0.005 285.823;

    /* Popover */
    --popover: 1 0 0;
    --popover-foreground: 0.141 0.005 285.823;

    /* Primary - Warm orange */
    --primary: 0.646 0.222 41.116;
    --primary-foreground: 0.98 0.016 73.684;

    /* Secondary - Light purple-gray */
    --secondary: 0.967 0.001 286.375;
    --secondary-foreground: 0.21 0.006 285.885;

    /* Muted - Subtle elements */
    --muted: 0.967 0.001 286.375;
    --muted-foreground: 0.552 0.016 285.938;

    /* Accent */
    --accent: 0.967 0.001 286.375;
    --accent-foreground: 0.21 0.006 285.885;

    /* Destructive - Red */
    --destructive: 0.577 0.245 27.325;

    /* Border and Input */
    --border: 0.92 0.004 286.32;
    --input: 0.92 0.004 286.32;

    /* Focus ring */
    --ring: 0.75 0.183 55.934;

    /* Chart colors */
    --chart-1: 0.837 0.128 66.29;
    --chart-2: 0.705 0.213 47.604;
    --chart-3: 0.646 0.222 41.116;
    --chart-4: 0.553 0.195 38.402;
    --chart-5: 0.47 0.157 37.304;
  }

  .dark {
    /* Dark mode backgrounds */
    --background: 0.141 0.005 285.823;
    --foreground: 0.985 0 0;

    /* Dark mode card */
    --card: 0.21 0.006 285.885;
    --card-foreground: 0.985 0 0;

    /* Dark mode popover */
    --popover: 0.21 0.006 285.885;
    --popover-foreground: 0.985 0 0;

    /* Dark mode primary - Brighter for contrast */
    --primary: 0.705 0.213 47.604;
    --primary-foreground: 0.98 0.016 73.684;

    /* Dark mode secondary */
    --secondary: 0.274 0.006 286.033;
    --secondary-foreground: 0.985 0 0;

    /* Dark mode muted */
    --muted: 0.274 0.006 286.033;
    --muted-foreground: 0.705 0.015 286.067;

    /* Dark mode accent */
    --accent: 0.274 0.006 286.033;
    --accent-foreground: 0.985 0 0;

    /* Dark mode destructive */
    --destructive: 0.704 0.191 22.216;

    /* Dark mode borders (with alpha) */
    --border: 1 0 0 / 10%;
    --input: 1 0 0 / 15%;

    /* Dark mode focus ring */
    --ring: 0.408 0.123 38.172;

    /* Chart colors (consistent) */
    --chart-1: 0.837 0.128 66.29;
    --chart-2: 0.705 0.213 47.604;
    --chart-3: 0.646 0.222 41.116;
    --chart-4: 0.553 0.195 38.402;
    --chart-5: 0.47 0.157 37.304;
  }
}

@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply bg-background text-foreground;
  }
}

移行するプロジェクト向けのカスタマイズ:

デザインシステムを備えた既存アプリを移行する場合は、既存のカラーを抽出し、CSS 変数に割り当てます。

# Use the detection script to find existing colors
bash ./scripts/detect-hardcoded-values.sh /path/to/old/codebase

# Map old colors to new CSS variables (OKLCH format)
# Use https://oklch.com or https://colorjs.io to convert
# Example:
# Old: #FF6B35 (brand orange) → --primary: 0.646 0.222 41.116
# Old: #3B82F6 (blue) → --primary: 0.630 0.213 255.5
# Old: #10B981 (green) → --success: 0.710 0.180 165.4
3.5 必須の shadcn コンポーネントをインストールする

MCP を使って、必要なコンポーネントを確認しましょう!

コアコンポーネントをインストールします。

# Layout & Structure
npx shadcn@latest add card
npx shadcn@latest add separator

# Forms
npx shadcn@latest add button
npx shadcn@latest add input
npx shadcn@latest add label
npx shadcn@latest add select
npx shadcn@latest add checkbox
npx shadcn@latest add radio-group
npx shadcn@latest add form

# Navigation
npx shadcn@latest add navigation-menu
npx shadcn@latest add tabs
npx shadcn@latest add breadcrumb

# Feedback
npx shadcn@latest add alert
npx shadcn@latest add toast
npx shadcn@latest add dialog
npx shadcn@latest add tooltip

# Data Display
npx shadcn@latest add table
npx shadcn@latest add badge
npx shadcn@latest add avatar

# Overlays
npx shadcn@latest add popover
npx shadcn@latest add dropdown-menu
npx shadcn@latest add sheet

開発中に必要に応じて、MCP に問い合わせて追加のコンポーネントを確認してください。

3.6 テーマプロバイダーを設定する(ダークモード対応)

next-themes をインストールします。

npm install next-themes

components/theme-provider.tsx を作成します。

"use client"

import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

app/layout.tsx を更新します。

import { ThemeProvider } from "@/components/theme-provider"

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}
3.7 サンプルコンポーネントを作成する

ベストプラクティスを示す components/example-card.tsx を作成します。

import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"

export function ExampleCard() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>shadcn/ui Best Practices</CardTitle>
        <CardDescription>
          This card demonstrates proper shadcn patterns
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p className="text-sm text-muted-foreground">
          Notice: No hardcoded colors, using CSS variables via Tailwind classes,
          standard shadcn components, and proper typography scale.
        </p>
      </CardContent>
      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button>Continue</Button>
      </CardFooter>
    </Card>
  )
}

示されている主なパターン:

  • 標準の shadcn コンポーネント(Card、Button)を使用しています
  • ハードコードされたカラーを使用しません(text-muted-foreground を使用)
  • CSS 変数は Tailwind を通じて自動的に適用されます
  • セマンティックなバリアント(outline、default)を使用しています
  • 適切にコンポーネントを構成しています

フェーズ 4:体系的な変換(詳細な手順)

4.1 コンポーネント変換のワークフロー

コンポーネントを 5~10 個ずつ変換します。

ステップ 1:バッチ内のコンポーネントを確認する

コンポーネントファイルを読み込み、以下を把握します。

  • 現在の機能
  • Props/API
  • スタイル設定の方法
  • 状態管理
  • イベントハンドラー

ステップ 2:MCP に shadcn の対応コンポーネントを問い合わせる

変換前に、MCP を使って以下を確認します。

  • 「[component type] に対応する shadcn コンポーネントは何ですか?」
  • 「shadcn の [component] の Props と使用例を見せてください」
  • 「[feature] で shadcn の [component] を使う方法を教えてください」

ステップ 3:コンポーネントを変換する

次のパターンに従います。

// OLD: Custom button with hardcoded styles
const CustomButton = ({ children, onClick, variant = 'primary' }) => {
  const styles = {
    primary: {
      backgroundColor: '#3b82f6', // HARDCODED!
      color: '#ffffff',
      padding: '8px 16px', // HARDCODED!
      borderRadius: '6px'
    },
    secondary: {
      backgroundColor: '#6b7280',
      color: '#ffffff',
      padding: '8px 16px',
      borderRadius: '6px'
    }
  }

  return (
    <button style={styles[variant]} onClick={onClick}>
      {children}
    </button>
  )
}

// NEW: shadcn Button with CSS variables
import { Button } from "@/components/ui/button"

const CustomButton = ({ children, onClick, variant = 'default' }) => {
  return (
    <Button variant={variant} onClick={onClick}>
      {children}
    </Button>
  )
}

変換チェックリスト:

  • ✅ shadcn コンポーネントに置き換える
  • ✅ ハードコードされたカラーをすべて削除する
  • ✅ インラインスタイルを削除する
  • ✅ Tailwind クラスのみを使用する
  • ✅ セマンティックなバリアント(default、outline、destructive など)を使用する
  • ✅ すべての機能を維持する
  • ✅ TypeScript の型を適切に定義する

ステップ 4:ハードコードされた値を CSS 変数に置き換える

// OLD: Hardcoded spacing and colors
<div style={{
  backgroundColor: '#f3f4f6',  // WRONG
  padding: '20px',              // WRONG
  margin: '10px 0'              // WRONG
}}>

// NEW: Tailwind classes using CSS variables
<div className="bg-secondary p-5 my-2.5">

// Or for custom spacing:
<div className="bg-secondary" style={{ padding: 'var(--spacing-5)' }}>

ステップ 5:機能をテストする

各コンポーネントの変換後に、以下を行います。

# Run tests
npm test

# Visual testing
npm run dev
# Manually verify component renders correctly

ステップ 6:違反がないことを確認する

新しいコンポーネントに対して検出スクリプトを実行します。

bash ./scripts/detect-hardcoded-values.sh src/components/[batch-name]

違反数が 0 件になるはずです。

ステップ 7:バッチを完了としてマークし、次に進む

todo リストと migration-plan.md の進捗を更新します。

4.2 よくあるコンポーネントの移行

詳細な対応表については、./references/shadcn-component-mapping.md を参照してください。

クイックリファレンス:

パターン従来の方法shadcn の方法
Buttonカスタムスタイルのボタン<Button variant="...">
Modal/Dialogカスタムオーバーレイ<Dialog> と <DialogTrigger>、<DialogContent>
Form Inputバリデーション付きカスタム入力<Form> + <FormField> + react-hook-form
Dropdownカスタムセレクト<Select> または <DropdownMenu>
Tableカスタムテーブル<Table> または DataTable パターン
Tooltipカスタムホバーコンポーネント<Tooltip>
Toast/Notificationカスタム通知useToast() フック + <Toaster>
Tabsカスタムタブコンポーネント<Tabs> と <TabsList>、<TabsContent>
Cardカスタムカードサブコンポーネントを含む <Card>
Badgeカスタムバッジ/ピル<Badge variant="...">
4.3 複雑なコンポーネントの処理

shadcn に直接対応するものがないコンポーネントの場合:

オプション 1:コンポジション

shadcn のプリミティブを使って構築します:

// Complex dashboard widget using shadcn primitives
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"

export function DashboardWidget({ title, data, onRefresh }) {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle>{title}</CardTitle>
        <Button variant="outline" size="sm" onClick={onRefresh}>
          Refresh
        </Button>
      </CardHeader>
      <CardContent>
        {data.map(item => (
          <div key={item.id} className="flex items-center justify-between py-2">
            <span className="text-sm">{item.label}</span>
            <Badge variant={item.status === 'success' ? 'default' : 'destructive'}>
              {item.value}
            </Badge>
          </div>
        ))}
      </CardContent>
    </Card>
  )
}

オプション 2:shadcn コンポーネントの拡張

shadcn を拡張するカスタムコンポーネントを作成します:

// Custom component extending shadcn Button
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

interface IconButtonProps extends React.ComponentProps<typeof Button> {
  icon: React.ReactNode
}

export function IconButton({ icon, children, className, ...props }: IconButtonProps) {
  return (
    <Button className={cn("flex items-center gap-2", className)} {...props}>
      {icon}
      {children}
    </Button>
  )
}

オプション 3:shadcn ブロックを使用

MCP を使って shadcn ブロック(あらかじめ構築された複雑なコンポーネント)を検索します:

「shadcn には [ユースケース] 向けにどのようなブロックがありますか?」

ブロックをインストールします:

npx shadcn@latest add [block-name]
4.4 ページとルートの変換

ページを Next.js App Router の構造に変換します:

旧構造(React Router):

src/
  pages/
    Home.tsx
    About.tsx
    Dashboard.tsx
    users/
      UserList.tsx
      UserDetail.tsx

新構造(Next.js App Router):

app/
  page.tsx          # Home
  about/
    page.tsx        # About
  dashboard/
    page.tsx        # Dashboard
    layout.tsx      # Dashboard layout
  users/
    page.tsx        # UserList
    [id]/
      page.tsx      # UserDetail
  layout.tsx        # Root layout
  loading.tsx       # Loading state
  error.tsx         # Error boundary

変換例:

// OLD: React Router page
// src/pages/Dashboard.tsx
import { useNavigate } from 'react-router-dom'

export function Dashboard() {
  const navigate = useNavigate()
  return (
    <div style={{ padding: '20px' }}>
      <h1>Dashboard</h1>
      <button onClick={() => navigate('/users')}>
        View Users
      </button>
    </div>
  )
}

// NEW: Next.js App Router page
// app/dashboard/page.tsx
import Link from 'next/link'
import { Button } from '@/components/ui/button'

export default function DashboardPage() {
  return (
    <div className="container py-6">
      <h1 className="text-3xl font-bold mb-6">Dashboard</h1>
      <Link href="/users">
        <Button>View Users</Button>
      </Link>
    </div>
  )
}

主な変更点:

  • ページにはデフォルトエクスポートを使用します
  • ルーターによるナビゲーションの代わりに Next.js の <Link> を使用します
  • ハードコードされたパディングを削除し、Tailwind クラスを使用します
  • shadcn の Button を使用します
4.5 状態管理の移行

参照資料を読み込みます: 状態管理のパターンについては ./references/react-to-nextjs.md を参照してください

一般的なパターン:

ローカル状態(useState):

  • Next.js App Router でも変更ありません
  • クライアントコンポーネントに "use client" を指定します

グローバル状態:

  • Redux → Zustand または React Context
  • MobX → Zustand
  • Recoil → Zustand または Jotai

サーバー状態:

  • React Query → TanStack Query(Next.js でも引き続き動作します)
  • SWR → SWR(Next.js 互換)
  • または、サーバーのデータには Next.js Server Components を使用します

フェーズ 5:検証とクリーンアップ(詳細手順)

5.1 テストスイートを実行
# Run all tests
npm test

# Run with coverage
npm test -- --coverage

# Ensure 100% of migrated components have passing tests
5.2 ビジュアルリグレッションテスト

手動での確認チェックリスト:

  • すべてのページが正しく表示される
  • すべてのコンポーネントがデザインシステムに準拠している
  • ダークモードが正しく動作する
  • レスポンシブデザインが維持されている
  • ハードコードされた色が表示されない
  • 全体を通して間隔が統一されている
  • タイポグラフィがデザインシステムに準拠している

任意:Percy、Chromatic、または Playwright を使って、自動ビジュアルリグレッションテストを設定します。

5.3 レスポンシブデザインのテスト

重要:ブラウザーの DevTools だけでなく、実機でテストしてください

参照先: 包括的なレスポンシブテストのガイドラインについては ./references/responsive-design-patterns.md を参照してください。

デバイステストのチェックリスト:

  • iPhone SE(320px - 現行機種で最小のビューポート)
  • iPhone 14 Pro(390px)
  • iPad(768px)
  • iPad Pro(1024px)
  • デスクトップ(1280px - 1920px)
  • ウルトラワイド(2560px 以上)

向きのテスト:

  • モバイル/タブレットの縦向き
  • モバイル/タブレットの横向き
  • デバイスを回転させたときのレスポンシブな動作

レスポンシブパターンの確認:

  • ナビゲーション:モバイルのハンバーガーメニュー → タブレットのサイドバー → デスクトップのナビゲーションバー
  • データテーブル:モバイルのカード → タブレットのスクロール可能なテーブル → デスクトップの全幅テーブル
  • グリッド:モバイルは 1 列 → タブレットは 2 列 → デスクトップは 3~4 列
  • フォーム:モバイルは 1 列 → デスクトップは複数列
  • タッチターゲット:モバイルでは最小 44x44px
  • タイポグラフィ:すべての画面サイズで読みやすい(本文は最小 16px)
  • 画像:適切なアスペクト比でレスポンシブにサイズ調整される

ブレークポイントの確認:

# Test all Tailwind breakpoints
# sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px

# Verify components respond correctly at each breakpoint

コンポーネントの例: レスポンシブデザインの例については ./assets/component-templates/ を確認してください:

  • responsive-navigation.tsx - モバイル/タブレット/デスクトップのナビゲーションパターン
  • responsive-data-table.tsx - モバイルではカード表示になるレスポンシブテーブル
  • responsive-dashboard.tsx - レスポンシブなグリッドレイアウト
  • complex-form.tsx - 複数ステップのレスポンシブフォーム
5.4 ハードコードされた値の最終チェックを実行
bash ./scripts/detect-hardcoded-values.sh src/

期待される結果: 違反 0 件

違反が見つかった場合は、フェーズ 4 に戻って修正してください。

5.5 アクセシビリティ監査(WCAG 2.1 レベル AA)

重要:WCAG 2.1 レベル AA への準拠を達成してください

参照先: アクセシビリティテストの包括的なガイドラインについては、./references/accessibility-best-practices.md を参照してください。

# Install axe DevTools or use Lighthouse
npm install -D @axe-core/playwright

# Run accessibility tests
npm run test:a11y

shadcn/ui のコンポーネントは、アクセシビリティを考慮して構築されています(Radix UI のプリミティブを使用)が、次の項目を確認してください。

自動テスト:

  • axe DevTools のブラウザー拡張機能をすべてのページで実行する
  • Lighthouse のアクセシビリティスコアが 90 以上
  • 自動ツールによる WCAG 違反の報告がない
  • eslint-plugin-jsx-a11y が合格している(設定されている場合)

キーボード操作(WCAG 2.1.1、2.1.2):

  • すべてのインタラクティブ要素に Tab キーでアクセスできる
  • 論理的なタブ順序になっている(視覚的なレイアウトに沿っている)
  • キーボードトラップがない(すべてのコンポーネントから Tab キーで移動できる)
  • Enter/Space キーでボタンやリンクを操作できる
  • Escape キーでモーダルやダイアログを閉じられる
  • 矢印キーでコンポーネント内を移動できる(タブ、メニュー、ラジオグループ)
  • すべてのインタラクティブ要素でフォーカスインジケーターが見える

スクリーンリーダーのテスト: 実際のスクリーンリーダーでテストします。

  • macOS:VoiceOver(Cmd + F5)
  • Windows:NVDA(無料)または JAWS
  • モバイル:VoiceOver(iOS)または TalkBack(Android)

スクリーンリーダーのチェックリスト(WCAG 1.3.1、4.1.2):

  • すべての画像に alt テキストがある
  • フォーム入力に対応するラベルがある
  • ボタンに説明的なテキストまたは aria-label がある
  • 見出しが論理的な階層に沿っている(h1 → h2 → h3)
  • ランドマークがある(header、nav、main、aside、footer)
  • 動的コンテンツが aria-live 領域を介して通知される
  • エラーメッセージがスクリーンリーダーに通知される

色のコントラスト(WCAG 1.4.3):

  • 本文テキスト:コントラスト比が 4.5:1 以上
  • 大きなテキスト(18pt 以上):コントラスト比が 3:1 以上
  • UI コンポーネント:コントラスト比が 3:1 以上
  • フォーカスインジケーター:コントラスト比が 3:1 以上
  • ライトモードとダークモードの両方でテストする

フォームのアクセシビリティ(WCAG 3.3.1、3.3.2):

  • すべての入力に視認できるラベルがある
  • 必須フィールドが明確に示されている
  • エラーメッセージが具体的で役に立つ
  • エラーメッセージが入力に関連付けられている(aria-describedby)
  • フォームの検証が色だけに依存していない

タッチターゲット(WCAG 2.5.5):

  • モバイル上のすべてのタッチターゲットが CSS ピクセルで 44x44 以上
  • タッチターゲット間に十分な間隔がある(最低 8px)

ARIA の使用(WCAG 4.1.2):

  • アイコンのみのボタンに ARIA ラベルがある
  • 折りたたみ可能なセクションに aria-expanded がある
  • タブに aria-selected がある
  • 装飾要素に aria-hidden がある
  • エラーメッセージに role="alert" がある
  • 重要度の低い更新に role="status" がある

WCAG 2.1 AA 完全チェックリスト: WCAG 2.1 レベル AA の完全なチェックリストについては、./references/accessibility-best-practices.md を参照してください。

5.6 パフォーマンス監査
# Build for production
npm run build

# Analyze bundle
npm run analyze  # If you have bundle analyzer configured

Lighthouse 監査を実行します。

  • パフォーマンスが 90 以上
  • アクセシビリティが 90 以上
  • ベストプラクティスが 90 以上
  • SEO が 90 以上

パフォーマンスのチェックリスト:

  • Core Web Vitals が「良好」の基準を満たしている
    • LCP(最大視覚コンテンツの表示時間)< 2.5s
    • FID(初回入力遅延)< 100ms
    • CLS(累積レイアウトシフト)< 0.1
  • 画像が最適化されている(Next.js Image コンポーネントを使用)
  • 大きなコンポーネントにコード分割が実装されている
  • ファーストビューより下のコンテンツが遅延読み込みされる
  • バンドルサイズが妥当である(バンドルアナライザーで確認)
5.7 古いコードを削除する

移行の検証が完了したら:

# Remove old framework code
rm -rf src/old-components/  # or whatever old structure was

# Remove old dependencies
npm uninstall [old-framework] [old-ui-library] styled-components emotion ...

# Clean up old config files
rm -f .babelrc webpack.config.js  # etc.
5.8 完了レポートを生成する

migration-complete-report.md を作成します。

# Migration Completion Report

## Summary
Successfully migrated [Project Name] from [Old Framework] to Next.js + shadcn/ui.

## Statistics
- **Components Migrated**: 47
- **Lines of Code Changed**: ~5,200
- **Hardcoded Values Removed**: 231
- **CSS Variables Added**: 48
- **shadcn Components Used**: 18

## Test Results
- **Unit Tests**: 142/142 passing
- **Integration Tests**: 23/23 passing
- **Accessibility Score**: 98/100
- **Lighthouse Performance**: 94/100

## Before/After Comparison

### Before
- Framework: React 18 + Vite
- Styling: styled-components + custom CSS
- Hardcoded values: 231 violations
- Bundle size: 523 KB
- Lighthouse: 76

### After
- Framework: Next.js 15 + App Router
- Styling: Tailwind CSS + shadcn/ui
- Hardcoded values: 0 violations
- Bundle size: 398 KB (24% reduction)
- Lighthouse: 94 (23% improvement)

## Design System
All components now use CSS variables defined in globals.css:
- 24 color tokens
- 12 spacing tokens
- 8 typography tokens
- Full dark mode support

## Next Steps
- Deploy to production
- Monitor performance metrics
- Gather user feedback
- Optional: Implement additional shadcn blocks

shadcn のデザイン原則(重要)

基本原則

1. すべてのテーマ設定に CSS 変数を使用する

  • 色、余白、タイポグラフィをハードコードしてはいけません
  • すべてのデザイントークンを globals.css の CSS 変数として定義します
  • これらの変数を参照する Tailwind クラスを使用します

2. 標準コンポーネントのみを使用する

  • shadcn/ui コンポーネントをそのまま使用します
  • 変更ではなく、組み合わせによって拡張します
  • shadcn にない場合は、shadcn のプリミティブを使って構築します

3. 一貫したデザイン言語

  • shadcn のデザインパターンに従います
  • 意味的なバリアント(default、outline、destructive、ghost、link、secondary)を使用します
  • 一貫した余白のスケールを維持します
  • タイポグラフィの階層は shadcn に従います

4. カスタム UI コンポーネントを作成しない

  • カスタムのボタン、入力欄、カードなどを作成しないでください
  • shadcn コンポーネントを使用するか、shadcn のプリミティブを使って構築します
  • 例外:ビジネスロジックコンポーネント(UI プリミティブではないもの)

5. アクセシビリティを最優先する

  • shadcn は Radix UI を使用しているため、デフォルトでアクセシブルです
  • アクセシビリティ機能を上書きしないでください
  • キーボード操作とスクリーンリーダーでテストします
避けるべきアンチパターン

以下は絶対に行わないでください:

❌ 色のハードコード

// WRONG
<div style={{ backgroundColor: '#3b82f6' }}>

// RIGHT
<div className="bg-primary">

❌ 余白のハードコード

// WRONG
<div style={{ padding: '20px', margin: '10px' }}>

// RIGHT
<div className="p-5 m-2.5">

❌ UI プリミティブ用のカスタムスタイル付きコンポーネント

// WRONG
const CustomButton = styled.button`
  background: #3b82f6;
  padding: 8px 16px;
  border-radius: 6px;
`

// RIGHT
import { Button } from '@/components/ui/button'

❌ インラインスタイル

// WRONG
<div style={{ color: 'red', fontSize: '14px' }}>

// RIGHT
<div className="text-destructive text-sm">

❌ フォントのハードコード

// WRONG
<h1 style={{ fontFamily: 'Montserrat' }}>

// RIGHT
<h1 className="font-sans text-4xl font-bold">

❌ 絵文字アイコン(代わりに Lucide React アイコンを使用してください)

// WRONG
<span>❌ Delete</span>

// RIGHT
import { X } from 'lucide-react'
<Button variant="destructive">
  <X className="mr-2 h-4 w-4" />
  Delete
</Button>

❌ 任意の CSS 値

// WRONG
<div className="text-[#ff0000]">

// RIGHT
<div className="text-destructive">
ベストプラクティス

✅ 意味的な色名を使用する

// Use semantic CSS variable names
bg-background
text-foreground
bg-primary
text-primary-foreground
bg-secondary
text-muted-foreground
border-border

✅ Tailwind の余白スケールを使用する

// Consistent spacing using Tailwind
p-2, p-4, p-6, p-8  // padding
m-2, m-4, m-6, m-8  // margin
gap-2, gap-4        // flex/grid gap

✅ コンポーネントを組み合わせる

// Build complex UIs by composing shadcn components
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'

✅ MCP を使って探す

// Before building, ask MCP:
// "What shadcn component should I use for [use case]?"
// "Show me examples of shadcn [component]"

✅ 組み合わせによって拡張する

// Create higher-level components that compose shadcn
export function FeatureCard({ feature }: { feature: Feature }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{feature.title}</CardTitle>
      </CardHeader>
      <CardContent>
        <p className="text-muted-foreground">{feature.description}</p>
        <Button className="mt-4">Learn More</Button>
      </CardContent>
    </Card>
  )
}

参考ファイル

フレームワーク固有の移行:

コンポーネントとスタイリング:

レスポンシブデザインとアクセシビリティ:

コンポーネントテンプレートの例:

スクリプト:

  • ./scripts/analyze-codebase.py - コードベースの自動分析
  • ./scripts/detect-hardcoded-values.sh - アンチパターンの検出
  • ./scripts/init-nextjs-shadcn.sh - プロジェクトの初期化
  • ./scripts/generate-migration-report.py - 移行レポートの作成

公式ドキュメント:


新規プロジェクトのクイックスタート

新しい Next.js アプリを作成する場合(移行ではない場合):

  1. 初期化

    bash ./scripts/init-nextjs-shadcn.sh my-app
    
  2. MCP へのアクセスを確認

    npx shadcn@latest mcp init --client claude
    
  3. コンポーネントをインストール

    • MCP を使って必要なコンポーネントを探します
    • npx shadcn@latest add [component] でインストールします
  4. ベストプラクティスに従って構築

    • CSS 変数のみを使用します
    • shadcn コンポーネントを組み合わせます
    • 上記のデザイン原則に従います

概要

このスキルを使うと、設計原則を厳格に遵守しながら、フロントエンドを Next.js + shadcn/ui に体系的に移行できます。

  • 既存のコードベースを自動分析
  • 体系的な一括変換(一度に 5~10 個のコンポーネント)
  • ハードコードされた値を一切許容しない(CSS 変数のみ)
  • shadcn コンポーネントの検索に対応するMCP 統合
  • 複数のフレームワークに対応(React、Vue、Angular、vanilla JS)
  • 包括的な検証(テスト、アクセシビリティ、パフォーマンス)

結果: shadcn/ui のベストプラクティスに従い、一貫性のあるデザインシステム、完全なダークモード対応、アンチパターンのない、本番環境向けの品質を備えた Next.js アプリケーション。

コメント