# 機能設計書 71-デフォルトUIコンポーネント

## 概要

本ドキュメントは、Decap CMSの管理画面全体で共有されるデフォルトUIコンポーネント群（`decap-cms-ui-default`パッケージ）の機能設計を記述する。

### 本機能の処理概要

本機能は、CMS管理画面で繰り返し使用されるUIコンポーネントと、デザインシステムとしてのスタイル定数を一元的に提供する共有UIライブラリである。

**業務上の目的・背景**：CMS管理画面の各所で利用されるUI要素（ローダー、トグルスイッチ、ドロップダウン、アイコン、フィールドラベルなど）を個別に実装すると、一貫性の欠如やコードの重複が発生する。本パッケージはこれらを統一的に提供し、デザインの一貫性と開発効率を両立させる。

**機能の利用シーン**：CMS管理画面のすべての画面（ログイン画面、コレクション一覧画面、エントリ編集画面、ワークフロー画面、メディアライブラリ画面など）で使用される。ウィジェットの入力コントロールやプレビュー領域の構築にも利用される。

**主要な処理内容**：
1. **Loader**: ローディングスピナーの表示。アニメーション付きの回転インジケータと、5秒間隔で切り替わるテキストメッセージ表示をサポート
2. **Toggle**: トグルスイッチの提供。ブールウィジェット等で使用されるオン/オフ切替UI
3. **Dropdown / DropdownItem / DropdownCheckedItem**: ドロップダウンメニューの提供。react-aria-menubuttonベースのアクセシブルなメニューコンポーネント
4. **Icon**: SVGアイコンの表示。60種類以上のアイコンを提供し、サイズ（xsmall/small/medium/large）と方向（right/down/left/up）をサポート
5. **FieldLabel**: フォームフィールドのラベル表示。アクティブ/エラー状態に応じた色変更をサポート
6. **ListItemTopBar**: リストウィジェットの各アイテムのトップバー。折り畳み・ドラッグハンドル・削除ボタンを含む
7. **ObjectWidgetTopBar**: オブジェクトウィジェットのトップバー。折り畳み・型付きリストの追加UIを含む
8. **IconButton**: 円形のアイコンボタン。small/largeサイズとアクティブ/非アクティブ状態をサポート
9. **AuthenticationPage**: 認証ページのレイアウトコンポーネント。ロゴ・ログインボタン・エラーメッセージ・サイトへの戻りリンクを含む
10. **GoBackButton**: サイトへの戻りリンクボタン。ローカライズ対応
11. **WidgetPreviewContainer**: ウィジェットプレビュー領域のコンテナ
12. **GlobalStyles**: アプリケーション全体のグローバルCSS（box-sizing、フォント、カラー、リセットスタイル）
13. **スタイル定数群**: fonts、colorsRaw、colors、lengths、buttons、shadows、borders、transitions、effects、zIndex、reactSelectStyles等のデザイントークン

**関連システム・外部連携**：react-aria-menubutton（ドロップダウン）、react-transition-group（ローダーアニメーション）、@emotion/styled・@emotion/react（CSS-in-JS）と連携する。

**権限による制御**：UIコンポーネント自体には権限制御はない。利用側のコンポーネントで権限に基づいた表示制御が行われる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ログイン画面 | 主画面 | AuthenticationPageコンポーネントによるログインUI描画 |
| 2 | PKCE認証画面 | 主画面 | AuthenticationPageコンポーネントによるPKCE認証UI描画 |
| 3 | コレクション一覧画面 | 参照画面 | Icon、Dropdown、FieldLabel等による一覧画面UI構成 |
| 6 | エントリ編集画面 | 参照画面 | ListItemTopBar、ObjectWidgetTopBar、Toggle等のウィジェットUI |
| 8 | ワークフロー画面 | 参照画面 | Dropdown、Icon等によるワークフローUI構成 |
| 9 | メディアライブラリ画面 | 参照画面 | Loader、Icon等によるメディアライブラリUI構成 |
| 12 | ローディング画面 | 主画面 | Loaderコンポーネントによるローディング表示 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

各コンポーネントの主要なPropsを以下に示す。

**Loader**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| active | boolean | No | ローダーの表示/非表示 | - |
| children | node | No | 表示テキスト。文字列または配列 | - |

**Toggle**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string | No | HTML要素のID | - |
| active | boolean | No | 初期アクティブ状態 | - |
| onChange | function | No | トグル切替時のコールバック | - |

