Beta Preview

Form

Forms allow users to enter data that can be submitted while providing alignment and styling for form fields.

size 
labelPosition 
labelAlign 
necessityIndicator 
isRequired 
isDisabled 
isEmphasized 
import {Form, TextField, Checkbox, ButtonGroup, Button} from '@react-spectrum/s2';

<Form>
  <TextField label="Name" />
  <TextField label="Email" type="email" />
  <Checkbox>I agree to the terms</Checkbox>
  <ButtonGroup>
    <Button type="submit" variant="primary">Submit</Button>
    <Button type="reset" variant="secondary">Reset</Button>
  </ButtonGroup>
</Form>

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.

validationBehavior 
import {Form, TextField, Button} from '@react-spectrum/s2';

<Form>
  <TextField
    label="Username"
    isRequired
    validate={value => value === 'admin' ? 'Nice try.' : null}
    name="username"
    defaultValue="admin" />
  <Button type="submit">Submit</Button>
</Form>

Server validation

Use the validationErrors prop to provide server validation errors to the fields within a <Form>.

This username is not available.
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

NameTypeDefault
childrenReactNodeDefault:
size'S''M''L''XL'Default: 'M'
Size of the Form elements.
isDisabledbooleanDefault:
Whether the Form elements are disabled.
isEmphasizedbooleanDefault:
Whether the Form elements are rendered with their emphasized style.
actionstringFormHTMLAttributes<HTMLFormElement>['action']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.
stylesDefault:
Spectrum-defined styles, returned by the style() macro.