flutter-ui-designlisted
Install: claude install-skill chenyynx/claudio
# Flutter UI 実装規約
## アーキテクチャ概要
SSOT (Single Source of Truth) + UDF (Unidirectional Data Flow) に基づく設計。
### データフローパターン
- **Path A (Query)**: Cubit/Bloc → Widget (BlocBuilder/BlocListener)
- サーバー状態、永続化データ、共有状態
- BlocProvider を通じて単方向に流れる
- **Path B (Command)**: Widget → Cubit method → State emit
- ユーザーアクション、API呼び出し
- Cubit のメソッド経由で状態を変更
- **Path C (Local)**: StatefulWidget / useState
- テキスト入力、スクロール位置、展開状態等の一時的UI状態
## Widget 分割ルール
### 禁止パターン
```dart
// NG: プライベートメソッドでのWidget分割
class MyScreen extends StatefulWidget {
Widget _buildHeader() { ... }
Widget _buildBody() { ... }
Widget _buildFooter() { ... }
}
```
### 推奨パターン
```dart
// OK: 独立したWidgetクラスに分割
class MyScreenHeader extends StatelessWidget { ... }
class MyScreenBody extends StatelessWidget { ... }
class MyScreenFooter extends StatelessWidget { ... }
```
### 分割の判断基準
- 20行以上のbuildメソッド内ブロック → 独立Widgetに
- 独自のCubitを持つ → 独立Widget + BlocProvider
- BlocBuilder を含む → 独立Widget
- 表示のみ → StatelessWidget
## 状態管理
### Cubit パターン
```dart
class ChatSessionCubit extends Cubit<ChatSessionState> {
ChatSessionCubit() : super(const ChatSessionState());
void sendMessage(String text) {
// Command (Path B)
emit(state.copyWith(/* ... */));
}
}
```
### BridgeCubit パターン(Stream購読)
```dart
class ConnectionCubit extends BridgeCubit<BridgeConnectionState> {
ConnectionCubit(super.initialState, super.stream);
}
```
### Freezed State
```dart
@freezed
class ChatSessionState with _$ChatSessionState {
const fac