# 機能設計書 45-テーマへの設定適用（applyConfigToTheme）

## 概要

本ドキュメントは、v3設定ファイルのthemeセクションをv4のThemeオブジェクトに変換・適用する `applyConfigToTheme` 関数の設計を記述する。

### 本機能の処理概要

applyConfigToThemeは、resolveConfigで解決されたユーザー設定のテーマ値をv4のDesignSystemのThemeオブジェクトにCSSカスタムプロパティとして追加する処理である。

**業務上の目的・背景**：v3の設定ファイルではJavaScriptオブジェクトでテーマ値を定義する（例: `colors.red.500: '#ef4444'`）。一方、v4ではテーマ値はCSSカスタムプロパティ（例: `--color-red-500`）として管理される。この機能は、v3形式のテーマ値をv4のCSSカスタムプロパティ名に変換し、DesignSystemのThemeに登録する。

**機能の利用シーン**：`upgradeToFullPluginSupport` の終盤で、resolvedUserConfigのテーマ値をDesignSystemに反映する際に呼び出される。

**主要な処理内容**：
1. 置き換えられたテーマキーの名前空間をデフォルトオプションでクリア
2. テーマ値を再帰的に走査し、プリミティブ値（string/number）を抽出
3. v3キーパス（例: `['colors', 'red', '500']`）をCSSプロパティ名（例: `color-red-500`）に変換
4. `<alpha-value>` プレースホルダーを `1` に置換
5. opacity名前空間の値を小数（0-1）からパーセント表記に変換
6. fontFamily.sans/monoのデフォルト値を更新

**関連システム・外部連携**：DesignSystemのThemeオブジェクトに直接値を追加する。

**権限による制御**：追加されるテーマ値はすべて `ThemeOptions.INLINE | ThemeOptions.REFERENCE | ThemeOptions.DEFAULT` オプションで登録される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面には直接関連しない |

## 機能種別

データ連携（v3テーマ → v4テーマ変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| designSystem | DesignSystem | Yes | テーマ値の追加先 | 有効なDesignSystem |
| resolvedConfig | ResolvedConfig | Yes | 解決済み設定（themeプロパティ使用） | 有効なResolvedConfig |
| replacedThemeKeys | Set<string> | Yes | 置き換えられたテーマキーの集合 | 有効なSetインスタンス |

### 入力データソース

- resolveConfigで生成されたresolvedUserConfig
- replacedThemeKeys（mergeThemeで追跡されたキー）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| theme | ResolvedConfig['theme'] | 処理済みテーマオブジェクト |

### 出力先

- DesignSystemのThemeオブジェクト（theme.add()で値を追加）

## 処理フロー

### 処理シーケンス

```
1. 置き換えキーの名前空間クリア
   └─ replacedThemeKeysの各キーについてtheme.clearNamespace()を実行

2. テーマ値の走査（themeableValues）
   ├─ プリミティブ値（string/number）の抽出
   ├─ タプル値の展開
   └─ 配列値の処理

3. 各値の変換・登録
   ├─ <alpha-value>の置換（'1'に）
   ├─ opacity値のパーセント変換
   ├─ keyPathToCssProperty: キーパスからCSSプロパティ名に変換
   └─ theme.add(): INLINE|REFERENCE|DEFAULTオプションで登録

4. fontFamilyの特別処理
   ├─ fontFamily.sansの値で--default-font-*を更新
   └─ fontFamily.monoの値で--default-mono-font-*を更新
```

### フローチャート