**Dropdown**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| renderButton | function | Yes | ボタン描画関数 | - |
| dropdownWidth | string | No | ドロップダウン幅（デフォルト: 'auto'） | - |
| dropdownPosition | string | No | 表示位置（'left'/'right'、デフォルト: 'left'） | - |
| dropdownTopOverlap | string | No | 上部オフセット（デフォルト: '0'） | - |

**Icon**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | string | Yes | アイコンタイプ名 | icons定義に存在する名前 |
| direction | string | No | 方向（'right'/'down'/'left'/'up'） | - |
| size | string | No | サイズ（'xsmall'/'small'/'medium'/'large'、デフォルト: 'medium'） | - |

**FieldLabel**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| isActive | boolean | No | アクティブ状態 | - |
| hasErrors | boolean | No | エラー状態 | - |

### 入力データソース

各コンポーネントのPropsは、利用側の親コンポーネントから渡される。スタイル定数はパッケージ内のstyles.jsで一元管理される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReactElement | JSX.Element | 各コンポーネントのレンダリング結果 |
| スタイル定数 | object | fonts, colors, lengths, buttons, shadows等のCSS値オブジェクト |

### 出力先

画面表示（DOMへのレンダリング）

## 処理フロー

### 処理シーケンス

```
1. コンポーネントのimport
   └─ 利用側が `import { Icon, Dropdown, ... } from 'decap-cms-ui-default'` でインポート
2. Props渡しによるコンポーネント描画
   └─ 親コンポーネントがPropsを指定してレンダリング
3. スタイル適用
   └─ Emotion CSS-in-JSによるスタイル計算とDOM適用
4. ユーザーインタラクション処理
   └─ onClick、onChange等のコールバック実行
```

### フローチャート

