# 機能設計書 43-プラグインAPI

## 概要

本ドキュメントは、Tailwind CSS v3互換のプラグインAPIを記述する。`buildPluginApi` 関数により構築されるPluginAPIオブジェクトは、`addUtilities`・`matchUtilities`・`addVariant`・`matchVariant`・`addBase`・`addComponents`等のAPIを提供し、v3プラグインがv4のDesignSystemにユーティリティ・バリアントを登録する仕組みを実現する。

### 本機能の処理概要

プラグインAPIは、v3形式のプラグインが利用するインターフェースをv4のDesignSystemの内部APIにマッピングするアダプター層である。

**業務上の目的・背景**：Tailwind CSS v3のプラグインエコシステムは `addUtilities`、`matchUtilities`、`addVariant` 等のAPIに依存している。v4ではDesignSystem内部のUtilities/Variantsクラスが直接操作されるが、v3プラグインとの後方互換性のためにこれらのAPIをラップして提供する必要がある。

**機能の利用シーン**：`@plugin` ディレクティブで読み込まれたv3プラグインのhandler関数に対してPluginAPIオブジェクトが引数として渡される。プラグイン作者は `api.addUtilities()`、`api.matchUtilities()` 等を呼び出してカスタムユーティリティやバリアントを登録する。

**主要な処理内容**：
1. `addBase`: ベースレイヤーにCSS-in-JSオブジェクトをASTに変換して追加
2. `addVariant`: 静的バリアントの登録（セレクタベース/CSS-in-JSベース）
3. `matchVariant`: 動的バリアントの登録（値パターンマッチ）
4. `addUtilities`: 静的ユーティリティの登録（CSS-in-JSオブジェクトからASTへ変換）
5. `matchUtilities`: 動的ユーティリティの登録（値解決・型推論・修飾子処理）
6. `addComponents`/`matchComponents`: `addUtilities`/`matchUtilities`のエイリアス
7. `theme`: テーマ値へのドット記法アクセス
8. `config`: 設定値へのキーパスアクセス
9. `prefix`: クラス名にプレフィックスを付与（v4では常にそのまま返す）

**関連システム・外部連携**：DesignSystemのUtilities/Variantsオブジェクトと直接連携する。

**権限による制御**：`referenceMode` がtrueの場合、`addBase` はスキップされる（ASTにノードを追加しない）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面には直接関連しない。プラグインのhandler関数内部で使用される |

## 機能種別

計算処理 / データ連携（v3 API to v4 DesignSystem アダプター）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| designSystem | DesignSystem | Yes | ユーティリティ/バリアント登録先 | 有効なDesignSystemインスタンス |
| ast | AstNode[] | Yes | ベースレイヤー追加先のAST | 有効なASTノード配列 |
| resolvedConfig | ResolvedConfig | Yes | 解決済み設定（テーマ・プラグイン情報） | 有効なResolvedConfig |
| featuresRef | { current: Features } | Yes | 使用機能の追跡用参照 | current プロパティに対してセッタ経由でOR代入 |
| referenceMode | boolean | Yes | referenceモードフラグ | true/false |
| src | SourceLocation / undefined | Yes | ソース位置情報（ASTノードのsrc設定用） | undefined可 |

### 入力データソース

- プラグインのhandler関数からの呼び出し
- CSS-in-JSオブジェクト（addUtilities等の引数）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PluginAPI | PluginAPI | プラグインAPIオブジェクト |

### 出力先

- DesignSystemのUtilitiesオブジェクト（static/functionalユーティリティ登録）
- DesignSystemのVariantsオブジェクト（static/functional/groupバリアント登録）
- ASTノード配列（addBaseで追加されるベースレイヤーCSS）

## 処理フロー

### 処理シーケンス