```mermaid
flowchart TD
    A[applyConfigToTheme開始] --> B[replacedThemeKeysの名前空間クリア]
    B --> C[themeableValuesでテーマ値走査]
    C --> D{値はstring/number?}
    D -->|No| E[スキップ]
    D -->|Yes| F[alpha-value置換]
    F --> G{opacity名前空間?}
    G -->|Yes| H[パーセント変換]
    G -->|No| I[keyPathToCssProperty変換]
    H --> I
    I --> J{CSSプロパティ名が有効?}
    J -->|No| E
    J -->|Yes| K[theme.add INLINE|REFERENCE|DEFAULT]
    K --> L{fontFamilyが設定されている?}
    L -->|Yes| M[--default-font-*更新]
    L -->|No| N[完了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-45-01 | alpha-value置換 | `<alpha-value>`を`1`に置換する | 値がstringの場合 |
| BR-45-02 | opacity変換 | 0-1の小数値を0%-100%のパーセント値に変換する | path[0]が'opacity' |
| BR-45-03 | container除外 | path[0]が'container'の場合はCSSプロパティ名に変換しない | container設定 |
| BR-45-04 | 名前空間変換 | v3名前空間をv4に変換（colors→color, screens→breakpoint等） | OLD_TO_NEW_NAMESPACE |
| BR-45-05 | 特殊DEFAULTキー | borderWidth.DEFAULT等はdefault-border-widthに変換される | SPECIAL_DEFAULT_KEYS |
| BR-45-06 | fontFamily特別処理 | fontFamily.sans/monoが設定されている場合、--default-font-*を更新する | fontFamily設定時 |
| BR-45-07 | DEFAULTオプション | 追加される値はすべてDEFAULTフラグ付きで、CSSの@themeで上書き可能 | 常時 |

### 計算ロジック

**v3名前空間 → v4変換マッピング（OLD_TO_NEW_NAMESPACE）**:
- animation → animate
- aspectRatio → aspect
- borderRadius → radius
- boxShadow → shadow
- colors → color
- containers → container
- fontFamily → font
- fontSize → text
- letterSpacing → tracking
- lineHeight → leading
- maxWidth → container
- screens → breakpoint
- transitionTimingFunction → ease

**keyPathToCssProperty変換例**:
- `['colors', 'red', '500']` → `color-red-500`
- `['fontSize', 'xs']` → `text-xs`
- `['borderWidth', 'DEFAULT']` → `default-border-width`

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

該当なし

## エラー処理

### エラーケース一覧

特定のエラーケースはなく、無効なキーパスは `null` を返してスキップされる。

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- themeableValues内のwalkは再帰的だが、テーマ設定の深さは通常浅い

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

該当なし

## 備考

- ThemeOptions.INLINE | ThemeOptions.REFERENCE | ThemeOptions.DEFAULT の組み合わせにより、値はCSSに直接出力されず、参照のみで使用され、@themeのCSS値で上書き可能となる
- IS_VALID_KEY正規表現 `/^[a-zA-Z0-9-_%/\.]+$/` で無効なキーをフィルタリング

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | OLD_TO_NEW_NAMESPACE定数（159-173行目）。v3→v4の名前空間マッピング |
| 1-2 | apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | SPECIAL_DEFAULT_KEYS定数（150-157行目）。特殊DEFAULTキーの変換先 |
| 1-3 | theme.ts | `packages/tailwindcss/src/theme.ts` | ThemeOptions列挙型（NONE/REFERENCE/INLINE/DEFAULT/STATIC） |

**読解のコツ**: keyPathToCssPropertyはv3のドット記法キーパスをCSSカスタムプロパティの名前部分に変換する。camelCaseからkebab-caseへの変換も行われる。

#### Step 2: メイン関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | applyConfigToTheme関数（22-110行目） |

**主要処理フロー**:
1. **27-32行目**: replacedThemeKeysの名前空間クリア
2. **34-61行目**: themeableValuesの走査と値の登録
3. **69-107行目**: fontFamilyの特別処理

#### Step 3: テーマ値の走査を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | themeableValues関数（112-148行目）。テーマオブジェクトの再帰走査 |

#### Step 4: キーパス変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | keyPathToCssProperty関数（177-240行目）。キーパスからCSSプロパティ名への変換 |

**主要処理フロー**:
- **184-185行目**: SPECIAL_DEFAULT_KEYSのチェック
- **188行目**: container除外
- **195-199行目**: OLD_TO_NEW_NAMESPACEによる名前空間変換
- **210行目**: タプルインデックス'1'の処理
- **228-229行目**: camelCaseからkebab-caseへの変換

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

```
applyConfigToTheme(designSystem, config, replacedThemeKeys)
    │
    ├─ designSystem.theme.clearNamespace()  [各replacedThemeKeyに対して]
    │      └─ keyPathToCssProperty([key])
    │
    ├─ themeableValues(config.theme)  [テーマ値走査]
    │      └─ walk(config, [], callback)  [再帰走査]
    │
    ├─ keyPathToCssProperty(path)  [各値に対して]
    │
    ├─ designSystem.theme.add()  [各値の登録]
    │
    └─ fontFamily特別処理
           ├─ resolveThemeValue(theme.fontFamily.sans)
           └─ designSystem.theme.add('--default-font-*', ...)
```

### データフロー図

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

ResolvedConfig.theme ──▶ themeableValues() ──▶ [path[], value]配列
                                │
                                ▼
replacedThemeKeys ─────▶ clearNamespace() ──▶ Theme名前空間クリア
                                │
                                ▼
                         keyPathToCssProperty() ──▶ CSSプロパティ名
                                │
                                ▼
                         theme.add() ──────────▶ Themeにエントリ追加
                                                 (INLINE|REFERENCE|DEFAULT)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apply-config-to-theme.ts | `packages/tailwindcss/src/compat/apply-config-to-theme.ts` | ソース | v3テーマ設定のv4テーマへの適用 |
| theme.ts | `packages/tailwindcss/src/theme.ts` | ソース | Themeクラス（add/clearNamespace/hasDefault） |
| resolve-config.ts | `packages/tailwindcss/src/compat/config/resolve-config.ts` | ソース | resolvedConfigの生成元 |
| apply-compat-hooks.ts | `packages/tailwindcss/src/compat/apply-compat-hooks.ts` | ソース | 呼び出し元（355行目） |
