# 機能設計書 35-レイアウトコンポーネント

## 概要

本ドキュメントは、Liam DBアプリケーションで使用されるレイアウト用UIコンポーネントについて記述する。本機能は、Sidebar、Resizable、Tabs等のレイアウト制御コンポーネントを提供し、アプリケーションの画面構成を柔軟に管理する。

### 本機能の処理概要

**業務上の目的・背景**：複雑なWebアプリケーションでは、サイドバー、リサイズ可能なパネル、タブナビゲーション等のレイアウトコンポーネントが必要である。本機能は、react-resizable-panelsとRadix UI Tabsをベースに、再利用可能なレイアウトコンポーネントを提供する。

**機能の利用シーン**：
- サイドバーナビゲーション（Sidebar）- 折りたたみ/展開可能なナビゲーション
- リサイズ可能パネル（Resizable）- ドラッグでサイズ変更可能なパネル
- タブナビゲーション（Tabs）- コンテンツの切り替え

**主要な処理内容**：
1. Sidebar：展開/折りたたみ状態管理、キーボードショートカット（Cmd/Ctrl+B）
2. Resizable：react-resizable-panelsのラッパー、パネルグループとハンドル
3. Tabs：Radix UI Tabsのラッパー、タブリストとコンテンツ切り替え

**関連システム・外部連携**：
- react-resizable-panels：リサイズ可能パネル
- @radix-ui/react-tabs：タブUI
- @radix-ui/react-slot：asChildパターン
- neverthrow：Result型によるエラーハンドリング

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | スキーマ画面 | 利用画面 | Tabs、Resizableパネルによるレイアウト構成 |
| 14 | デザインセッション詳細画面 | 利用画面 | リサイズ可能なパネルレイアウト |

## 機能種別

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

## 入力仕様

### 入力パラメータ

#### Sidebar

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| open | boolean | Yes | 展開状態 | - |
| onOpenChange | function | No | 状態変更ハンドラ | - |
| collapsible | string | No | 折りたたみモード | offcanvas/icon/none |

#### Resizable

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| isResizing | boolean | Yes | リサイズ中フラグ | - |
| withHandle | boolean | No | ハンドル表示 | - |

#### Tabs

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| defaultValue | string | No | デフォルトタブ | - |
| value | string | No | 制御されたタブ値 | - |
| onValueChange | function | No | タブ変更ハンドラ | - |

### 入力データソース

- コンポーネントのprops
- キーボードイベント（Cmd/Ctrl+B）

## 出力仕様

### 出力データ

- レンダリングされたReact要素
- サイドバー状態（expanded/collapsed）

### 出力先

- DOM（ブラウザ画面）

## 処理フロー

### 処理シーケンス

#### Sidebarコンポーネント

```
1. SidebarProvider配置
   └─ Context、TooltipProvider、CSS変数設定
2. キーボードショートカット登録
   └─ Cmd/Ctrl+B で toggleSidebar
3. 状態管理
   └─ open状態に応じて data-state を設定
4. SidebarTrigger
   └─ トグルボタンとTooltip表示
5. Sidebar本体
   └─ SidebarHeader、SidebarContent、SidebarFooter配置
```

#### Resizableコンポーネント

```
1. ResizablePanelGroup配置
   └─ パネルグループのコンテナ
2. ResizablePanel配置
   └─ 各パネル、isResizingでアニメーション制御
3. ResizableHandle配置
   └─ ドラッグハンドル、オプションでGripVerticalアイコン
```

### フローチャート