```
1. buildPluginApi呼び出し
   └─ PluginAPIオブジェクトの構築

2. addBase(css)
   ├─ referenceModeの場合はスキップ
   ├─ objectToAst(css): CSS-in-JSオブジェクトをASTに変換
   ├─ substituteFunctions: テーマ関数の置換
   └─ ast.push(@layer base): ベースレイヤーとしてASTに追加

3. addVariant(name, variant)
   ├─ バリアント名の検証
   ├─ :merge()を含む場合はスキップ（v4自動合成）
   ├─ 文字列/配列: designSystem.variants.static()
   └─ オブジェクト: designSystem.variants.fromAst()

4. matchVariant(name, fn, options)
   ├─ :merge()サンプルチェック
   ├─ designSystem.variants.group()内でfunctional登録
   ├─ ソート関数の設定
   └─ designSystem.variants.suggest()で補完候補登録

5. addUtilities(utilities)
   ├─ セレクタのパース・分割
   ├─ @keyframes処理
   ├─ セレクタからクラス名抽出
   ├─ テーマプレフィックスの適用
   └─ designSystem.utilities.static()で登録

6. matchUtilities(utilities, options)
   ├─ ユーティリティ名の検証
   ├─ 型情報の解析
   ├─ compileFn: 値解決・修飾子処理・色アルファ処理
   ├─ 負の値サポート
   └─ designSystem.utilities.functional()で登録
```

### フローチャート

```mermaid
flowchart TD
    A[buildPluginApi] --> B[PluginAPIオブジェクト生成]
    B --> C{プラグインhandler呼び出し}
    C --> D[addBase]
    C --> E[addVariant/matchVariant]
    C --> F[addUtilities/matchUtilities]
    C --> G[theme/config]
    D --> D1{referenceMode?}
    D1 -->|Yes| D2[スキップ]
    D1 -->|No| D3[objectToAst変換]
    D3 --> D4[ASTに@layer base追加]
    E --> E1[バリアント名検証]
    E1 --> E2[DesignSystem.variants登録]
    F --> F1[CSS-in-JS解析]
    F1 --> F2[クラス名抽出]
    F2 --> F3[DesignSystem.utilities登録]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | ユーティリティ名検証 | ユーティリティ名は`/^[a-z@][a-zA-Z0-9/%._-]*$/`に一致する必要がある | addUtilities/matchUtilities |
| BR-43-02 | バリアント名検証 | バリアント名はIS_VALID_VARIANT_NAMEパターンに一致する必要がある | addVariant/matchVariant |
| BR-43-03 | :merge無視 | v3の`:merge()`を含むバリアントはv4では自動合成されるため無視する | addVariant/matchVariant |
| BR-43-04 | referenceモード | referenceModeがtrueの場合、addBaseはASTにノードを追加しない | addBase |
| BR-43-05 | addComponents委譲 | addComponents/matchComponentsはaddUtilities/matchUtilitiesに委譲される | addComponents/matchComponents |
| BR-43-06 | 暗黙的カラー値 | 色型ユーティリティはinherit/transparent/currentcolorを暗黙的にサポート | matchUtilitiesでtype: 'color' |
| BR-43-07 | camelCase変換 | CSS-in-JSのcamelCaseプロパティ名はkebab-caseに自動変換される | objectToAst |
| BR-43-08 | 負の値サポート | supportsNegativeValuesオプションで`-{name}`ユーティリティが自動登録される | matchUtilities |

### 計算ロジック

- **型推論**: `inferDataType` を使用して任意値の型（color/length/number等）を推論し、ユーティリティの対応型と照合する
- **カラーアルファ**: `withAlpha(value, modifier)` で色値にアルファ修飾子を適用する
- **負の値計算**: `calc({value} * -1)` で値を反転する

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

該当なし（メモリ上のオブジェクト操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | addUtilitiesに無効なセレクタ名 | エラーメッセージを投げる |
| - | Error | matchUtilitiesに無効なユーティリティ名 | エラーメッセージを投げる |
| - | Error | addVariantに無効なバリアント名 | エラーメッセージを投げる |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- objectToAstによるCSS-in-JSからAST変換は各プラグイン呼び出し時に実行される
- matchUtilitiesのcompileFnは候補コンパイル時に遅延実行される

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

- プラグインのhandler関数はサードパーティコードを実行するため、信頼性の確認が必要

## 備考

- `objectToAst` はCSS-in-JSオブジェクトをASTに変換するヘルパーで、プラグインAPIの多くのメソッドで使用される
- `@slot` 値はCSS-in-JSの値として特別に処理され、バリアント内のスロット位置を指定する
- addComponents/matchComponentsの委譲により、v3のcomponents/utilitiesの区別がv4では統合される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | PluginAPI型定義（38-89行目）。提供されるAPI一覧 |
| 1-2 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | Plugin/PluginFn/PluginWithConfig/PluginWithOptions型（22-36行目） |
| 1-3 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | CssInJs型（556行目）。CSS-in-JSオブジェクトの型定義 |

**読解のコツ**: PluginAPI型には各メソッドのシグネチャが定義されている。CssInJsは再帰的なオブジェクト型で、CSSの階層構造を表現する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | buildPluginApi関数（93-554行目）。PluginAPIオブジェクトの構築 |

**主要処理フロー**:
1. **108行目**: apiオブジェクトの開始
2. **109-118行目**: addBase実装
3. **120-160行目**: addVariant実装
4. **161-263行目**: matchVariant実装
5. **266-348行目**: addUtilities実装
6. **350-509行目**: matchUtilities実装
7. **512-518行目**: addComponents/matchComponents
8. **520-524行目**: theme実装
9. **526-528行目**: prefix実装
10. **530-546行目**: config実装

#### Step 3: objectToAst変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | objectToAst関数（558-600行目）。CSS-in-JSからASTへの変換ロジック |

**主要処理フロー**:
- **573-585行目**: プリミティブ値の処理（camelCase→kebab-case変換、@slotの特別処理）
- **586-593行目**: 配列値の処理（同一プロパティの複数値）
- **594-596行目**: ネストされたオブジェクトの再帰処理

#### Step 4: matchUtilitiesの値解決を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | compileFn関数（364-473行目）。候補値の解決・型チェック・修飾子処理 |

**主要処理フロー**:
- **367-390行目**: 任意値の型チェック（inferDataType）
- **398-431行目**: 値の解決（DEFAULT/arbitrary/fraction/named/BARE_VALUE）
- **438-452行目**: 修飾子の解決
- **460-462行目**: カラーアルファの適用（withAlpha）

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

```
buildPluginApi(params)
    │
    ├─ api.addBase(css)
    │      ├─ objectToAst(css)
    │      ├─ substituteFunctions()
    │      └─ ast.push(@layer base)
    │
    ├─ api.addVariant(name, variant)
    │      ├─ parseVariantValue()
    │      └─ designSystem.variants.static/fromAst()
    │
    ├─ api.matchVariant(name, fn, options)
    │      ├─ designSystem.variants.group()
    │      │      └─ designSystem.variants.functional()
    │      └─ designSystem.variants.suggest()
    │
    ├─ api.addUtilities(utilities)
    │      ├─ objectToAst(css)
    │      ├─ SelectorParser.parse(name)
    │      └─ designSystem.utilities.static()
    │
    ├─ api.matchUtilities(utilities, options)
    │      ├─ compileFn()
    │      │      ├─ inferDataType()
    │      │      ├─ withAlpha()
    │      │      └─ objectToAst()
    │      ├─ designSystem.utilities.functional()
    │      └─ designSystem.utilities.suggest()
    │
    └─ api.theme/config/prefix()
           └─ createThemeFn() / resolvedConfig参照
