-
Notifications
You must be signed in to change notification settings - Fork 3
Form Validation Support in Morphr #3
Description
Problem
Currently, Morphr doesn't support form validation natively, making developers manually validate each field. This is tedious and error-prone.
As one user put it: "I need to use formKey.currentState.validate() to simplify field validation. Form is required with key and validateMode param."
Proposed Solution
Add form validation support using modular transformers:
- TextFieldTransformer - For transforming Figma text elements into input fields
- FormTransformer - For form structure and validation state
- FormFieldTransformer - For validated form fields
This approach allows using text fields independently or as part of a form.
// TextFieldTransformer - For any text input without validation
class TextFieldTransformer extends NodeTransformer {
TextFieldTransformer({
required NodeSelector selector,
this.keyboardType,
this.obscureText = false,
this.onChanged,
this.controller,
// other text field properties...
}) : super(
transform: (context, widget) {
// Create TextField from Figma text element
},
);
}
// FormTransformer - Just handles the Form widget
class FormTransformer extends NodeTransformer {
FormTransformer({
required NodeSelector selector,
required GlobalKey<FormState> formKey,
List<NodeTransformer> fieldTransformers = const [],
AutovalidateMode autovalidateMode = AutovalidateMode.disabled,
}) : super(
transform: (context, widget) => Form(
key: formKey,
autovalidateMode: autovalidateMode,
child: widget,
),
childTransformers: fieldTransformers,
);
}
// FormFieldTransformer - For validated form fields
class FormFieldTransformer extends NodeTransformer {
FormFieldTransformer({
required NodeSelector selector,
this.validator,
this.keyboardType,
this.obscureText = false,
// other properties...
}) : super(
transform: (context, widget) {
// Create TextFormField from Figma text element
},
);
}Example Usage
For standalone text fields:
FigmaComponent.widget(
"profile_screen",
transformers: [
TextFieldTransformer.byName(
"username_field",
controller: _usernameController,
),
],
)For validating forms:
final _formKey = GlobalKey<FormState>();
FigmaComponent.widget(
"login_container",
transformers: [
FormTransformer.byName(
"login_form",
formKey: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
fieldTransformers: [
FormFieldTransformer.byName(
"email_field",
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || !value.contains('@')) {
return 'Please enter a valid email';
}
return null;
},
),
FormFieldTransformer.byName(
"password_field",
obscureText: true,
validator: (value) {
if (value == null || value.length < 8) {
return 'Password must be at least 8 characters';
}
return null;
},
),
],
),
GestureTransformer.byName(
"submit_button",
onTap: () {
if (_formKey.currentState!.validate()) {
// Form is valid, process the data
}
},
),
],
)Benefits
This modular approach separates concerns appropriately, with no special components needed in Figma. It's compatible with existing designs and requires no changes to Morphr's core renderers.
Each transformer maintains a single responsibility, making the system more maintainable and extensible. Developers can use fields individually or as part of a form, with the same consistent API.
Implementation Notes
The implementation will respect the original Figma design's styling for error messages. The validation errors should be displayed according to the style defined in Figma rather than using default Material Design error styles. This ensures visual consistency with the design system.