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

Flutter form widgets backed by Zema schemas. Surgical per-field rebuilds, isTouched UX, auto-focus on first error, and a form-level error banner.

zema_forms #

Flutter form widgets backed by Zema schemas.

  • Surgical per-field rebuilds: only the field in error rebuilds on each keystroke.
  • "First contact" UX: errors appear after the field loses focus or the form is submitted, never on the first character.
  • Auto-focus: failed submit() moves focus to the first field in error automatically.
  • Form-level error banner via submitErrors for hidden or conditional fields.
  • Works with Flutter's native Form widget (zero migration cost).

Installation #

dependencies:
  zema: ^0.5.0
  zema_forms: ^0.1.0

Quick start #

import 'package:zema/zema.dart';
import 'package:zema_forms/zema_forms.dart';

final _schema = z.object({
  'email': z.string().email(),
  'password': z.string().min(8),
});

class LoginForm extends StatefulWidget {
  const LoginForm({super.key});

  @override
  State<LoginForm> createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> {
  late final _ctrl = ZemaFormController(schema: _schema);

  @override
  void dispose() {
    _ctrl.dispose();
    super.dispose();
  }

  void _onSubmit() {
    final data = _ctrl.submit();
    if (data != null) {
      // data is Map<String, dynamic> with validated values
    }
  }

  @override
  Widget build(BuildContext context) {
    return ZemaForm(
      controller: _ctrl,
      child: Column(
        children: [
          ZemaTextField(
            field: 'email',
            decoration: const InputDecoration(labelText: 'Email'),
            keyboardType: TextInputType.emailAddress,
          ),
          ZemaTextField(
            field: 'password',
            decoration: const InputDecoration(labelText: 'Password'),
            obscureText: true,
          ),
          ElevatedButton(
            onPressed: _onSubmit,
            child: const Text('Sign in'),
          ),
        ],
      ),
    );
  }
}

Error visibility #

Errors are validated on every keystroke but shown only when:

  • The field has lost focus at least once (isTouched), or
  • submit() has been called (isSubmitted).

This prevents showing "Email invalide" after the user types the first character.

Form-level error banner #

When a form has conditional or hidden fields, pair submit() with a banner that reads submitErrors:

ValueListenableBuilder<List<ZemaIssue>>(
  valueListenable: _ctrl.submitErrors,
  builder: (context, issues, _) {
    if (issues.isEmpty) return const SizedBox.shrink();
    return Text('${issues.length} field(s) require attention.');
  },
)

Native Form bridge #

TextFormField(
  controller: _ctrl.controllerFor('email'),
  validator: _ctrl.validatorFor('email'),
)

Numeric fields #

TextField always produces a String. Use the coercion layer for numeric fields:

z.object({
  'age': z.coerce().integer(min: 0, max: 150),
  'price': z.coerce().decimal(),
})

API reference #

Member Description
ZemaFormController(schema:) Create a controller for the given ZemaObject
controllerFor(field) TextEditingController for the field
errorsFor(field) ValueNotifier<List<ZemaIssue>> for per-field errors
touchedFor(field) ValueNotifier<bool>true after field loses focus
markTouched(field) Force-mark a field as touched
isSubmitted ValueNotifier<bool>true after first submit()
submitErrors Issues from the last failed submit() call; empty on success
submit() Validate, auto-focus first error, return typed output or null
validatorFor(field) String? Function(String?) for TextFormField.validator
setValue(field, value) Set field text programmatically
hasErrors true when any field has active errors
reset() Clear all text, errors, and state
dispose() Release all resources
0
likes
150
points
69
downloads

Documentation

Documentation
API reference

Publisher

verified publishermeragix.dev

Weekly Downloads

Flutter form widgets backed by Zema schemas. Surgical per-field rebuilds, isTouched UX, auto-focus on first error, and a form-level error banner.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#flutter #form #validation #schema #zema

License

MIT (license)

Dependencies

flutter, zema

More

Packages that depend on zema_forms