final_forms 2.0.0
final_forms: ^2.0.0 copied to clipboard
A standalone Flutter form package with validation, custom field builders, and programmatic control. Zero external dependencies.
FinalForms #
A standalone, reusable Flutter form package with validation, custom field builders, and programmatic control. Zero external dependencies.
Features #
- Declarative Form Definition - Define forms with a simple list of field configurations
- Built-in Validators - Required, email, phone, minLength, maxLength, pattern, age18, name
- Custom Validators - Add your own validation logic with custom functions
- Custom Field Builders - Override default UI with your own widgets
- Programmatic Control - Access form state via
FinalFormController - Value Transformers - Transform values before submission (e.g., dates to timestamps)
- Zero Dependencies - Only depends on Flutter SDK
Installation #
dependencies:
final_forms: ^2.0.0
Or run:
flutter pub add final_forms
Usage #
Basic Form #
import 'package:final_forms/final_forms.dart';
class LoginForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
final fields = [
FinalFormField(
name: 'email',
type: FinalFieldType.email,
label: 'Email',
validators: [
FinalValidator(type: ValidatorType.required),
FinalValidator(type: ValidatorType.email),
],
),
FinalFormField(
name: 'password',
type: FinalFieldType.password,
label: 'Password',
validators: [
FinalValidator(type: ValidatorType.required),
FinalValidator(type: ValidatorType.minLength, params: {'min': 6}),
],
),
];
return FinalForm(
fields: fields,
onSubmit: (data) async {
print('Form data: $data');
// Call your API
},
onSuccess: () => print('Success!'),
onError: (e) => print('Error: $e'),
);
}
}
Custom Field Builders #
FinalForm(
fields: fields,
onSubmit: (data) async => submitForm(data),
fieldBuilder: (context, field, value, errors, onChanged, onBlur, controller) {
// Return your custom widget
return MyCustomTextField(
label: field.label,
value: value,
error: errors.isNotEmpty ? errors.first.customMessage : null,
onChanged: onChanged,
);
},
submitButtonBuilder: (context, isLoading, isValid, submit) {
return ElevatedButton(
onPressed: isLoading ? null : submit,
child: isLoading ? CircularProgressIndicator() : Text('Submit'),
);
},
);
Field Types #
Built-in types with automatic keyboard/rendering behavior:
FinalFieldType.text- Text inputFinalFieldType.password- Password input (obscured)FinalFieldType.email- Email input with email keyboardFinalFieldType.phone- Phone input with phone keyboardFinalFieldType.date- Date inputFinalFieldType.select- Dropdown selectFinalFieldType.checkbox- Checkbox
Custom Field Types #
Use any string value for custom types:
FinalFormField(
name: 'rating',
type: 'rating', // Custom type
label: 'Rating',
),
Handle custom types in your fieldBuilder to render custom widgets.
Validators #
| Type | Description | Params |
|---|---|---|
required |
Field must have a value | - |
email |
Valid email format | - |
phone |
Valid phone format | - |
minLength |
Minimum string length | {'min': int} |
maxLength |
Maximum string length | {'max': int} |
pattern |
Regex pattern match | {'pattern': String} |
age18 |
Must be 18+ years old | - |
name |
Valid name (letters, spaces, hyphens) | - |
custom |
Custom validation function | - |
Custom Validator Example #
FinalValidator(
type: ValidatorType.custom,
customMessage: 'Must contain "test"',
customValidator: (value, params) {
if (value == null || value is! String) return true;
return value.toLowerCase().contains('test');
},
)
FinalFormController #
Access the form controller for programmatic control:
// Get field value
controller.getValue('email');
// Set field value
controller.setValue('email', 'test@example.com');
// Check if form is valid
controller.isValid;
// Check if form is loading
controller.isLoading;
// Get field errors
controller.getErrors('email');
// Reset form
controller.reset();
Example App #
See the example directory for a complete example app with multiple form examples.
License #
MIT License - see LICENSE for details.