```mermaid
flowchart TD
    A[利用側コンポーネント] --> B{コンポーネント選択}
    B -->|ローダー| C[Loader: 回転アニメーション表示]
    B -->|トグル| D[Toggle: オン/オフ切替]
    B -->|ドロップダウン| E[Dropdown: メニュー展開]
    B -->|アイコン| F[Icon: SVGアイコン表示]
    B -->|フィールドラベル| G[FieldLabel: 状態別色変更]
    B -->|認証ページ| H[AuthenticationPage: レイアウト描画]
    C --> I[画面表示]
    D --> I
    E --> I
    F --> I
    G --> I
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-01 | Loaderテキスト切替 | 子要素が配列の場合、5秒間隔でテキストを順次切替表示する | children が配列の場合 |
| BR-71-02 | Toggle状態管理 | トグルは内部でuseStateによりアクティブ状態を管理し、onChangeコールバックで外部に通知する | 常時 |
| BR-71-03 | Icon方向回転 | directionプロパティに基づき、アイコンのデフォルト方向からの回転角度を計算する | direction指定時 |
| BR-71-04 | FieldLabel状態色 | hasErrors時は赤、isActive時は青、それ以外はデフォルト色を適用する | 常時 |
| BR-71-05 | Dropdown選択時閉じ | closeOnSelection（デフォルトtrue）に基づき、項目選択時にドロップダウンを自動的に閉じる | 常時 |

### 計算ロジック

**Icon回転角度計算**（Icon.js getRotation関数）:
- 方向定義: right=90, down=180, left=270, up=360
- 回転角度 = 指定方向の角度 - アイコンのデフォルト方向の角度

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

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

本機能はUIコンポーネントライブラリであり、データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | PropTypes警告 | 必須Propsが未指定の場合 | コンソール警告を出力 |
| - | アイコン未定義 | Icon typeに存在しないアイコン名を指定 | JavaScriptランタイムエラー（icons[type]がundefined） |

### リトライ仕様

リトライは不要（同期的なUI描画処理のみ）。

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

データベーストランザクションは存在しない。

## パフォーマンス要件

- 各コンポーネントの初回レンダリングは16ms以内に完了すること
- Loaderのアニメーションは60fpsを維持すること（CSSアニメーションにより実現）
- GlobalStylesはアプリケーション起動時に1度だけ適用される

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

- AuthenticationPageのlogoUrlにはユーザー指定のURLが渡されるため、img要素のsrc属性として使用される。XSSリスクはReactのエスケープ機構により軽減される
- DropdownのonSelection実行時、handler関数は利用側から渡される。悪意のあるハンドラが登録されないよう、利用側で検証が必要

## 備考

- 本パッケージはReact 19対応のため、componentDidMountでPropTypes.checkPropTypesを手動呼び出ししている
- styled-componentの代わりに@emotion/styledを使用している
- decap-cms-ui-defaultパッケージは名前付きエクスポートとDecapCmsUiDefaultオブジェクトの両方でエクスポートされる

---

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

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

### 推奨読解順序

#### Step 1: デザインシステム（スタイル定数）を理解する

まず、パッケージ全体のスタイル基盤を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | styles.js | `packages/decap-cms-ui-default/src/styles.js` | fonts、colorsRaw、colors、lengths、buttons、shadows等のデザイントークン定義を理解する |

**読解のコツ**:
- **7-29行目**: フォントスタック定義。primary（システムフォント）とmono（等幅フォント）
- **34-53行目**: colorsRaw - 基本カラーパレット定義
- **55-87行目**: colors - セマンティックカラー定義（colorsRawからの派生）
- **89-98行目**: lengths - レイアウト寸法定数（topBarHeight: 56px等）
- **183-258行目**: buttons - ボタンスタイルバリエーション（default, widget, medium, small, gray, green等）
- **419-431行目**: zIndex - z-index階層管理
- **433-525行目**: GlobalStyles - アプリケーション全体のグローバルCSS

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `packages/decap-cms-ui-default/src/index.js` | パッケージのエクスポート構造を理解する |

**主要処理フロー**:
- **1-16行目**: 各コンポーネントファイルからのインポート
- **17-32行目**: styles.jsからのスタイル定数インポート
- **34-67行目**: DecapCmsUiDefaultオブジェクトとしてのまとめエクスポート
- **68-102行目**: 名前付きエクスポート

#### Step 3: 主要コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Icon.js | `packages/decap-cms-ui-default/src/Icon.js` | SVGアイコンの表示ロジック。getRotation関数による方向回転計算 |
| 3-2 | Loader.js | `packages/decap-cms-ui-default/src/Loader.js` | ローディングスピナー。CSSアニメーションと5秒間隔テキスト切替 |
| 3-3 | Toggle.js | `packages/decap-cms-ui-default/src/Toggle.js` | トグルスイッチ。useStateによる状態管理とaria属性 |
| 3-4 | Dropdown.js | `packages/decap-cms-ui-default/src/Dropdown.js` | ドロップダウンメニュー。react-aria-menubuttonラッパー |
| 3-5 | FieldLabel.js | `packages/decap-cms-ui-default/src/FieldLabel.js` | フィールドラベル。状態別色変更ロジック |

**主要処理フロー**:
- **Icon.js 39-46行目**: getRotation - アイコン方向の回転角度計算
- **Icon.js 55-67行目**: Iconコンポーネント本体。IconWrapper内でSVG描画
- **Loader.js 80-89行目**: setAnimation - 5秒間隔のテキスト切替タイマー
- **Toggle.js 60-65行目**: handleToggle - 状態切替とonChangeコールバック実行
- **Dropdown.js 85-108行目**: Dropdownコンポーネント本体。StyledWrapperでreact-aria-menubuttonをラップ

#### Step 4: ウィジェット向けコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ListItemTopBar.js | `packages/decap-cms-ui-default/src/ListItemTopBar.js` | リストアイテムのトップバー。折り畳み・ドラッグ・削除UI |
| 4-2 | ObjectWidgetTopBar.js | `packages/decap-cms-ui-default/src/ObjectWidgetTopBar.js` | オブジェクトウィジェットのトップバー。型付き追加UI |
| 4-3 | WidgetPreviewContainer.js | `packages/decap-cms-ui-default/src/WidgetPreviewContainer.js` | プレビュー領域のコンテナ |

**主要処理フロー**:
- **ListItemTopBar.js 48-76行目**: 条件付きでcollapseボタン、ドラッグハンドル、削除ボタンを表示
- **ObjectWidgetTopBar.js 75-84行目**: renderAddUI - typesの有無で追加UIの切替（ドロップダウン or ボタン）

#### Step 5: 認証ページコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | AuthenticationPage.js | `packages/decap-cms-ui-default/src/AuthenticationPage.js` | 認証ページのレイアウト。ロゴ・ログインボタン・戻りリンク |
| 5-2 | GoBackButton.js | `packages/decap-cms-ui-default/src/GoBackButton.js` | サイトへの戻りリンクボタン |

**主要処理フロー**:
- **AuthenticationPage.js 43-48行目**: renderPageLogo - カスタムロゴURL有無でDecapロゴとカスタムロゴを切替
- **AuthenticationPage.js 77-105行目**: メインレイアウト。条件付きでrenderPageContent/renderButtonContentを描画

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

```
decap-cms-ui-default/src/index.js (エントリーポイント)
    |
    +-- styles.js (デザイントークン・グローバルスタイル)
    |
    +-- Icon.js
    |       +-- Icon/icons.js (アイコン定義マップ)
    |              +-- Icon/images/_index.js (SVGファイルインポート)
    |
    +-- Loader.js
    |       +-- styles.js (colors, zIndex)
    |
    +-- Toggle.js
    |       +-- styles.js (colors, colorsRaw, shadows, transitions)
    |
    +-- Dropdown.js
    |       +-- styles.js (colors, buttons, components, zIndex)
    |       +-- Icon.js
    |
    +-- FieldLabel.js
    |       +-- styles.js (colors, colorsRaw, transitions, text)
    |
    +-- ListItemTopBar.js
    |       +-- Icon.js
    |       +-- styles.js (colors, lengths, buttons)
    |
    +-- ObjectWidgetTopBar.js
    |       +-- Icon.js
    |       +-- Dropdown.js
    |       +-- styles.js (colors, buttons)
    |
    +-- IconButton.js
    |       +-- Icon.js
    |       +-- styles.js (buttons, colors, colorsRaw, shadows)
    |
    +-- AuthenticationPage.js
    |       +-- Icon.js
    |       +-- GoBackButton.js
    |       +-- styles.js (buttons, shadows)
    |
    +-- WidgetPreviewContainer.js
