# 機能設計書 81-Shade

## 概要

本ドキュメントは、Ghostの新しいデザインシステム「Shade」の機能設計を定義する。ShadeはShadCN/UI、Radix UI、TailwindCSSをベースとした、マイクロフロントエンド間で共有可能なUIコンポーネントライブラリである。

### 本機能の処理概要

Shadeは、Ghost管理画面およびフロントエンドアプリケーションで使用されるUIコンポーネント、デザイントークン、ユーティリティ関数を提供する統合デザインシステムである。

**業務上の目的・背景**：Ghost Adminおよび関連アプリケーション（admin-x-settings、posts、stats、activitypub等）において、一貫したユーザー体験と視覚的デザインを提供するために、再利用可能なコンポーネントライブラリが必要である。従来のadmin-x-design-systemを段階的に置き換え、より現代的なUIパターンを採用することを目的としている。

**機能の利用シーン**：
- 管理画面でのボタン、フォーム、ダイアログなどのUI構築
- 設定画面、投稿分析、統計ダッシュボードなどのReactアプリケーション開発
- ActivityPubやPortalなどの公開向けUIの構築
- 新規コンポーネント開発時のStorybookによるドキュメント・テスト

**主要な処理内容**：
1. UIコンポーネントの提供（Button、Input、Dialog、Card、Table等50種以上）
2. TailwindCSSプリセットによるデザイントークン管理（カラー、スペーシング、フォント）
3. ShadeProvider/ShadeAppによるテーマ管理（ダークモード対応）
4. ユーティリティ関数の提供（cn、formatUrl、formatNumber等）
5. アイコン・ロゴアセットの提供

