Form
StableA form with one validation pattern for the whole system: client checks on submit, server errors passed by field name, each shown under its Field and listed in a summary that takes focus.
When to use
Use it for
- Any group of fields submitted together: connect a repository, create a token, invite reviewers.
- errors for server-side validation, keyed by each Field's name.
- FormActions for the button row: primary action last.
Not for
- A single setting that saves on change: use Switch or an inline control without a form.
- Search and filter bars that update results live: no submit, no Form.
Do and don't
Every example is rendered with the real component, so it always matches what ships.
Validate on submit, then live
Do not flag fields while the user is still typing for the first time. After a failed submit, errors clear as soon as the value is fixed.
Keep what the user typed
Show the error next to the value so it can be corrected, never clear the field.
Disabling submit until the form is valid
A disabled button explains nothing. Keep it enabled and show what is missing on submit.
One generic error at the top
"Something went wrong" sends users hunting. Attach each error to its field.
Accessibility
- Base UI Form: native form element; fields validate on submit and the first invalid field gets focus.
- Server errors set aria-invalid on the control and are linked with aria-describedby.
- The error summary is role alert, receives focus when new errors arrive, and links move focus to each field.
- Errors are icon plus text, never color alone.
Anatomy and tokens
Read from packages/react/src/components/Form/Form.module.css at build time. Every value is a token: open one to see its
alias chain in both themes.
- Form container
.form - Error summary
.summary - Error summary, focus
.summary:focus-visible - summaryIcon
.summaryIcon - summaryBody
.summaryBody - Summary title
.summaryTitle - summaryList
.summaryList - Link to a field
.summaryLink - Link to a field, focus
.summaryLink:focus-visible - Actions footer
.actions
Props
Parsed from the TypeScript types in packages/react/src/components/Form/Form.tsx, so this table cannot drift from the
code.
It also accepts every native <HTMLFormElement> attribute except onSubmit.
| Prop | Type | Default | Description |
|---|---|---|---|
errors | Record<string, string | string[]> | none | Errors returned by the server after submit, keyed by field name. Each one shows under its Field and, with `errorSummary`, in a list at the top. A field's error clears when its value changes. |
onFormSubmit | (values: Record<string, unknown>) => void | none | Called with the form values (keyed by name) when the form is valid and submitted. |
validationMode | 'onSubmit' | 'onBlur' | 'onChange' | 'onSubmit' | When fields validate. Default `onSubmit`, then live once a field has been shown as invalid. |
errorSummary | boolean | true | Show a summary of `errors` above the fields, with links that move focus to each field. Default true. |
errorSummaryTitle | (count: number) => ReactNode | defaultTitle | Heading of the summary. Default "Fix {n} fields to continue". |
children | ReactNode | none | No description in the code yet. |
Comes with FormActions, each accepting native <div> attributes.
Playground
Change the props and see the real Form update. Controls are generated from the TypeScript props; nothing here changes the system.
<Form />Workbench
For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Form in Storybook) .
Embed Storybook stories here (3)
Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay
empty.
Default
ServerErrors
AllStates
Changelog
- New
Forms: Field (label, description, error wired by Base UI Field) and Input rebuilt on it (prefix, suffix, sizes; label, hint and error props kept). New Textarea (autosize, character count), Select (groups, descriptions), Combobox (filtering, async loading and empty states, multiple with chips), Checkbox (indeterminate, parent), CheckboxGroup, RadioGroup, Switch, Slider (single and range), NumberField (steppers, units) and Form (server errors with a focusable error summary, FormActions footer).
Unreleased (current version 0.1.0, no release tagged yet) , Oct 17, 2026