# 機能設計書 36-フィードバックコンポーネント

## 概要

本ドキュメントは、Liam DBアプリケーションで使用されるフィードバック用UIコンポーネントについて記述する。本機能は、Toast、Tooltip、Spinnerなどのユーザーフィードバックコンポーネントを提供し、アプリケーションの操作結果や状態をユーザーに伝達する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザー操作の結果やシステム状態を視覚的にフィードバックするコンポーネントは、UXの向上に不可欠である。本機能は、Radix UI Toastをベースにしたトースト通知、Radix UI Tooltipをベースにしたツールチップ、およびカスタムSVGによるローディングスピナーを提供する。

**機能の利用シーン**：
- Toast：操作成功/失敗の通知、警告表示
- Tooltip：ボタンやアイコンのヒント表示
- Spinner：ローディング状態の表示

**主要な処理内容**：
1. Toast：ステータス別（success/error/warning/info）の通知表示、複数表示位置（header/command-palette）
2. Tooltip：遅延表示（100ms）、ポータル経由でのレンダリング
3. Spinner：サイズ可変（12/14/16px）、回転アニメーション

**関連システム・外部連携**：
- @radix-ui/react-toast：トースト通知
- @radix-ui/react-tooltip：ツールチップ
- CSS Modules：スタイリング

**権限による制御**：
コンポーネント自体には権限制御は含まれない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 全画面 | 共通 | 利用画面 | ToastProvider経由での通知表示 |
| 12 | スキーマ画面 | 利用画面 | 操作成功/失敗時のトースト通知 |
| 16 | 設定画面 | 利用画面 | 組織名更新時のトースト通知 |

## 機能種別

UIコンポーネントライブラリ

## 入力仕様

### 入力パラメータ

#### Toast

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| title | string | Yes | トーストのタイトル | - |
| description | string | No | トーストの説明文 | - |
| status | ToastStatus | Yes | 通知ステータス | success/error/warning/info |

#### useToast

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| position | ToastPosition | No | 表示位置 | header/command-palette（デフォルト：header） |

#### Tooltip

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| delayDuration | number | No | 表示遅延（ms） | デフォルト100ms |

#### Spinner

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| size | string | No | スピナーサイズ | '12'/'14'/'16'（デフォルト：'16'） |

### 入力データソース

- コンポーネントのprops
- ToastContextからの関数呼び出し

## 出力仕様

### 出力データ

- レンダリングされたReact要素
- トースト通知の表示/非表示状態

### 出力先

- DOM（ブラウザ画面）
- トーストはRadix Portalを通じて固定位置に表示

## 処理フロー

### 処理シーケンス

#### Toastコンポーネント

```
1. ToastProvider配置
   └─ ToastContextの作成
2. ViewportProvider配置
   ├─ HeaderToastViewportProvider（右上固定）
   └─ CommandPaletteToastViewportProvider（中央下部）
3. useToast呼び出し
   └─ position引数で表示位置を選択
4. toast関数実行
   └─ ToastOptionsを渡して通知表示
5. アニメーション表示
   └─ slideInアニメーション（150ms）
6. 自動/手動クローズ
   └─ hideアニメーション（100ms）
```

#### Tooltipコンポーネント

```
1. TooltipProvider配置
   └─ delayDuration=100ms設定
2. TooltipRoot配置
   └─ ツールチップのルート
3. TooltipTrigger配置
   └─ ホバー/フォーカス対象要素
4. TooltipPortal配置
   └─ DOMツリー外にレンダリング
5. TooltipContent表示
   └─ fadeInアニメーション（150ms）
```

### フローチャート

