Form
Forms contain fields of controls to enter information for submission.
Installation
Base UI components are all available as a single package.
npm install @base_ui/react
Once you have the package installed, import the component.
import { Form } from '@base_ui/react/Form'; import { Field } from '@base_ui/react/Field';
Anatomy
Forms are implemented using a Root
component and Field
components:
<Form.Root />
renders the<form>
element.<Field.Root />
renders an individual Field element.
<Form.Root>
<Field.Root />
</Form.Root>
Usage
Forms are intended to be used with the Field
component, which provides labeling and validation for individual form controls. These are nested inside Form.Root
:
import { Form } from '@base_ui/react/Form';
import { Field } from '@base_ui/react/Field';
<Form.Root>
<Field.Root>
<Field.Control />
</Field.Root>
<button type="submit">Submit</button>
</Form.Root>
If any of the Fields within the Form are invalid upon submit, focus is moved to the first invalid Field's control and the submit event is prevented.
Validation
The Field.Error
subcomponent of a Field renders error messages inside of it, with its content automatically populated with any client-side validation messages that occur.
<Field.Root>
<Field.Control />
<Field.Error />
</Field.Root>
Server-side validation
For server-side validation messages, the Form.Root
component accepts an errors
prop — an object whose keys map to the Field name
prop, with each value being a string or array of strings representing error messages. The onClearErrors
prop is called to clear these external server errors when the field's control has been changed:
const [errors, setErrors] = React.useState({});
async function handleSubmit(event) {
event.preventDefault();
const formData = Object.fromEntries(new FormData(event.currentTarget));
try {
await submitForm(formData);
} catch (errors) {
// Map errors from the server response
setErrors({
username: errors.username,
});
}
}
return (
<Form.Root onSubmit={handleSubmit} errors={errors} onClearErrors={setErrors}>
<Field.Root name="username">
<Field.Control />
<Field.Error /> {/* Populated with `errors.username` string */}
</Field.Root>
</Form.Root>
);
For more flexibility if required, each Field.Root
component accepts an invalid
boolean prop, and each Field.Error
subcomponent accepts a forceShow
boolean prop. These can be used as an alternative to Form.Root
's errors
prop by manually targeting specific Fields and showing specific error messages.
Native validation
By default, browser-native validation popups are disabled, as Field.Error
replaces this by rendering the validation messages to allow for flexible styling. If necessary, to enable these native validation popups, re-apply the default prop:
<Form.Root noValidate={false}>
API Reference
FormRoot
Prop | Type | Default | Description |
---|---|---|---|
className | union | Class names applied to the element or a function that returns them based on the component's state. | |
errors | object | Object of error messages with each key mapping to the name prop of a Field control, usually from server-side validation. | |
onClearErrors | func | Callback fired when the external server-side error messages should be cleared. | |
render | union | A function to customize rendering of the component. |