flutter-bloc-forms

Manage form state, validation, and input handling through dedicated FormBlocs. Use when building forms with real-time validation, multi-step flows, or complex input patterns like search debouncing.

dhruvanbhalara/skills127 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: flutter-bloc-forms
description: Manage form state, validation, and input handling through dedicated FormBlocs. Use when building forms with real-time validation, multi-step flows, or complex input patterns like search debouncing.
license: MIT
---

# Form Architecture with BLoC

-   Manage form state in a dedicated `FormBloc` — NOT in widget `setState`
-   Each form field maps to a property in the BLoC state
-   Validate on field change (real-time) or on submit (batch) depending on UX requirements
-   Emit `FormSubmitting`, `FormSuccess`, `FormError` states for submission flow

## Form Events

-   `FieldChanged(field, value)` — update a single field in state
-   `FormSubmitted` — trigger validation and submission
-   `FormReset` — clear all fields and errors

## Form State

-   Use a single state class with all field values, field-level errors, and form status:
    ```dart
    sealed class FormStatus { initial, submitting, success, failure }
    ```
-   Field errors: `Map<String, String?>` keyed by field name — `null` means valid

# Validation Patterns

-   Validate in the domain layer — NOT in widgets or BLoCs
-   Create pure validator functions that return `String?` (null = valid, string = error message):
    ```dart
    String? validateEmail(String value) =>
      value.contains('@') ? null : 'Invalid email';
    ```
-   Compose validators: `String? validate(String v) => validateRequired(v) ?? validateEmail(v)`
-   Use localized error messages via `context.l10n` — no hardcoded validation strings

# Input Widgets

-   Use `TextFormField` with `InputDecoration` for consistent styling
-   Always set `textInputAction` for proper keyboard behavior (`next`, `done`)
-   Always set `keyboardType` matching the field type (`emailAddress`, `phone`, `number`)
-   Use `inputFormatters` to restrict input (e.g., `FilteringTextInputFormatter.digitsOnly`)
-   Assign `Key('feature_fieldName')` to every form field for test access
-   Use `AutofillHints` for login/signup forms (email, password, name)
-   Wrap form fields with `Focus` or `FocusTraversalGroup` for proper tab order

# Controller Lifecycle

-   Declare `TextEditingController` as `late final` in `initState()` — dispose in `dispose()`
-   Sync controllers to BLoC via `onChanged` callback or controller listener

# Form Submission

-   Disable submit button while `FormStatus.submitting` to prevent double-submission
-   Show inline field errors below each field — not just a top-level error
-   On success: navigate, show success feedback, and reset form if staying on same page
-   On failure: show error feedback via `SnackBar` or inline, keep form data intact

# Common Form Patterns

-   **Search**: Use `debounce` transformer on search events (300-500ms delay)
-   **Multi-step**: Each step is a separate form state within one `FormBloc`, validated independently
-   **Dependent fields**: Update dependent field options in `on<FieldChanged>` handler (e.g., country → city)

More Mobile skills

← All Mobile skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY