# 機能設計書 65-カラーウィジェット

## 概要

本ドキュメントは、Decap CMSのカラーウィジェット（Color Widget）の機能設計を定義する。カラーウィジェットは、カラーピッカーによる色値入力機能を提供するUIコンポーネントである。

### 本機能の処理概要

カラーウィジェットは、ChromePickerコンポーネント（react-color）を使用したカラーピッカーとテキスト入力を組み合わせた色値入力ウィジェットである。HEX形式またはRGBA形式の色値を管理する。

**業務上の目的・背景**：Webサイトのテーマカラー、ブランドカラー、背景色などをCMSで管理する場合、色値を視覚的に選択できるカラーピッカーは不可欠である。テキスト入力のみでは色の確認が困難なため、視覚的なカラーピッカーを提供する。

**機能の利用シーン**：エントリ編集画面でフィールドタイプが`color`に設定されているフィールドに対して利用される。テーマ設定、ブランドカラー管理、カスタムスタイル設定などに使用される。

**主要な処理内容**：
1. カラースウォッチ（色見本）の表示とクリックによるカラーピッカー表示
2. ChromePickerによる色選択（HEX/RGBA）
3. テキスト入力による色値の直接入力（allowInput設定時）
4. 透明色対応（enableAlpha設定時）
5. 色値のクリア（allowInput=false時のみ）
6. 外側クリックによるカラーピッカーの閉じ処理

**関連システム・外部連携**：react-colorライブラリ（ChromePicker）、tinycolor2ライブラリ（色の検証）。

**権限による制御**：allowInputオプションにより、テキスト入力の可否を制御可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | エントリ編集画面 | 主画面 | カラーフィールドの編集 |
| 7 | エントリ新規作成画面 | 主画面 | カラーフィールドの入力 |

## 機能種別

UI入力コンポーネント / カラーピッカー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| field | ImmutableMap | Yes | フィールド定義（allowInput, enableAlpha等） | - |
| value | string | No | 色値（HEX/RGBA形式文字列） | デフォルトは空文字列 |
| onChange | function | Yes | 値変更コールバック | - |
| forID | string | No | フィールド一意識別子 | - |
| classNameWrapper | string | Yes | CSSクラス名ラッパー | - |
| setActiveStyle | function | Yes | アクティブスタイル設定関数 | - |
| setInactiveStyle | function | Yes | 非アクティブスタイル設定関数 | - |

### 入力データソース

- 画面入力: カラーピッカーでの色選択、テキスト入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value | string | 色値文字列（例: '#ff0000', 'rgba(255, 0, 0, 0.5)'） |

### 出力先

- Redux Store: エントリのフィールド値として保存

## 処理フロー

### 処理シーケンス

```
1. ウィジェット初期化
   └─ 現在の色値でカラースウォッチとテキスト入力を表示
2. カラースウォッチクリック
   └─ showColorPickerをトグルしてカラーピッカーを表示/非表示
3. 色選択
   └─ handleChangeでalpha < 1ならRGBA形式、そうでなければHEX形式で出力
4. テキスト入力（allowInput=true時）
   └─ input.onChangeで直接値を更新
5. クリア（allowInput=false時）
   └─ handleClearで空文字列を設定
6. 外側クリック
   └─ ClickOutsideDivのonClickでカラーピッカーを閉じる
```

### フローチャート

