Form Editor
A complete form system for Flutter with 12 field types, rich validation, conditional rules, multi-step wizards, and a visual drag-and-drop designer. Split into a runtime package (vyuh_feature_forms) and an editor package (vyuh_form_editor).
Key Capabilities
Rich Field Types
Text, select, boolean, number, date/time, slider, range, file/image picker, phone number, entity references, and formula fields — 12 field types out of the box.
Comprehensive Validation
Sync validators (required, email, URL, pattern, ranges), async validators, temporal validators (future/past date, business hours), soft warnings, and cross-field context-aware validation.
Rules Engine
Conditional logic with field and section rules. Show/hide, enable/disable, focus, set values, compound actions, and dynamic validation are modeled as data.
Visual Form Designer
Drag-and-drop editor with field palette, properties panel, block canvas, row layout controls, preview, import/export, undo/redo, and keyboard shortcuts.
Core Concepts
- Architecture — Package split, descriptor system, and FormGroup as single source of truth
- Form Model — Form, FormRowBlock, FormSection, RepeatingSection, and StepForm
- Field Types — All 12 built-in field types with constructors and options
- Validation — Sync, async, soft, and context-aware validation
- Rules System — Conditions and actions for dynamic form behavior
- FormBuilder DSL — Fluent API for constructing forms programmatically
Core Types
| Type | Description |
|---|---|
| Form | Top-level container with FormGroup, validation, listeners, and async validation |
| FormField | Abstract base with name, title, validations, rules, visibility/enabled state, and typed FormControl creation |
| FormSection | Structural grouping with title, collapsible behavior, and visibility rules |
| RepeatingSection | Dynamic array of field groups with min/max instances and accordion/expanded display |
| StepForm | Multi-step wizard with sequential navigation, progress tracking, and draft support |
| FormBuilder | Fluent DSL for constructing forms with auto-finalize pattern |
Packages
Field Types
The form system includes 12 built-in field types:
| Field | Control Type | Description |
|---|---|---|
TextField | FormControl<String> | Text input with secure mode, mask, multiline |
NumberField | FormControl<num> | Integer and decimal number input |
SelectField | FormControl<String> | Dropdown with options, groups, and multi-select |
BooleanField | FormControl<bool> | Checkbox or switch toggle with tristate |
DateTimeField | FormControl<DateTime> | Date, time, or date-time picker |
SliderField | FormControl<double> | Single-value slider with min/max/divisions |
RangeSliderField | FormControl<RangeValues> | Dual-thumb range slider |
PhoneNumberField | FormControl<String> | Phone number with filtered input |
ImagePickerField | FormControl<List<XFile>?> | Image selection from gallery |
FilePickerField | FormControl<List<PlatformFile>?> | File selection with type filtering |
FormulaField | Computed | Calculated values from expressions |
ReferenceField | FormControl<String> | Entity reference with multiple layouts |
Quick Example
import 'package:vyuh_feature_forms/dsl/form_builder.dart';
// Build a course enrollment form using the fluent DSL
final form = FormBuilder(title: 'Course Enrollment')
.text('student_name', title: 'Student Name')
.required('Name is required')
.minLength(2)
.text('email', title: 'Email Address')
.required()
.email()
.phone('phone', title: 'Phone Number')
.select('enrollment_type', title: 'Enrollment Type')
.option('open', title: 'Open Enrollment')
.option('paid', title: 'Paid Enrollment')
.required()
.text('payment_method', title: 'Payment Method')
.showWhen(When.fieldEquals('enrollment_type', 'paid'))
.required()
.dateTime('start_date', title: 'Preferred Start Date')
.dateOnly()
.required()
.section('Preferences', (s) => s
.boolean('notifications', title: 'Enable Notifications')
.select('schedule', title: 'Schedule Preference')
.option('morning', title: 'Morning')
.option('afternoon', title: 'Afternoon')
.option('evening', title: 'Evening'),
collapsible: true,
)
.build();The DSL uses an auto-finalize pattern -- calling a new field method automatically commits the previous field. Validation, visibility rules, and field properties are all fluent chainable methods.
Next Steps
- Installation -- Add both packages to your project
- Quick Start -- Build a complete enrollment form in 5 minutes
- Architecture -- Understand the package split and descriptor system