```

### データフロー図

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

CSS-in-JS ─────────▶ objectToAst() ──────▶ ASTノード配列
オブジェクト                                       │
                                                   ▼
                                           designSystem.utilities/
                                           variants に登録
                                                   │
候補クラス名 ─────▶ compileFn() ──────────▶ ユーティリティCSS
(ビルド時)         (値解決・型推論)              (ASTノード配列)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | ソース | プラグインAPIの構築・CSS-in-JS変換 |
| plugin-functions.ts | `packages/tailwindcss/src/compat/plugin-functions.ts` | ソース | createThemeFn等のプラグイン用ヘルパー |
| utilities.ts | `packages/tailwindcss/src/utilities.ts` | ソース | Utilitiesクラス（static/functional登録先） |
| variants.ts | `packages/tailwindcss/src/variants.ts` | ソース | Variantsクラス（static/functional/group登録先） |
| design-system.ts | `packages/tailwindcss/src/design-system.ts` | ソース | DesignSystemインターフェース |
| selector-parser.ts | `packages/tailwindcss/src/selector-parser.ts` | ソース | セレクタの解析（addUtilities内） |
| candidate.ts | `packages/tailwindcss/src/candidate.ts` | ソース | Candidate型（compileFnの引数） |
| infer-data-type.ts | `packages/tailwindcss/src/utils/infer-data-type.ts` | ソース | 値の型推論 |
| apply.ts | `packages/tailwindcss/src/apply.ts` | ソース | substituteAtApply（ユーティリティ内の@apply処理） |
