mcpField
F
flutter-bloc-forms

flutter-bloc-forms

github.com/dhruvanbhalara開発30147 回インストール8 週間前に更新
リポジトリ

flutter-bloc-forms について

BLoC を使った Flutter フォーム構成のガイドです。フォーム状態、検証、入力動作、送信フローに加え、検索や複数ステップ形式などのパターンを説明します。

主な機能

  1. 01専用 FormBloc による状態管理
  2. 02フィールド単位の検証とエラー
  3. 03ローカライズされた検証メッセージ
  4. 04入力とコントローラーのライフサイクル指針
  5. 05送信状態とフィードバック
  6. 06検索と複数ステップのフォームパターン

活用シーン

  1. 01検証付きサインアップフォームの構築
  2. 02送信失敗時の入力内容保持
  3. 03デバウンス付きフォーム検索の実装
  4. 04複数ステップのデータ入力

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dhruvanbhalara/skills --skill flutter-bloc-forms

インストール後、Claude Code で/flutter-bloc-formsを入力して読み込まれたか確認します。

詳細

BLoC によるフォームアーキテクチャ

  • フォームの状態は専用の FormBloc で管理します(ウィジェットの setState では管理しません)
  • 各フォームフィールドは BLoC の状態内のプロパティに対応します
  • UX 要件に応じて、フィールド変更時(リアルタイム)または送信時(バッチ)にバリデーションを行います
  • 送信フロー用に FormSubmitting、FormSuccess、FormError の状態を発行します

フォームイベント

  • FieldChanged(field, value): 状態内の単一フィールドを更新します
  • FormSubmitted: バリデーションと送信をトリガーします
  • FormReset: すべてのフィールドとエラーをクリアします

フォームの状態

  • すべてのフィールド値、フィールド単位のエラー、フォームのステータスを持つ単一の状態クラスを使用します:
    sealed class FormStatus { initial, submitting, success, failure }
    
  • フィールドエラー: フィールド名をキーとする Map<String, String?>(null は有効を意味します)

バリデーションのパターン

  • ドメイン層でバリデーションを行います(ウィジェットや BLoC では行いません)
  • String? を返す純粋なバリデータ関数を作成します(null = 有効、文字列 = エラーメッセージ):
    String? validateEmail(String value) =>
      value.contains('@') ? null : 'Invalid email';
    
  • バリデータを組み合わせます: String? validate(String v) => validateRequired(v) ?? validateEmail(v)
  • context.l10n を介してローカライズされたエラーメッセージを使用します: バリデーション文字列をハードコードしないでください

入力ウィジェット

  • 一貫したスタイリングのために、InputDecoration とともに TextFormField を使用します
  • 適切なキーボード動作のために常に textInputAction を設定します(next、done)
  • フィールドの種類に一致する keyboardType を常に設定します(emailAddress、phone、number)
  • 入力を制限するために inputFormatters を使用します(例: FilteringTextInputFormatter.digitsOnly)
  • テストからのアクセスのために、すべてのフォームフィールドに Key('feature_fieldName') を割り当てます
  • ログイン/サインアップフォームには AutofillHints を使用します(email、password、name)
  • 適切なタブ順序のために、フォームフィールドを Focus または FocusTraversalGroup でラップします

コントローラーのライフサイクル

  • TextEditingController は initState() で late final として宣言します: dispose() で破棄します
  • onChanged コールバックまたはコントローラーのリスナーを介して、コントローラーを BLoC と同期します

フォームの送信

  • FormStatus.submitting の間は送信ボタンを無効にして、二重送信を防ぎます
  • 各フィールドの下にインラインのフィールドエラーを表示します(トップレベルのエラーだけでなく)
  • 成功時: ナビゲートし、成功フィードバックを表示し、同じページにとどまる場合はフォームをリセットします
  • 失敗時: SnackBar またはインラインでエラーフィードバックを表示し、フォームデータはそのまま保持します

一般的なフォームのパターン

  • 検索: 検索イベントに debounce トランスフォーマーを使用します(300~500ms の遅延)
  • マルチステップ: 各ステップは 1 つの FormBloc 内の個別のフォーム状態であり、独立してバリデーションされます
  • 依存フィールド: on<FieldChanged> ハンドラーで依存フィールドのオプションを更新します(例: 国 → 都市)

コメント