**関連システム・外部連携**：
- @radix-ui/* - アクセシブルなプリミティブコンポーネント
- tailwindcss - ユーティリティファーストCSS
- class-variance-authority（CVA）- バリアント管理
- lucide-react - アイコンライブラリ
- recharts - チャートライブラリ
- react-hook-form + zod - フォームバリデーション

**権限による制御**：デザインシステムとしてのShadeには権限制御は存在しない。利用するアプリケーション側で適切な認証・認可を実装する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | デザインサンドボックス | 主画面 | UIコンポーネントのテスト・プレビュー |

## 機能種別

UIコンポーネントライブラリ / デザインシステム

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| darkMode | boolean | Yes | ダークモードの有効/無効 | - |
| className | string | No | 追加のCSSクラス | - |
| variant | string | No | コンポーネントのバリアント | コンポーネント定義による |
| size | string | No | コンポーネントのサイズ | コンポーネント定義による |

### 入力データソース

- 呼び出し元Reactコンポーネントからのprops
- TailwindCSSの設定ファイル（tailwind.config.cjs）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReactElement | JSX.Element | レンダリングされたUIコンポーネント |
| CSS Styles | string | Tailwindによって生成されたスタイル |

### 出力先

- DOMへのレンダリング
- ESモジュールとしてのエクスポート（es/index.js）

## 処理フロー

### 処理シーケンス

```
1. ShadeAppでアプリケーションをラップ
   └─ .shade CSSスコープの適用
2. ShadeProviderによるコンテキスト提供
   └─ ダークモード状態、フォーカス状態の管理
3. 個別コンポーネントの利用
   └─ CVAによるバリアント適用
   └─ cn()によるクラス名マージ
4. Toasterによる通知表示
   └─ ポータルを通じてdocument.bodyにレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[ShadeApp開始] --> B[ShadeProviderでラップ]
    B --> C[GlobalDirtyStateProvider]
    C --> D[子コンポーネントのレンダリング]
    D --> E{darkMode?}
    E -->|Yes| F[.darkクラス適用]
    E -->|No| G[ライトモード]
    F --> H[ToasterPortal]
    G --> H
    H --> I[DOM出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | CSSスコープ | すべてのスタイルは.shadeコンテナ内にスコープされる | 常時 |
| BR-81-02 | ダークモード | .darkクラスで切り替え、.light内は除外 | darkMode=true時 |
| BR-81-03 | クラスマージ | cn()関数でTailwindクラスをマージ | className指定時 |
| BR-81-04 | バリアント管理 | CVAでコンポーネントバリアントを定義 | バリアントあり時 |

### 計算ロジック

特になし（UIコンポーネントライブラリのため）

## データベース操作仕様

### 操作別データベース影響一覧

なし（UIライブラリのためDB操作なし）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | RenderError | コンポーネントレンダリング失敗 | ErrorBoundaryでキャッチ |
| - | ValidationError | propsの型不正 | TypeScriptコンパイル時に検出 |

### リトライ仕様

なし

## トランザクション仕様

なし（UIライブラリのため）

## パフォーマンス要件

- コンポーネントのバンドルサイズ最小化（tree-shakingサポート）
- 遅延ロードによる初期ロード時間の短縮

## セキュリティ考慮事項

- ユーザー入力のサニタイズは利用側アプリケーションで実施
- XSS対策はReactのデフォルト挙動に依存

## 備考

- ShadCN/UIのコンポーネントを追加する際は`npx shadcn@latest add <component>`を使用
- 既存コンポーネントの上書きは禁止

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tailwind.config.cjs | `apps/shade/tailwind.config.cjs` | デザイントークン（カラー、スペーシング、フォント）の定義 |
| 1-2 | styles.css | `apps/shade/styles.css` | グローバルスタイルとCSS変数の定義 |

**読解のコツ**: TailwindCSSの設定ファイルで、`theme.colors`でカラーパレット、`theme.extend`で追加設定を確認。`important: '.shade'`でCSSスコープが設定されている。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `apps/shade/src/index.ts` | すべてのエクスポートの集約ポイント |
| 2-2 | shade-app.tsx | `apps/shade/src/shade-app.tsx` | アプリケーションラッパーの実装 |

**主要処理フロー**:
1. **19-32行目**: ShadeAppコンポーネントの定義、darkModeプロップの処理
2. **20-23行目**: clsxによるクラス名の組み立て
3. **25-31行目**: ShadeProviderでchildrenをラップ

#### Step 3: コンテキストプロバイダを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | shade-provider.tsx | `apps/shade/src/providers/shade-provider.tsx` | ShadeContext、ToasterPortal、GlobalDirtyStateProviderの実装 |

**主要処理フロー**:
- **9-21行目**: ShadeContextTypeインターフェースとコンテキスト作成
- **33-67行目**: ToasterPortalコンポーネント（createPortalでdocument.bodyにレンダリング）
- **75-90行目**: ShadeProviderの実装

#### Step 4: UIコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | button.tsx | `apps/shade/src/components/ui/button.tsx` | CVAを使用したバリアント定義の代表例 |
| 4-2 | dialog.tsx | `apps/shade/src/components/ui/dialog.tsx` | Radix UIプリミティブの利用例 |

**主要処理フロー**（button.tsx）:
- **8-33行目**: buttonVariantsの定義（CVA使用）
- **41-61行目**: Buttonコンポーネント（forwardRef、Slot対応）

#### Step 5: ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | utils.ts | `apps/shade/src/lib/utils.ts` | cn関数、フォーマッター、チャートヘルパー |

**主要処理フロー**:
- **10-12行目**: cn関数（clsx + twMerge）
- **56-139行目**: formatUrl関数（URL正規化）
- **266-271行目**: formatNumber関数

### プログラム呼び出し階層図

```
ShadeApp
    │
    ├─ ShadeProvider
    │      ├─ ShadeContext.Provider
    │      │      └─ isAnyTextFieldFocused, darkMode 状態管理
    │      ├─ GlobalDirtyStateProvider
    │      │      └─ フォームダーティ状態の管理
    │      └─ ToasterPortal
    │             └─ Toaster (sonner)
    │
    └─ UI Components
           ├─ Button (CVA variants)
           ├─ Dialog (Radix UI)
           ├─ Input, Textarea
           ├─ Card, Table
           └─ ... (50+ components)
```

### データフロー図

```
[入力]               [処理]                    [出力]

Props           ───▶ CVA Variants          ───▶ className
  (variant,          (class-variance-
   size, etc)         authority)

className       ───▶ cn() merge            ───▶ Tailwind classes
  (custom)           (clsx + twMerge)

darkMode        ───▶ ShadeContext          ───▶ .dark class toggle
  (boolean)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| package.json | `apps/shade/package.json` | 設定 | パッケージ定義、依存関係 |
| tailwind.config.cjs | `apps/shade/tailwind.config.cjs` | 設定 | デザイントークン定義 |
| index.ts | `apps/shade/src/index.ts` | ソース | エクスポート集約 |
| shade-app.tsx | `apps/shade/src/shade-app.tsx` | ソース | アプリケーションラッパー |
| shade-provider.tsx | `apps/shade/src/providers/shade-provider.tsx` | ソース | コンテキストプロバイダ |
| utils.ts | `apps/shade/src/lib/utils.ts` | ソース | ユーティリティ関数 |
| button.tsx | `apps/shade/src/components/ui/button.tsx` | ソース | ボタンコンポーネント |
| dialog.tsx | `apps/shade/src/components/ui/dialog.tsx` | ソース | ダイアログコンポーネント |
| styles.css | `apps/shade/styles.css` | スタイル | グローバルスタイル |
| AGENTS.md | `apps/shade/AGENTS.md` | ドキュメント | 開発ガイドライン |
