fabrik_forms 0.1.0 copy "fabrik_forms: ^0.1.0" to clipboard
fabrik_forms: ^0.1.0 copied to clipboard

A clean, UI-agnostic form state and validation system for Flutter.

fabrik_forms #

A clean, UI-agnostic form state and validation system for Flutter.

pub.dev license platform


What's included #

API What it does
FabrikField<T> Holds a value, validators, and metadata (isTouched, isDirty, error, visibleError)
FabrikForm<T> Named field container with isValid, isDirty, values, errors, markAllTouched, reset
FabrikFormNotifier<T> ValueNotifier wrapper for reactive form state
FabrikFormBuilder<T> Declarative widget builder that rebuilds on form updates
RequiredValidator Ensures the field is not empty
EmailValidator Validates email format, optional or required
MinLengthValidator Enforces a minimum character count
MaxLengthValidator Enforces a maximum character count
PasswordValidator Configurable complexity rules (uppercase, digit, special char, min length)
UrlValidator Validates HTTP/HTTPS URLs, optional HTTPS-only mode
PhoneValidator Validates local and international phone number formats
RangeValidator Validates that a numeric value falls within an inclusive range

Installation #

dependencies:
  fabrik_forms: ^0.1.0
flutter pub get

Usage #

Setting up a form #

final formNotifier = FabrikFormNotifier<String>(
  FabrikForm({
    'email': FabrikField(
      value: '',
      validators: [const EmailValidator()],
    ),
    'password': FabrikField(
      value: '',
      validators: [
        const PasswordValidator(
          requireDigit: true,
          requireSpecialChar: true,
        ),
      ],
    ),
  }),
);

Building the UI #

FabrikFormBuilder<String>(
  formNotifier: formNotifier,
  builder: (context, form, get) {
    final emailField = get<String>('email');
    final passwordField = get<String>('password');

    return Column(
      children: [
        TextField(
          onChanged: (val) => formNotifier.update('email', val),
          decoration: InputDecoration(
            labelText: 'Email',
            errorText: emailField.visibleError,
          ),
        ),
        TextField(
          onChanged: (val) => formNotifier.update('password', val),
          obscureText: true,
          decoration: InputDecoration(
            labelText: 'Password',
            errorText: passwordField.visibleError,
          ),
        ),
        ElevatedButton(
          onPressed: () {
            if (formNotifier.isValid) {
              // submit formNotifier.values
            } else {
              formNotifier.markAllTouched(); // reveal all errors
            }
          },
          child: const Text('Sign In'),
        ),
      ],
    );
  },
);

Resetting a form #

// Restore all fields to initial values and clear touched/dirty state
formNotifier.reset();

Validators #

RequiredValidator #

RequiredValidator()
RequiredValidator(message: 'Name is required', trim: false)

EmailValidator #

EmailValidator()                          // required by default
EmailValidator(isRequired: false)         // optional — empty is valid
EmailValidator(invalidMessage: 'Bad email')

MinLengthValidator / MaxLengthValidator #

MinLengthValidator(min: 3)
MaxLengthValidator(max: 50, message: 'Keep it under 50 chars')

PasswordValidator #

PasswordValidator()                          // requires 8+ chars, non-empty
PasswordValidator(isRequired: false)         // optional password
PasswordValidator(
  minLength: 12,
  requireUppercase: true,
  requireDigit: true,
  requireSpecialChar: true,
)

UrlValidator #

UrlValidator()                          // accepts http and https
UrlValidator(requireHttps: true)        // https only
UrlValidator(isRequired: false)         // optional — empty is valid

PhoneValidator #

PhoneValidator()                        // required by default
PhoneValidator(isRequired: false)       // optional — empty is valid
// Accepts: +1 234 567 8900 · (123) 456-7890 · 123-456-7890 · 1234567890

RangeValidator #

RangeValidator(min: 1, max: 100)
RangeValidator(min: 0.0, max: 1.0, minMessage: 'Too low', maxMessage: 'Too high')

Custom validators #

class UsernameValidator extends FabrikValidator<String> {
  const UsernameValidator();

  @override
  String? call(String value) {
    if (value.contains(' ')) return 'No spaces allowed';
    return null;
  }
}

Field metadata #

Property Type Description
value T Current field value
error String? Validation error (always set, regardless of touch)
visibleError String? Error only exposed after the field is touched
isValid bool No active errors
isTouched bool User has interacted with the field
isDirty bool Value differs from the original

Documentation #

Full API reference and guides at fabriktool.com


Contributing #

Found a bug or have a suggestion? Open an issue or pull request on GitHub.

Maintainers #

2
likes
160
points
124
downloads

Publisher

verified publisherfabriktool.com

Weekly Downloads

A clean, UI-agnostic form state and validation system for Flutter.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on fabrik_forms