@@ -118,6 +118,52 @@ await app.start();
118118- Validation runs inside the update function so it stays deterministic and doesn’t run during render.
119119- ` touched ` is set on ` onBlur ` so errors only display after the user leaves a field.
120120
121+ ## ` useForm ` Advanced Features
122+
123+ ` @rezi-ui/core ` also provides a richer ` useForm ` API for more complex flows:
124+
125+ - ** Field arrays** with deterministic keys and state-preserving mutations:
126+ - ` const fields = form.useFieldArray("items") `
127+ - ` fields.append(item) ` , ` fields.remove(index) ` , ` fields.move(from, to) `
128+ - ** Wizard flow** with step gates:
129+ - configure ` wizard.steps ` in ` useForm ` options
130+ - navigate with ` form.nextStep() ` , ` form.previousStep() ` , ` form.goToStep(index) `
131+ - backward navigation does not re-run validation
132+ - ** Form-level disabled/readOnly** with per-field overrides:
133+ - ` form.setDisabled(true) ` / ` form.setReadOnly(true) `
134+ - ` form.setFieldDisabled("name", false) ` and ` form.setFieldReadOnly("name", false) ` override form-level flags
135+
136+ ### Example: Wizard + Field Array
137+
138+ ``` typescript
139+ import { useForm } from " @rezi-ui/core/forms" ;
140+
141+ type Values = {
142+ name: string ;
143+ emails: string [];
144+ };
145+
146+ const form = useForm (ctx , {
147+ initialValues: { name: " " , emails: [" " ] },
148+ validate : (v ) => ({
149+ name: v .name ? undefined : " Required" ,
150+ emails: v .emails .map ((email ) => (email .includes (" @" ) ? undefined : " Invalid email" )),
151+ }),
152+ wizard: {
153+ steps: [
154+ { id: " profile" , fields: [" name" ] },
155+ { id: " emails" , fields: [" emails" ] },
156+ ],
157+ },
158+ onSubmit : (values ) => {
159+ // handle values
160+ },
161+ });
162+
163+ const emails = form .useFieldArray (" emails" );
164+ emails .append (" " );
165+ ```
166+
121167## Related
122168
123169- [ Input] ( ../widgets/input.md ) - Text input widget
0 commit comments