```mermaid
flowchart TD
    A[SidebarProvider] --> B[Context作成]
    B --> C[キーボードイベント登録]
    C --> D[TooltipProvider配置]
    D --> E{ユーザー操作}
    E -->|Cmd/Ctrl+B| F[toggleSidebar]
    E -->|トリガークリック| F
    F --> G[onOpenChange呼び出し]
    G --> H[状態更新]
    H --> I[data-state更新]
    I --> J[UIレンダリング]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-01 | キーボードショートカット | Cmd/Ctrl+B でサイドバートグル | SidebarProvider内 |
| BR-35-02 | CSS変数設定 | --sidebar-width: 16rem、--sidebar-width-icon: 3rem | SidebarProvider |
| BR-35-03 | 状態属性 | data-state="expanded"/"collapsed" | Sidebar |
| BR-35-04 | リサイズアニメーション | isResizing=false時のみアニメーション | ResizablePanel |
| BR-35-05 | useSidebar検証 | Provider外での使用時はエラーを返す | useSidebar |

### 計算ロジック

サイドバー状態の決定：
```typescript
const state = open ? 'expanded' : 'collapsed'
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Context エラー | SidebarProviderの外でuseSidebarを使用 | neverthrowのResultでエラーを返却 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- リサイズ操作は60fpsでのスムーズな動作
- サイドバートグルは即座に反映

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

特になし。

## 備考

- neverthrowのResult型でuseSidebarのエラーハンドリング
- collapsibleモードでoffcanvas、icon、noneの3種類

---

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

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

### 推奨読解順序

#### Step 1: Sidebarコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Sidebar.tsx | `frontend/packages/ui/src/components/Sidebar/Sidebar.tsx` | Context管理、キーボードショートカット |

**主要処理フロー**:
- **26-28行目**: 定数定義（幅、ショートカットキー）
- **44-51行目**: useSidebar - neverthrowのResult型
- **53-123行目**: SidebarProvider - Context、キーボードイベント
- **173-206行目**: SidebarTrigger - トグルボタン

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Resizable.tsx | `frontend/packages/ui/src/components/Resizable/Resizable.tsx` | react-resizable-panelsラッパー |

**主要処理フロー**:
- **9-17行目**: ResizablePanelGroup
- **19-34行目**: ResizablePanel - isResizingでアニメーション制御
- **38-55行目**: ResizableHandle - GripVerticalアイコン

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

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

**主要処理フロー**:
- **6-14行目**: TabsRoot
- **16-24行目**: TabsList
- **26-34行目**: TabsTrigger
- **36-44行目**: TabsContent

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

```
Sidebar/
    ├─ SidebarProvider（Context、キーボードイベント）
    │      └─ TooltipProvider
    ├─ Sidebar
    │      ├─ SidebarHeader
    │      ├─ SidebarContent
    │      ├─ SidebarGroup
    │      │      ├─ SidebarGroupLabel
    │      │      └─ SidebarGroupContent
    │      │             └─ SidebarMenu
    │      │                    └─ SidebarMenuItem
    │      │                           └─ SidebarMenuButton
    │      └─ SidebarFooter
    └─ SidebarTrigger

Resizable/
    └─ ResizablePanelGroup（react-resizable-panels）
           ├─ ResizablePanel
           ├─ ResizableHandle（GripVerticalアイコン）
           └─ ResizablePanel

Tabs/（@radix-ui/react-tabs）
    └─ TabsRoot
           ├─ TabsList
           │      └─ TabsTrigger
           └─ TabsContent
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Sidebar.tsx | `frontend/packages/ui/src/components/Sidebar/Sidebar.tsx` | ソース | サイドバーコンポーネント |
| Sidebar.module.css | `frontend/packages/ui/src/components/Sidebar/Sidebar.module.css` | スタイル | サイドバースタイル |
| Resizable.tsx | `frontend/packages/ui/src/components/Resizable/Resizable.tsx` | ソース | リサイズ可能パネル |
| Resizable.module.css | `frontend/packages/ui/src/components/Resizable/Resizable.module.css` | スタイル | リサイズスタイル |
| Tabs.tsx | `frontend/packages/ui/src/components/Tabs/Tabs.tsx` | ソース | タブコンポーネント |
| BaseLayout.tsx | `frontend/packages/ui/src/components/BaseLayout/BaseLayout.tsx` | ソース | 基本レイアウト |
| Drawer.tsx | `frontend/packages/ui/src/components/Drawer/Drawer.tsx` | ソース | ドロワーコンポーネント |
