voo_forms 0.3.47
voo_forms: ^0.3.47 copied to clipboard
A comprehensive cross-platform forms package with atomic design, clean architecture, and Material 3 support for Flutter applications.
VooForms #
A comprehensive, type-safe forms package for Flutter with clean architecture, atomic design pattern, and excellent developer experience.
โจ Features #
- ๐ฏ Type-Safe Fields - Full type safety with generics throughout
- ๐๏ธ Clean Architecture - Follows SOLID principles with clear separation of concerns
- ๐จ Atomic Design - Components organized as atoms, molecules, and organisms
- ๐ฑ Cross-Platform - Works seamlessly on iOS, Android, Web, Desktop
- ๐จ Material 3 - Built with the latest Material Design guidelines
- โ Rich Validators - 13+ built-in validators with composable validation
- ๐ง Smart Formatters - 12+ formatters for phone, credit card, currency, etc.
- ๐ฎ Powerful Controller - Advanced form state management
- ๐ Multiple Layouts - Vertical, grid, stepped, tabbed layouts
- ๐ Excellent DX - Intuitive API with great IDE support
๐ฆ Installation #
Add voo_forms
to your pubspec.yaml
:
dependencies:
voo_forms: ^0.3.2
๐ Quick Start #
Simple Form Example #
import 'package:voo_forms/voo_forms.dart';
// Create a form using direct widget instantiation
final form = VooForm(
fields: [
VooTextField(
name: 'username',
label: 'Username',
validators: [
RequiredValidation(),
MinLengthValidation(minLength: 3),
],
),
VooEmailField(
name: 'email',
label: 'Email Address',
validators: [
RequiredValidation(),
EmailValidation(),
],
),
VooPasswordField(
name: 'password',
label: 'Password',
validators: [
RequiredValidation(),
MinLengthValidation(minLength: 8),
PatternValidation(
pattern: r'^(?=.*[A-Z])(?=.*[0-9])',
errorMessage: 'Must contain uppercase and number',
),
],
),
],
);
Organizing Fields with Sections #
// Group related fields in collapsible sections
final form = VooForm(
fields: [
VooFormSection(
title: 'Personal Information',
description: 'Enter your basic details',
isCollapsible: true,
children: [
VooTextField(name: 'firstName', placeholder: 'First Name'),
VooTextField(name: 'lastName', placeholder: 'Last Name'),
VooDateField(name: 'birthDate', label: 'Date of Birth'),
],
),
VooFormSection(
title: 'Contact Details',
children: [
VooEmailField(name: 'email', label: 'Email'),
VooPhoneField(name: 'phone', label: 'Phone'),
],
),
],
);
๐จ Field Types #
VooForms provides direct widget classes for all field types:
// Text Fields
VooTextField(name: 'username', label: 'Username')
VooEmailField(name: 'email', label: 'Email')
VooPasswordField(name: 'password', label: 'Password')
VooPhoneField(name: 'phone', label: 'Phone')
VooMultilineField(name: 'bio', label: 'Bio')
VooNumberField(name: 'age', label: 'Age')
// Selection Fields
VooDropdownField<String>(
name: 'country',
label: 'Country',
options: ['United States', 'United Kingdom', 'Canada'],
)
VooCheckboxField(name: 'terms', label: 'Accept Terms')
VooBooleanField(name: 'newsletter', label: 'Subscribe')
// Date & Time
VooDateField(name: 'birthday', label: 'Birthday')
VooDateFieldButton(name: 'appointment', label: 'Appointment Date')
// Numeric Fields
VooIntegerField(name: 'age', label: 'Age')
VooDecimalField(name: 'price', label: 'Price')
VooCurrencyField(name: 'salary', label: 'Salary')
VooPercentageField(name: 'discount', label: 'Discount')
// Other Types
VooFileField(name: 'avatar', label: 'Avatar')
VooListField<String>(
name: 'tags',
label: 'Tags',
items: tags,
itemBuilder: (tag) => Chip(label: Text(tag)),
)
โ Validators #
Built-in Validators #
Each validator is in its own file for better organization:
// Basic Validators
RequiredValidation()
EmailValidation()
PhoneValidation()
UrlValidation()
// String Validators
MinLengthValidation(minLength: 3)
MaxLengthValidation(maxLength: 50)
PatternValidation(pattern: r'^[A-Z]', errorMessage: 'Must start with capital')
// Numeric Validators
MinValueValidation(minValue: 0)
MaxValueValidation(maxValue: 100)
RangeValidation(minValue: 0, maxValue: 100)
// Date Validators
DateRangeValidation(
minDate: DateTime(2020),
maxDate: DateTime(2030),
)
// Custom Validation
CustomValidation(
validator: (value) {
if (value == 'admin') return 'Username not available';
return null;
},
)
// Combine Multiple Validators
CompoundValidation(rules: [
RequiredValidation(),
EmailValidation(),
])
Creating Custom Validators #
class PasswordMatchValidation extends VooValidationRule<String> {
final String Function() getPassword;
PasswordMatchValidation({required this.getPassword})
: super(errorMessage: 'Passwords do not match');
@override
String? validate(String? value) {
if (value != getPassword()) {
return errorMessage;
}
return null;
}
}
๐ง Formatters #
Smart input formatting for better UX:
// Phone Formatters
VooFormatters.phoneUS() // (123) 456-7890
VooFormatters.phoneInternational() // +1 234 567 8900
// Card & Financial
VooFormatters.creditCard() // 1234 5678 9012 3456
VooFormatters.currency(symbol: '\$') // $1,234.56
// Date Formatters
VooFormatters.dateUS() // MM/DD/YYYY
VooFormatters.dateEU() // DD/MM/YYYY
VooFormatters.dateISO() // YYYY-MM-DD
// Text Formatters
VooFormatters.uppercase()
VooFormatters.lowercase()
VooFormatters.alphanumeric()
VooFormatters.numbersOnly()
// US Specific
VooFormatters.ssn() // 123-45-6789
VooFormatters.zipCode() // 12345 or 12345-6789
// Custom Patterns
VooFormatters.mask('###-##-####') // Custom mask
VooFormatters.pattern(
pattern: 'AA-####',
patternMapping: {
'A': RegExp(r'[A-Z]'),
'#': RegExp(r'[0-9]'),
},
)
๐ญ Field Options #
Customize field appearance and behavior:
VooField.text(
name: 'username',
options: VooFieldOptions(
// Label positioning
labelPosition: LabelPosition.floating, // or above, left, placeholder, hidden
// Field styling
fieldVariant: FieldVariant.filled, // or outlined, underlined, ghost, rounded, sharp
// Validation behavior
validateOnChange: true,
validateOnFocusLost: true,
// Error display
errorDisplayMode: ErrorDisplayMode.always, // or onFocus, onSubmit
// Focus behavior
focusBehavior: FocusBehavior.next, // or submit, none
),
)
Preset Options #
Use built-in presets for consistency:
options: VooFieldOptions.material // Material Design defaults
options: VooFieldOptions.comfortable // Spacious layout
options: VooFieldOptions.compact // Dense layout
options: VooFieldOptions.minimal // Minimal styling
๐ฎ Form Controller #
Advanced form control:
final controller = VooFormController(
form: form,
onFieldChange: (field, value) {
print('${field.name} changed to $value');
},
onValidationChange: (isValid) {
print('Form valid: $isValid');
},
);
// Programmatic control
controller.setValue('username', 'john_doe');
controller.getValue('username'); // 'john_doe'
controller.validate(); // Validate all fields
controller.validateField('email'); // Validate specific field
controller.reset(); // Reset to initial values
controller.clear(); // Clear all values
controller.submit(); // Submit the form
// Field management
controller.enableField('email');
controller.disableField('password');
controller.showField('optional');
controller.hideField('advanced');
controller.focusField('username');
๐ Layouts #
Multiple layout options:
Vertical Layout (Default) #
VooFormVerticalLayout(
fields: fields,
spacing: 16.0,
)
Grid Layout #
VooFormGridLayout(
fields: fields,
columns: 2,
spacing: 16.0,
crossAxisSpacing: 12.0,
)
Stepped Layout (Wizard) #
VooFormSteppedLayout(
steps: [
VooFormStep(
title: 'Personal Info',
fields: [/* fields */],
),
VooFormStep(
title: 'Contact',
fields: [/* fields */],
),
],
)
Tabbed Layout #
VooFormTabbedLayout(
tabs: [
VooFormTab(
label: 'Basic',
fields: [/* fields */],
),
VooFormTab(
label: 'Advanced',
fields: [/* fields */],
),
],
)
๐ Async Options & Search #
Support for dynamic dropdown options:
// Async dropdown with search
VooField.dropdown<City>(
name: 'city',
label: 'City',
enableSearch: true,
asyncOptionsLoader: (query) async {
final cities = await api.searchCities(query);
return cities.map((city) => VooFieldOption(
value: city,
label: city.name,
subtitle: city.state,
icon: Icons.location_city,
)).toList();
},
)
๐งช Testing #
VooForms is designed for easy testing:
testWidgets('Form submission', (tester) async {
final form = VooForm(
fields: [
VooField.text(name: 'username'),
VooField.email(name: 'email'),
],
onSubmit: expectAsync1((values) {
expect(values['username'], 'testuser');
expect(values['email'], 'test@example.com');
}),
);
await tester.pumpWidget(MaterialApp(home: form));
// Enter values
await tester.enterText(
find.byType(TextFormField).first,
'testuser',
);
await tester.enterText(
find.byType(TextFormField).last,
'test@example.com',
);
// Submit
await tester.tap(find.text('Submit'));
await tester.pump();
});
๐๏ธ Architecture #
VooForms follows clean architecture principles:
Presentation Layer (UI/Widgets)
โ
Domain Layer (Entities/Business Logic)
โ
Data Layer (Models/Repositories)
Atomic Design Pattern #
- Atoms: Basic input widgets (text field, checkbox, etc.)
- Molecules: Composed components (field with label, field with error)
- Organisms: Complete forms and layouts
Key Principles #
- One class per file - Better organization and navigation
- No _buildXXX methods - Using helper classes instead
- Clean imports - No relative imports, properly ordered
- Type safety - Generics used throughout
- SOLID principles - Single responsibility, open/closed, etc.
๐จ Theming #
VooForms respects your app's Material theme:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: MyApp(),
)
๐ Documentation #
- Developer Guide - Comprehensive guide with examples
- API Documentation - Full API reference
- Example App - Complete example implementation
- Changelog - Version history
๐ค Contributing #
Contributions welcome! Please ensure:
- Follow clean architecture principles
- One class per file
- No _buildXXX methods returning widgets
- Add tests for new features
- Update documentation
๐ License #
MIT License - see LICENSE file for details.
๐ What's New in 0.1.14 #
- Major Technical Debt Cleanup - Eliminated all _buildXXX methods
- Better Organization - 25+ classes split into individual files
- Improved DX - Each validator/formatter in its own file
- Clean Architecture - Proper separation of concerns throughout
- Enhanced Testing - 92.6% test success rate
See CHANGELOG.md for full details.