voo_forms 0.3.47  voo_forms: ^0.3.47 copied to clipboard
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.