# 機能設計書 70-コンポーネントライブラリ

## 概要

本ドキュメントは、Actualアプリケーションで使用されるコンポーネントライブラリの設計仕様を記載したものである。再利用可能なUIコンポーネントのライブラリを提供する。

### 本機能の処理概要

**業務上の目的・背景**：Actualアプリケーションでは、一貫したUIデザインと開発効率の向上が求められる。コンポーネントライブラリは、Button、View、Text、Tooltipなどの基本的なUIコンポーネントを提供し、アプリケーション全体でのデザインの一貫性と再利用性を実現する。react-aria-componentsをベースに、アクセシビリティ対応のコンポーネントを提供する。

**機能の利用シーン**：
- アプリケーション画面の構築時
- フォーム入力UI（Button, Input, Select等）
- 情報表示（Text, Tooltip, Popover等）
- レイアウト構成（View, SpaceBetween, Card等）

**主要な処理内容**：
1. 基本UIコンポーネントの提供（Button, View, Text等）
2. フォームコンポーネントの提供（Input, Select, Toggle等）
3. オーバーレイコンポーネントの提供（Popover, Tooltip, Menu等）
4. レイアウトコンポーネントの提供（SpaceBetween, Card, InlineField等）
5. アイコンコンポーネントの提供（v0, v1, v2）
6. テーマ・スタイルシステムの提供（theme, tokens, styles）

**関連システム・外部連携**：
- react-aria-components（アクセシビリティ対応UIライブラリ）
- @emotion/css（CSS-in-JS）
- Storybook（コンポーネントドキュメント）

**権限による制御**：特になし（UIライブラリ）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全画面共通 | 基盤機能 | すべての画面で使用されるUIコンポーネント |

## 機能種別

UIライブラリ / 開発基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| props | ComponentProps | Yes | 各コンポーネント固有のプロパティ | コンポーネント依存 |
| style | CSSProperties | No | カスタムスタイル | - |
| className | string | No | カスタムクラス名 | - |
| children | ReactNode | No | 子要素 | コンポーネント依存 |

### 入力データソース

- Reactコンポーネントプロパティ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReactElement | JSX.Element | レンダリングされたコンポーネント |

### 出力先

- DOM（ブラウザレンダリング）

## 処理フロー

### 処理シーケンス

```
1. コンポーネントがプロパティを受け取る
   └─ props展開

2. スタイルの計算
   └─ @emotion/css で動的スタイル生成

3. react-aria-components のラップ
   └─ アクセシビリティ対応

4. JSX レンダリング
   └─ 子要素とともに DOM に出力
```

### フローチャート