```mermaid
flowchart TD
    A[ToastProvider] --> B[ToastContext作成]
    B --> C[HeaderViewportProvider]
    B --> D[CommandPaletteViewportProvider]
    C --> E[useToast'header']
    D --> F[useToast'command-palette']
    E --> G{toast関数呼び出し}
    F --> G
    G --> H[ToastItem作成]
    H --> I[isOpen: true]
    I --> J[slideInアニメーション]
    J --> K[トースト表示]
    K --> L{クローズ}
    L --> M[hideアニメーション]
    M --> N[isOpen: false]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | ステータス別スタイル | success/error/warning/infoで異なるカラースキーム | Toast |
| BR-36-02 | 表示位置 | headerは右上、command-paletteは中央下 | ToastViewport |
| BR-36-03 | 遅延表示 | TooltipProviderでdelayDuration=100ms | Tooltip |
| BR-36-04 | スピナーサイズ | 12/14/16pxの3サイズ | Spinner |
| BR-36-05 | トースト切り替え | 新しいトーストは前のトーストをクローズ後100ms後に表示 | useToastDisplay |

### 計算ロジック

トーストのステータス別スタイル決定：
```typescript
clsx(
  styles.wrapper,
  status === 'success' && styles.success,
  status === 'error' && styles.error,
  status === 'warning' && styles.warning,
  status === 'info' && styles.info,
)
```

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

本機能はUIコンポーネントのため、直接的なデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Context警告 | ToastProvider外でuseToastを使用 | 空の関数が返される（デフォルト値） |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- アニメーションは60fpsでスムーズに動作
- Spinnerの回転は1秒で1回転（linear）
- トースト切り替えは100msの遅延で実行

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

- XSS対策：titleとdescriptionはReactによりエスケープされる

## 備考

- useIdによるSpinnerのグラデーションID生成でSSR対応
- RadixのPortalにより、トーストはDOMの最上位に配置

---

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

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

### 推奨読解順序

#### Step 1: Toast型定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `frontend/packages/ui/src/components/Toast/types.ts` | ToastOptions、ToastPosition等の型定義 |

**主要処理フロー**:
- **1行目**: ToastStatus型（success/error/warning/info）
- **3-7行目**: ToastOptions型（title、description、status）
- **9行目**: ToastItem型（isOpen追加）
- **13行目**: ToastPosition型（header/command-palette）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Toast.tsx | `frontend/packages/ui/src/components/Toast/Toast.tsx` | Toast本体、Provider、Viewport |
| 2-2 | useToast.tsx | `frontend/packages/ui/src/components/Toast/useToast.tsx` | useToastフック |

**主要処理フロー**:
- **20-47行目**: Toast - RadixToast.Rootのラッパー、ステータス別スタイル
- **49-55行目**: ToastContext - headerToastとcommandPaletteToastの関数
- **57-66行目**: HeaderToastViewportProvider - 右上に固定
- **68-79行目**: CommandPaletteToastViewportProvider - 中央下部に固定
- **81-95行目**: useToastDisplay - トースト表示状態管理フック
- **97-132行目**: ToastProvider - Context、2つのViewport配置
- **5-13行目（useToast.tsx）**: useToast - positionに応じた関数を返す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Tooltip.tsx | `frontend/packages/ui/src/components/Tooltip/Tooltip.tsx` | Radix Tooltipラッパー |

**主要処理フロー**:
- **13-22行目**: TooltipContent - スタイル適用したContent
- **24-33行目**: TooltipProvider - delayDuration=100ms
- **34-36行目**: 各コンポーネントの再エクスポート

#### Step 4: Spinnerコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Spinner.tsx | `frontend/packages/ui/src/components/Spinner/Spinner.tsx` | SVGスピナー |

**主要処理フロー**:
- **6-54行目**: SVG - useIdでグラデーションID生成、LinearGradient定義
- **56-58行目**: Props型 - sizeのみ（'12'/'14'/'16'）
- **60-69行目**: Spinner - サイズ適用とCSS Moduleクラス

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

```
Toast/
    ├─ ToastProvider（Context提供）
    │      ├─ ToastContext.Provider
    │      ├─ HeaderToastViewportProvider
    │      │      └─ RadixToast.Provider
    │      │             ├─ Toast（条件付きレンダリング）
    │      │             └─ RadixToast.Viewport
    │      └─ CommandPaletteToastViewportProvider
    │             └─ RadixToast.Provider
    │                    ├─ Toast
    │                    └─ RadixToast.Viewport
    └─ useToast（headerToast/commandPaletteToast選択）

Tooltip/
    └─ TooltipProvider（@radix-ui/react-tooltip）
           └─ TooltipRoot
                  ├─ TooltipTrigger
                  └─ TooltipPortal
                         └─ TooltipContent

Spinner/
    └─ Spinner
           └─ SVG（LinearGradient、回転アニメーション）
```

### データフロー図

```
useToast呼び出し
       │
       ↓
┌──────────────────┐
│ ToastContext     │
│ useContext()     │
└────────┬─────────┘
         │
         ↓
┌──────────────────┐
│ position判定     │
│ 'header' or      │
│ 'command-palette'│
└────────┬─────────┘
         │
    ┌────┴────┐
    ↓         ↓
headerToast  commandPaletteToast
    │              │
    ↓              ↓
createToastItem関数
    │
    ↓
┌──────────────────┐
│ closeToastItem   │
│ (前のトースト)   │
└────────┬─────────┘
         │
         ↓ 100ms後
┌──────────────────┐
│ setToastItem     │
│ isOpen: true     │
└────────┬─────────┘
         │
         ↓
Toast表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Toast.tsx | `frontend/packages/ui/src/components/Toast/Toast.tsx` | ソース | トースト通知コンポーネント |
| useToast.tsx | `frontend/packages/ui/src/components/Toast/useToast.tsx` | ソース | useToastフック |
| types.ts | `frontend/packages/ui/src/components/Toast/types.ts` | ソース | 型定義 |
| Toast.module.css | `frontend/packages/ui/src/components/Toast/Toast.module.css` | スタイル | トーストスタイル |
| Tooltip.tsx | `frontend/packages/ui/src/components/Tooltip/Tooltip.tsx` | ソース | ツールチップコンポーネント |
| Tooltip.module.css | `frontend/packages/ui/src/components/Tooltip/Tooltip.module.css` | スタイル | ツールチップスタイル |
| Spinner.tsx | `frontend/packages/ui/src/components/Spinner/Spinner.tsx` | ソース | スピナーコンポーネント |
| Spinner.module.css | `frontend/packages/ui/src/components/Spinner/Spinner.module.css` | スタイル | スピナースタイル |
