Form
Forms allow users to enter data that can be submitted while providing alignment and styling for form fields.
Submitting data
When using React 19, use the action
prop to handle form submission. This receives a FormData object containing the values for each form field. In React 18 or earlier, use the onSubmit
event instead. See the Forms guide details about integrating with frameworks.
import {Form, TextField, Button} from '@react-spectrum/s2';
<Form
action={formData => {
let name = formData.get('name');
alert(`Hello, ${name}!`);
}}>
<TextField name="name" label="Name" />
<Button type="submit">Submit</Button>
</Form>
Validation
Use validation props on each form field to prevent submission of invalid values. When validationBehavior="aria"
, form submission will not be prevented and validation will occur as the value is edited instead of on form submission. See the Forms guide for more details.
Server validation
Use the validationErrors
prop to provide server validation errors to the fields within a <Form>
.
import {Form, TextField} from '@react-spectrum/s2';
<Form
validationErrors={{
username: 'This username is not available.'
}}>
<TextField
name="username"
label="Username"
defaultValue="admin" />
</Form>
Focus management
By default, after a user submits a form with validation errors, the first invalid field will be focused. To prevent this, call preventDefault()
in the onInvalid
event. This example moves focus to an alert at the top of the form.
import {Form, TextField, Button, InlineAlert, Heading, Content} from '@react-spectrum/s2';
import {style} from '@react-spectrum/s2/style' with {type: 'macro'}
import {useState} from 'react';
function Example() {
let [isInvalid, setInvalid] = useState(false);
return (
<Form
styles={style({width: 300})}
onInvalid={e => {
e.preventDefault();
setInvalid(true);
}}
onSubmit={e => {
e.preventDefault();
setInvalid(false);
}}
onReset={() => setInvalid(false)}>
{isInvalid &&
<InlineAlert variant="negative" autoFocus>
<Heading>Unable to submit</Heading>
<Content>Please fix the validation errors below, and re-submit the form.</Content>
</InlineAlert>
}
<TextField
name="firstName"
isRequired
label="First Name" />
<TextField
name="lastName"
isRequired
label="Last Name" />
<div style={{display: 'flex', gap: 8}}>
<Button type="submit" variant="accent">Submit</Button>
<Button type="reset" variant="secondary">Reset</Button>
</div>
</Form>
);
}
API
Name | Type | Default |
---|---|---|
children | ReactNode | Default: — |
size | 'S'
| 'M'
| 'L'
| 'XL' | Default: 'M'
|
Size of the Form elements. | ||
isDisabled | boolean | Default: — |
Whether the Form elements are disabled. | ||
isEmphasized | boolean | Default: — |
Whether the Form elements are rendered with their emphasized style. | ||
action | string | FormHTMLAttributes | Default: — |
Where to send the form-data when the form is submitted. See MDN. | ||
encType | 'application/x-www-form-urlencoded'
| 'multipart/form-data'
| 'text/plain' | Default: — |
The enctype attribute specifies how the form-data should be encoded when submitting it to the server. See MDN. | ||
method | 'get'
| 'post'
| 'dialog' | Default: — |
The HTTP method to submit the form with. See MDN. | ||
target | '_blank'
| '_self'
| '_parent'
| '_top' | Default: — |
The target attribute specifies a name or a keyword that indicates where to display the response that is received after submitting the form. See MDN. | ||
autoCapitalize | 'off'
| 'none'
| 'on'
| 'sentences'
| 'words'
| 'characters' | Default: — |
Controls whether inputted text is automatically capitalized and, if so, in what manner. See MDN. | ||
styles | StylesProp | Default: — |
Spectrum-defined styles, returned by the style() macro. | ||