```mermaid
flowchart TD
    A[props受け取り] --> B[デフォルト値適用]
    B --> C[スタイル計算]
    C --> D{styleプロパティあり?}
    D -->|Yes| E[@emotion/css でクラス生成]
    D -->|No| F[デフォルトスタイル使用]
    E --> G[cx()でクラス結合]
    F --> G
    G --> H[react-aria-components使用]
    H --> I[JSXレンダリング]
    I --> J[DOM出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-001 | Viewベーススタイル | Viewコンポーネントはflexbox基本設定を持つ | View使用時 |
| BR-70-002 | テーマ変数使用 | 色はtheme変数を使用 | 全コンポーネント |
| BR-70-003 | アクセシビリティ | react-aria-componentsでアクセシビリティ対応 | 全インタラクティブコンポーネント |
| BR-70-004 | forwardRef | 全コンポーネントはref転送をサポート | 全コンポーネント |
| BR-70-005 | スタイル上書き | styleプロパティで個別スタイル上書き可能 | 全コンポーネント |

### 計算ロジック

特になし

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

特になし（UIライブラリ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | TypeScript型エラー | 不正なプロパティ型 | 型に合った値を渡す |

### リトライ仕様

特になし

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

特になし

## パフォーマンス要件

- コンポーネントレンダリング: 16ms以内（60fps維持）
- スタイル計算: 5ms以内

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

特になし（UIライブラリ）

## 備考

- @actual-app/componentsパッケージとして公開
- Storybookでコンポーネントカタログを提供
- アイコンはSVGR で生成

---

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

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

### 推奨読解順序

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

まず、パッケージ構成とエクスポート構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | package.json | `packages/component-library/package.json` | exports構成、依存関係 |
| 1-2 | tokens.ts | `packages/component-library/src/tokens.ts` | デザイントークン定義 |
| 1-3 | theme.ts | `packages/component-library/src/theme.ts` | テーマ変数定義 |
| 1-4 | styles.ts | `packages/component-library/src/styles.ts` | 共通スタイル定義 |

**読解のコツ**: exportsフィールドで各コンポーネントの個別インポートパスが定義されている。theme.tsのCSS変数はアプリケーション全体で使用される。

#### Step 2: 基本コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | View.tsx | `packages/component-library/src/View.tsx` | 基本レイアウトコンポーネント |
| 2-2 | Text.tsx | `packages/component-library/src/Text.tsx` | テキスト表示コンポーネント |
| 2-3 | Button.tsx | `packages/component-library/src/Button.tsx` | ボタンコンポーネント |

**主要処理フロー（View.tsx）**:
1. **7-12行目**: ViewProps型定義（className, style, nativeStyle, innerRef）
2. **14-33行目**: Viewコンポーネント実装
3. **20行目**: props展開
4. **26-29行目**: cxでクラス結合、cssでスタイル生成

**主要処理フロー（Button.tsx）**:
1. **17-29行目**: backgroundColor定義（variant別）
2. **30-44行目**: backgroundColorHover定義
3. **46-57行目**: borderColor定義
4. **59-70行目**: textColor定義
5. **131-137行目**: ButtonProps型定義
6. **139-185行目**: Buttonコンポーネント実装
7. **146-167行目**: useMemoでスタイル計算
8. **172-183行目**: ReactAriaButtonのラップ

#### Step 3: フォームコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Input.tsx | `packages/component-library/src/Input.tsx` | テキスト入力コンポーネント |
| 3-2 | Select.tsx | `packages/component-library/src/Select.tsx` | 選択コンポーネント |
| 3-3 | Toggle.tsx | `packages/component-library/src/Toggle.tsx` | トグルスイッチコンポーネント |

#### Step 4: オーバーレイコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Popover.tsx | `packages/component-library/src/Popover.tsx` | ポップオーバーコンポーネント |
| 4-2 | Tooltip.tsx | `packages/component-library/src/Tooltip.tsx` | ツールチップコンポーネント |
| 4-3 | Menu.tsx | `packages/component-library/src/Menu.tsx` | メニューコンポーネント |

#### Step 5: Storybookを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Button.stories.ts | `packages/component-library/src/Button.stories.ts` | Storybookストーリー定義 |
| 5-2 | main.ts | `packages/component-library/.storybook/main.ts` | Storybook設定 |

**主要処理フロー（Button.stories.ts）**:
- **6-17行目**: meta定義（title, component, parameters）
- **24-48行目**: Primaryストーリー
- **50-76行目**: Normalストーリー
- **78-100行目**: Bareストーリー

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

```
@actual-app/components (package.json exports)
    │
    ├─ ./button ──▶ Button.tsx
    │      │
    │      ├─ react-aria-components/Button
    │      ├─ @emotion/css
    │      ├─ ./styles.ts
    │      ├─ ./theme.ts
    │      └─ ./View.tsx
    │
    ├─ ./view ──▶ View.tsx
    │      │
    │      ├─ @emotion/css
    │      └─ ./styles.ts
    │
    ├─ ./text ──▶ Text.tsx
    │
    ├─ ./input ──▶ Input.tsx
    │      │
    │      └─ react-aria-components
    │
    ├─ ./select ──▶ Select.tsx
    │      │
    │      └─ react-aria-components
    │
    ├─ ./popover ──▶ Popover.tsx
    │      │
    │      └─ react-aria-components
    │
    ├─ ./tooltip ──▶ Tooltip.tsx
    │      │
    │      └─ react-aria-components
    │
    ├─ ./menu ──▶ Menu.tsx
    │      │
    │      └─ react-aria-components
    │
    ├─ ./space-between ──▶ SpaceBetween.tsx
    │
    ├─ ./card ──▶ Card.tsx
    │
    ├─ ./toggle ──▶ Toggle.tsx
    │
    ├─ ./theme ──▶ theme.ts
    │      └─ CSS変数定義
    │
    ├─ ./tokens ──▶ tokens.ts
    │      └─ デザイントークン
    │
    ├─ ./styles ──▶ styles.ts
    │      └─ 共通スタイル
    │
    └─ ./icons/* ──▶ icons/
           ├─ v0/
           ├─ v1/
           └─ v2/
```

### データフロー図

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

Reactコンポーネント ───┐
使用側                 │
                      ▼
              ┌─────────────────┐
              │ Component Props │
              │ - style         │
              │ - className     │
              │ - children      │
              │ - その他固有props│
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ デフォルト値適用 │
              │ variant = 'normal'等│
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ スタイル計算     │
              │ - theme変数参照  │
              │ - @emotion/css  │
              │ - useMemo       │
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ react-aria-     │
              │ components使用   │
              │ - Button        │
              │ - Popover       │
              │ - Tooltip       │
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ JSXレンダリング │
              │ - forwardRef    │
              │ - cx()でクラス結合│
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ DOM出力         │
              │ - アクセシビリティ│
              │   属性付与      │
              └─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| package.json | `packages/component-library/package.json` | 設定 | パッケージ設定、exports定義 |
| Button.tsx | `packages/component-library/src/Button.tsx` | ソース | ボタンコンポーネント |
| View.tsx | `packages/component-library/src/View.tsx` | ソース | 基本レイアウトコンポーネント |
| Text.tsx | `packages/component-library/src/Text.tsx` | ソース | テキストコンポーネント |
| Input.tsx | `packages/component-library/src/Input.tsx` | ソース | 入力コンポーネント |
| Select.tsx | `packages/component-library/src/Select.tsx` | ソース | 選択コンポーネント |
| Toggle.tsx | `packages/component-library/src/Toggle.tsx` | ソース | トグルコンポーネント |
| Popover.tsx | `packages/component-library/src/Popover.tsx` | ソース | ポップオーバーコンポーネント |
| Tooltip.tsx | `packages/component-library/src/Tooltip.tsx` | ソース | ツールチップコンポーネント |
| Menu.tsx | `packages/component-library/src/Menu.tsx` | ソース | メニューコンポーネント |
| Card.tsx | `packages/component-library/src/Card.tsx` | ソース | カードコンポーネント |
| SpaceBetween.tsx | `packages/component-library/src/SpaceBetween.tsx` | ソース | スペーシングコンポーネント |
| theme.ts | `packages/component-library/src/theme.ts` | ソース | テーマ変数 |
| tokens.ts | `packages/component-library/src/tokens.ts` | ソース | デザイントークン |
| styles.ts | `packages/component-library/src/styles.ts` | ソース | 共通スタイル |
| InitialFocus.ts | `packages/component-library/src/InitialFocus.ts` | ソース | フォーカス管理 |
| Button.stories.ts | `packages/component-library/src/Button.stories.ts` | Storybook | ボタンストーリー |
| main.ts | `packages/component-library/.storybook/main.ts` | Storybook | 設定 |
| preview.tsx | `packages/component-library/.storybook/preview.tsx` | Storybook | プレビュー設定 |