```mermaid
flowchart TD
    A[ColorControl表示] --> B[カラースウォッチ + テキスト入力]
    B --> C{操作}
    C -->|スウォッチクリック| D[カラーピッカー表示]
    D --> E[ChromePicker - 色選択]
    E --> F{alpha < 1?}
    F -->|Yes| G["onChange('rgba(...)')"]
    F -->|No| H["onChange(hex)"]
    C -->|テキスト入力| I["onChange(inputValue)"]
    C -->|クリアボタン| J["onChange('')"]
    C -->|外側クリック| K[カラーピッカー非表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-65-01 | 色形式自動判定 | alpha < 1の場合はRGBA形式（`rgba(r, g, b, a)`）、それ以外はHEX形式で出力 | 常時 |
| BR-65-02 | allowInput制御 | allowInputがfalseの場合、テキスト入力は読み取り専用になり、クリックでカラーピッカーを表示。クリアボタンが表示される | allowInputがfalse（デフォルト） |
| BR-65-03 | enableAlpha制御 | enableAlphaがtrue（デフォルトfalse）の場合、カラーピッカーにアルファチャンネル調整を表示 | enableAlphaがtrue |
| BR-65-04 | カラースウォッチ表示 | tinycolor.isValid()で色が有効な場合はその色を表示、無効な場合は白背景に'?'マーク表示 | 常時 |

### 計算ロジック

- 色形式変換: `color.rgb.a < 1 ? rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.rgb.a}) : color.hex`

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

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

該当なし（クライアントサイドのみの処理）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な色値 | tinycolor(value).isValid()がfalseの場合 | カラースウォッチに白背景と'?'マークを表示 |

### リトライ仕様

リトライ処理は行わない。

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

該当なし。

## パフォーマンス要件

- 特別なパフォーマンス要件なし。

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

- テキスト入力の値はReactのJSX経由で表示されるため、XSSリスクは低い。

## 備考

- カラーウィジェットにはschemaファイルが存在しない（スキーマ定義なし）
- チェッカーボード背景パターンにより透明色のプレビューに対応

---

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

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

### 推奨読解順序

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

カラーウィジェットの値は単純なstring型で、HEX形式（例: '#ff0000'）またはRGBA形式（例: 'rgba(255, 0, 0, 0.5)'）の文字列値を持つ。

**読解のコツ**: カラーウィジェットにはschemaファイルが存在しないため、プロパティの検証はreact-colorのChromePicker側で行われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `packages/decap-cms-widget-colorstring/src/index.js` | name='color'として登録。schemaがない点に注目 |

**主要処理フロー**:
1. **1-2行目**: ColorControlとColorPreviewをインポート
2. **4-10行目**: Widget関数でウィジェット定義を返却

#### Step 3: 制御コンポーネント（ColorControl）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ColorControl.js | `packages/decap-cms-widget-colorstring/src/ColorControl.js` | 178行の制御コンポーネント。handleChange()の色形式判定ロジックが核心 |

**主要処理フロー**:
- **79-87行目**: propTypes定義
- **93-95行目**: state初期値（showColorPicker: false）
- **101-103行目**: handleClick - カラーピッカー表示/非表示トグル
- **104-106行目**: handleClear - 色値のクリア
- **110-116行目**: handleChange - alpha < 1でRGBA形式、そうでなければHEX形式
- **121行目**: allowInput取得（デフォルトfalse）
- **137-145行目**: ColorSwatch - tinycolor.isValid()で色有効性判定
- **149-153行目**: ChromePicker - react-colorカラーピッカー描画
- **152行目**: disableAlpha - enableAlphaの反転

#### Step 4: プレビューコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ColorPreview.js | `packages/decap-cms-widget-colorstring/src/ColorPreview.js` | 値をそのままテキスト表示する簡素なプレビュー |

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

```
ColorControl (ColorControl.js)
    │
    ├─ render()
    │   ├─ ClearButton → handleClear()（allowInput=false時のみ）
    │   ├─ ColorSwatchBackground（チェッカーボード）
    │   ├─ ColorSwatch → handleClick()
    │   ├─ ChromePicker → handleChange()
    │   │   └─ ClickOutsideDiv → handleClose()
    │   └─ <input> → onChange(e.target.value)（allowInput=true時）
    │
    └─ handleChange(color)
        └─ alpha < 1 → rgba形式 / それ以外 → hex形式
```

### データフロー図

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

カラーピッカー ────▶ handleChange(color)
  (ChromePicker)        │
                       ▼
                  alpha < 1? ──▶ rgba(r, g, b, a)
                       │                │
                  alpha >= 1 ──▶ color.hex
                                        │
テキスト入力 ────────────────▶ onChange(string) ──▶ Redux Store
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `packages/decap-cms-widget-colorstring/src/index.js` | ソース | ウィジェット登録エントリーポイント |
| ColorControl.js | `packages/decap-cms-widget-colorstring/src/ColorControl.js` | ソース | カラー制御コンポーネント |
| ColorPreview.js | `packages/decap-cms-widget-colorstring/src/ColorPreview.js` | ソース | カラープレビューコンポーネント |
