When to use
Use this skill when:
- •Building forms with multiple inputs
- •Need field validation and error display
- •Handling form submission with loading states
Source of truth
- •
packages/core/src/forms/useForm.ts—useForm()hook - •
packages/core/src/widgets/types.ts—InputProps,FieldProps,CheckboxProps,SelectProps - •
packages/core/src/widgets/ui.ts—ui.input(),ui.field(),ui.checkbox(),ui.select() - •
packages/core/src/ui/recipes.ts—recipe.input(),recipe.button(),recipe.select()for design-system styling
Steps
- •
Use the
useForm()hook inside adefineWidget:typescriptimport { defineWidget, ui, useForm } from "@rezi-ui/core"; const MyForm = defineWidget<{ onSubmit: (v: Values) => void }>((props, ctx) => { const form = useForm(ctx, { initialValues: { name: "", email: "" }, validate: (values) => { const errors: Record<string, string> = {}; if (!values.name) errors.name = "Required"; if (!values.email.includes("@")) errors.email = "Invalid email"; return errors; }, onSubmit: async (values) => props.onSubmit(values), }); return ui.column({ gap: 1 }, [ ui.field({ label: "Name", error: form.errors.name, children: ui.input({ id: "field-name", ...form.bind("name") }), }), ui.field({ label: "Email", error: form.errors.email, children: ui.input({ id: "field-email", ...form.bind("email") }), }), ui.button({ id: "submit", label: "Submit", intent: "primary", onPress: form.submit }), ]); }, { name: "MyForm" }); - •
Bind fields using
form.bind("fieldName")— returns{ value, onChange }props - •
Use
ui.field()to wrap inputs with labels and error display - •
Access form state via
form.errors,form.touched,form.dirty,form.submitting
Design system note
Inputs are recipe-styled by default when semantic color tokens are available (for example via a ThemeDefinition preset).
Manual overrides merge on top via the same mergeTextStyle(baseStyle, ownStyle) pattern used by the renderer.
Use manual style only for targeted overrides (merged on top of recipe output).
Verification
- •Validation errors display next to fields
- •Submission works and calls
onSubmit - •Touched/dirty state tracked correctly