Form
Typed signal-based form store (createForm/useForm) with sync/async validation and a thin Form element wrapper
Category: inputs · WCAG 2.2-AA · form, validation, signals, input
States
- idle
- submitting
Props
| Prop | Type | Default | Description |
|---|---|---|---|
form | FormStore<T> | — | The form store holding values, validation, and submission state. |
onValid | (values: T) => void | Promise<void> | — | Called with the values when the form passes validation. |
children | ReactNode | — | Content rendered inside the component. |
className | string | — | Additional CSS class names merged onto the root element. |
Design tokens
--cascivo-space-4
When to use
- Collecting and submitting a set of related field values together
- Running sync or async validation (including Standard Schema like zod/valibot/arktype) before invoking onValid
- Tracking per-field touched state and errors via the signal-based store from useForm/createForm
When not to use
- A single standalone value with no submission step — render a bare Input
- Inline editing of one read-only value — use Editable
How to build an accessible Form in React →
Examples
Basic form with validation
function Demo() {
const form = useForm({
initialValues: { email: '' },
validate: (v) => v.email.includes('@') ? {} : { email: 'Invalid email' },
})
const email = form.field('email')
return (
<Form form={form} onValid={console.log}>
<Input
label="Email"
value={email.value}
onChange={(e) => email.onChange(e.currentTarget.value)}
onBlur={email.onBlur}
error={email.error}
/>
<Button type="submit">Save</Button>
</Form>
)
}Related components
- Input — Form wraps field controls like Input, wiring value/onChange/onBlur/error from form.field()
- FileUploader — File attachments can participate in a Form submission