```

### データフロー図

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

Props (type, size, direction) --> Icon.js (getRotation計算)   --> SVGアイコンDOM要素
Props (active, children)      --> Loader.js (アニメーション)   --> ローディングスピナーDOM
Props (active, onChange)      --> Toggle.js (useState管理)     --> トグルスイッチDOM
Props (renderButton, children)--> Dropdown.js (aria-menu)     --> ドロップダウンDOM
Props (isActive, hasErrors)   --> FieldLabel.js (色決定)       --> ラベルDOM要素
スタイル定数                   --> styles.js                    --> CSS-in-JSスタイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `packages/decap-cms-ui-default/src/index.js` | ソース | パッケージエントリーポイント |
| styles.js | `packages/decap-cms-ui-default/src/styles.js` | ソース | デザイントークン・グローバルスタイル定義 |
| Icon.js | `packages/decap-cms-ui-default/src/Icon.js` | ソース | SVGアイコンコンポーネント |
| icons.js | `packages/decap-cms-ui-default/src/Icon/icons.js` | ソース | アイコン定義マップ |
| _index.js | `packages/decap-cms-ui-default/src/Icon/images/_index.js` | ソース | SVG画像インポート |
| Loader.js | `packages/decap-cms-ui-default/src/Loader.js` | ソース | ローディングスピナーコンポーネント |
| Toggle.js | `packages/decap-cms-ui-default/src/Toggle.js` | ソース | トグルスイッチコンポーネント |
| Dropdown.js | `packages/decap-cms-ui-default/src/Dropdown.js` | ソース | ドロップダウンメニューコンポーネント |
| FieldLabel.js | `packages/decap-cms-ui-default/src/FieldLabel.js` | ソース | フィールドラベルコンポーネント |
| ListItemTopBar.js | `packages/decap-cms-ui-default/src/ListItemTopBar.js` | ソース | リストアイテムトップバーコンポーネント |
| ObjectWidgetTopBar.js | `packages/decap-cms-ui-default/src/ObjectWidgetTopBar.js` | ソース | オブジェクトウィジェットトップバーコンポーネント |
| IconButton.js | `packages/decap-cms-ui-default/src/IconButton.js` | ソース | アイコンボタンコンポーネント |
| AuthenticationPage.js | `packages/decap-cms-ui-default/src/AuthenticationPage.js` | ソース | 認証ページレイアウトコンポーネント |
| GoBackButton.js | `packages/decap-cms-ui-default/src/GoBackButton.js` | ソース | サイトへの戻りリンクボタン |
| WidgetPreviewContainer.js | `packages/decap-cms-ui-default/src/WidgetPreviewContainer.js` | ソース | ウィジェットプレビューコンテナ |
