# 通知設計書 13-無効なdarkMode variant設定警告

## 概要

本ドキュメントは、Tailwind CSSの互換性レイヤーにおいて、darkModeの設定で`variant`モードを使用する際にセレクタが未指定、またはセレクタに`&`が含まれない場合に`console.warn`で警告を出力する通知の設計を記述する。

### 本通知の処理概要

darkModeプラグインの初期化時に設定値を検証し、不正なvariant設定が検出された場合に開発者に対して設定の修正方法を含む警告メッセージを出力する処理である。

**業務上の目的・背景**：Tailwind CSSのdarkModeには複数のモード（`media`、`selector`、`variant`、`class`）が存在する。`variant`モードでは、カスタムセレクタを指定する必要があるが、デフォルトの`.dark`セレクタのまま使用したり、`&`（親セレクタ参照）を含まないセレクタを使用すると正しく動作しない。この警告により、開発者は設定ミスを早期に発見し、darkModeの動作不良を防止できる。

**通知の送信タイミング**：CSSコンパイル時にdarkModeプラグインが初期化される際、設定値の検証フェーズで送信される。具体的には`darkModePlugin`関数の実行時に、`variant`モードのフォーマット配列の各要素をチェックする。

**通知の受信者**：Tailwind CSSを設定・使用している開発者。コンソール（stderr）を通じて警告が表示される。

**通知内容の概要**：セレクタ未指定時は「セレクタを提供する必要がある」旨のメッセージと設定例。`&`未含有時は「セレクタに`&`を含める必要がある」旨のメッセージと設定例が出力される。

**期待されるアクション**：開発者はTailwind CSSの設定ファイル（tailwind.config.js等）のdarkMode設定を修正し、適切なセレクタを指定する。例：`darkMode: ["variant", ".your-selector &"]`

## 通知種別

コンソール警告（console.warn / stderr）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（console.warn による即時出力） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

`console.warn`による標準エラー出力への直接出力。動的な送信先決定ロジックは存在しない。

## 通知テンプレート

### メール通知の場合

該当なし（コンソール警告のみ）

### 本文テンプレート

パターン1: セレクタ未指定（デフォルト`.dark`のまま）:
```
When using `variant` for `darkMode`, you must provide a selector.
Example: `darkMode: ["variant", ".your-selector &"]`
```

パターン2: セレクタに`&`が含まれない:
```
When using `variant` for `darkMode`, your selector must contain `&`.
Example `darkMode: ["variant", ".your-selector &"]`
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| format | チェック対象のセレクタ文字列 | darkMode設定配列の第2要素 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| プラグイン初期化 | darkModePlugin実行 | mode === 'variant' かつ format === '.dark' | セレクタ未指定（23行目） |
| プラグイン初期化 | darkModePlugin実行 | mode === 'variant' かつ format に '&' が含まれない | セレクタ不正（26-28行目） |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| mode が 'variant' でない場合 | media、selector、class等の他モードでは検証しない |
| selector が関数型の場合 | typeof selector === 'function' の場合はフォーマット配列化をスキップ |
| セレクタが適切な場合 | '.dark'でなく、かつ'&'を含むセレクタの場合はスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[darkModePlugin初期化] --> B{mode === 'variant'?}
    B -->|No| Z[他モードの処理]
    B -->|Yes| C[formats配列を構成]
    C --> D{formats が配列?}
    D -->|No| Z2[関数の場合スキップ]
    D -->|Yes| E[各formatをチェック]
    E --> F{format === '.dark'?}
    F -->|Yes| G[console.warn: セレクタ未指定]
    F -->|No| H{format に '&' を含む?}
    H -->|Yes| I[チェック通過]
    H -->|No| J[console.warn: '&'未含有]
    G --> K[mode = false に設定]
    J --> K
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| セレクタ未指定 | variant モードでデフォルト'.dark'セレクタのまま | カスタムセレクタを指定 |
| '&'未含有 | variant モードのセレクタに'&'が含まれない | セレクタに'&'を追加 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（警告のみ。ただしmodeがfalseに設定されdark variantが無効化される） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（CSSコンパイル時に随時出力）

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

設定値のセレクタ文字列のみが出力に関連するため、機密情報の漏洩リスクはない。

## 備考

- 警告が発せられた場合、`mode`が`false`に設定され、darkModeのvariant登録が実質的に無効化される（22行目、27行目）
- darkModeの設定は配列形式`[mode, selector]`またはモード文字列のみで指定可能
- `variant`モードのセレクタは配列・関数・文字列の3形式をサポートする（11-17行目）
- 関数形式のセレクタの場合はこの検証は適用されない

---

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

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

### 推奨読解順序

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

darkMode設定の構造と型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dark-mode.ts | `packages/tailwindcss/src/compat/dark-mode.ts` | 5-6行目: darkMode設定の分解（mode, selector） |
| 1-2 | types.ts | `packages/tailwindcss/src/compat/config/types.ts` | ResolvedConfig['darkMode']の型定義 |

**読解のコツ**: darkMode設定は`[mode, selector]`の配列形式または単一のモード文字列で表現される。6行目の`Array.isArray(darkMode) ? darkMode : [darkMode]`がその変換処理。

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

darkModeプラグイン関数がエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dark-mode.ts | `packages/tailwindcss/src/compat/dark-mode.ts` | 4行目: `darkModePlugin`関数の定義 |

**主要処理フロー**:
1. **5行目**: config('darkMode')で設定値を取得
2. **6行目**: 配列分解で[mode, selector]を取得
3. **8行目**: mode === 'variant'の場合の処理分岐
4. **11-17行目**: selectorの型に応じてformats配列を構成
5. **19-31行目**: formats配列の各要素を検証

#### Step 3: 警告出力ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dark-mode.ts | `packages/tailwindcss/src/compat/dark-mode.ts` | 19-31行目: formatsの検証と警告出力 |

**主要処理フロー**:
- **20-25行目**: formatが'.dark'の場合、modeをfalseに設定し、セレクタ未指定の警告を出力
- **26-30行目**: formatに'&'が含まれない場合、modeをfalseに設定し、'&'未含有の警告を出力

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

```
darkModePlugin({ addVariant, config }) [dark-mode.ts:4]
    |
    +-- config('darkMode', null) [dark-mode.ts:5]
    |
    +-- [mode === 'variant'] の場合
    |       |
    |       +-- formats配列構成 [dark-mode.ts:11-17]
    |       |
    |       +-- formats検証ループ [dark-mode.ts:19-31]
    |               |
    |               +-- format === '.dark' -> console.warn() [dark-mode.ts:23-25]
    |               |
    |               +-- !format.includes('&') -> console.warn() [dark-mode.ts:28-30]
    |
    +-- addVariant('dark', ...) [dark-mode.ts:38-50]
```

### データフロー図

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

tailwind.config.js    --->  config('darkMode')   --->  [mode, selector]
  darkMode設定                   |
                                v
                          variant検証
                                |
                          [不正な場合]
                                |
                                v
                          console.warn()    --->  stderr: 警告メッセージ
                          mode = false      --->  dark variant 無効化
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dark-mode.ts | `packages/tailwindcss/src/compat/dark-mode.ts` | ソース | darkModeプラグインの定義・設定検証・警告出力 |
| types.ts | `packages/tailwindcss/src/compat/config/types.ts` | ソース | ResolvedConfig型定義（darkMode設定の型） |
| plugin-api.ts | `packages/tailwindcss/src/compat/plugin-api.ts` | ソース | PluginAPI型定義（addVariant, config関数） |
