Form
A set of components and models that process form data.
Import
import { Form } from 'rsuite';- Basic:
Form: Used to define forms that support data validation.Form.Label: Title corresponding to the form field.Form.Control: Defines the control for the form field. Defaults to theInputcomponent. Can customize the component through theaccepterproperty.
- Layout:
Form.Stack: Used to layout a group of form controls.Form.Group: Used to layout a single form control.
- Field State:
Form.Text: Provides help information for form fields.Form.ErrorMessage: Displays error message for form fields.Form.ErrorSummary: Lists errors with links to their corresponding controls.
- Hooks
useFormControl: A hook that provides form control functionality for custom form components, enabling seamless integration with the Form component.
Layouts
Vertical Layout
Fluid
The fluid property allows the Input 100% of the form to fill the container, valid only in vertical layouts.
Horizontal Layout
Inline Layout
Layout In Modal
Status
Help Text
<Form.Text> A help description can be defined below the form component. If the tooltip property is set, an icon will be displayed on the form component and the help description information will be displayed as <Tooltip>.
Error Message
Error message can be set in 2 ways:
- The
<Form.Control>component passes anerrorMessageproperty setting error message, anderrorPlacementsets the location of the error message display. - Customize a prompt message.
Disabled and read only
Error summary and field navigation
Use Form.ErrorSummary to show an ordered overview of errors in a long form. Supply items from your validation or server state, and localize the header, field labels and messages in your application. The summary does not run validation or move focus when it appears or changes.
The following example validates only on submission. After a failed submission, the application focuses the summary in an effect after the errors have been committed. Tab to an error link and press Enter to focus and scroll to that control. Existing inline errors and field values are preserved.
Each controlId must be a unique DOM ID on the actual focusable control. Form.Group controlId supplies this ID to Form.Control; a custom accepter must forward it to the correct input or focusable widget. A layout wrapper or an ignored ID cannot be used as a substitute. Errors without a controlId are displayed as text.
Navigation skips missing, disabled, ARIA-disabled, hidden and inert targets, and stays within the dialog containing the summary. It does not expand tabs or load fields. For a lazy or custom field, use onSelect(item, event), call event.preventDefault(), reveal the field and focus it after your own update. If the callback gives focus to another connected element, that focus is preserved.
For dynamic announcements, you can provide role or aria-live explicitly. By default, the summary is a labelled region without a live region; existing field errors continue to provide their own feedback.
Accessibility
ARIA properties
You should set the
aria-labeloraria-labelledbyproperty for each form so that the screen reader can read the purpose of the form correctly.Through the
controlIdprop of<Form.Group>, you can setidon<Form.Control>and sethtmlForon<Form.Label>. In addition,aria-labelledbyandaria-describebywill be generated for<Form.Control>, corresponding to theidof<Form.Label>and<Form.Text>.
<Form.Group controlId="name">
<Form.Label>Username</Form.Label>
<Form.Control />
<Form.Text>Username is required</Form.Text>
</Form.Group>HTML:
<div class="rs-form-group" role="group">
<label id="name-control-label" for="name" class="rs-form-control-label">Username</label>
<div class="rs-form-control rs-form-control-wrapper">
<input
id="name"
class="rs-input"
aria-labelledby="name-control-label"
aria-describedby="name-help-text"
/>
</div>
<span id="name-help-text" class="rs-form-help-text">Username is required</span>
</div>Required JavaScript features
- Click the button of
type='submit'in the Form, and the submit event of the form will be triggered automatically.
Props
<Form>
| Property | Type (default) |
Description | Version |
|---|---|---|---|
| checkTrigger | 'change' | 'blur' | 'none' ('change') |
Specifies when to trigger form validation | |
| disabled | boolean (false) |
Disables the form | |
| errorFromContext | boolean (true) |
Default error messages in Form.Control are sourced from Context | |
| fluid | boolean | Enables the Input to occupy 100% width in vertical layouts only | |
| formDefaultValue | object | Initial default values for the form | |
| formError | object | Error messages for the form | |
| formValue | object | Values of the form (controlled) | |
| layout | 'horizontal' | 'vertical' | 'inline' ('vertical') |
The layout style of the form | |
| model | Schema | Instance of SchemaModel | |
| nestedField | boolean (false) |
Allows support for nested fields | |
| onChange | (formValue: object, event) => void | Callback triggered on data change | |
| onCheck | (formError: object) => void | Callback triggered on data validation | |
| onError | (formError: object) => void | Callback triggered on validation errors | |
| onReset | (formValue: object, event: FormEvent) => void | Callback triggered on form reset | |
| onSubmit | (formValue: object, event: FormEvent) => void | Callback triggered on form submission, only occurs when form data is validated | |
| plaintext | boolean (false) |
Renders the form in plain text | |
| readOnly | boolean (false) |
Sets the form to read-only mode | |
| resolver | Resolver | Validation resolver for third-party schema libraries. Takes precedence over model. |
<Form.Stack>
| Property | Type(default) |
Description |
|---|---|---|
| classPrefix | string ('form-stack') |
CSS class prefix for the component |
| fluid | boolean | Enables the Input to occupy 100% width in vertical layouts only |
| layout | 'horizontal' | 'vertical' | 'inline' ('vertical') |
The layout style of the form |
| spacing | number | Spacing between form controls |
<Form.Control>
| Property | Type(default) |
Description |
|---|---|---|
| accepter | ElementType (Input) |
Component to be used as the input. |
| checkAsync | boolean | Enables asynchronous validation. |
| checkTrigger | 'change' | 'blur' | 'none' | Overrides the form's validation trigger type for this control. |
| classPrefix | string ('form-control') |
CSS class prefix for the component. |
| errorMessage | ReactNode | Displays error messages. |
| errorPlacement | Placement('bottomStart') |
Specifies where to display error messages. |
| name * | string | Name attribute for the control, supports nested paths like address.city for form value management. |
| plaintext | boolean | Renders the control in plain text. |
| readOnly | boolean | Sets the control to read-only mode. |
| rule | checkType | Validation rule for the field. Overrides form-level model validation if there's a conflict, example. |
| shouldResetWithUnmount | boolean('false') |
Removes the field value and error message when the component is unmounted. |
<Form.Group>
| Property | Type(default) |
Description |
|---|---|---|
| classPrefix | string ('form-group') |
CSS class prefix for the component |
| controlId | string | Assigns an id to the <Form.Control> and sets htmlFor on the <Form.Label>. |
<Form.Label>
| Property | Type(default) |
Description |
|---|---|---|
| classPrefix | string ('form-control-label') |
CSS class prefix for the component |
| htmlFor | string | The for attribute of the HTML label tag, defaults to the Form.Group's controlId |
<Form.Text>
| Property | Type(default) |
Description |
|---|---|---|
| classPrefix | string ('form-help-text') |
CSS class prefix for the component |
| htmlFor | string | The for attribute of the HTML label tag, defaults to the Form.Group's controlId |
| tooltip | boolean | Shows the text through a Tooltip component |
<Form.ErrorMessage>
| Property | Type(default) |
Description |
|---|---|---|
| classPrefix | string ('form-error-message') |
CSS class prefix for the component |
| placement | Placement('bottomStart') |
Specifies where to display error messages |
| show | boolean | Toggles the visibility of the error message |
<Form.ErrorSummary>
| Property | Type (default) |
Description |
|---|---|---|
| header * | ReactNode | Application-localized heading for the summary |
| items * | readonly FormErrorSummaryItem[] | Invalid fields in the desired display order; an empty array hides the summary |
| onSelect | (item: FormErrorSummaryItem, event: MouseEvent) => void | Called before navigation; prevent the default action to handle revealing or focusing the field yourself |
| tabIndex | number (-1) |
Tab order of the summary root; the forwarded ref allows explicit application-controlled focus |
FormErrorSummaryItem
| Property | Type | Description |
|---|---|---|
| name * | string | Unique, stable field identity; treated as an opaque string, not a nested path |
| label * | ReactNode | Label of the field with an error |
| message * | ReactNode | Description of the error and how to correct it |
| controlId | string | Unique DOM ID of the actual focusable field control; omit for a text-only error |
The component is also available as the named export FormErrorSummary and the default export from rsuite/FormErrorSummary. It accepts Box style props and standard DOM/ARIA props. Navigation focuses the exact target before scrolling with nearest alignment and instant behavior; it does not infer or focus a wrapper's descendants.
Form Ref
| Name | Type | Description |
|---|---|---|
| check | (callback?: (formError: E) => void) => boolean | Verify form data |
| checkAsync | () => Promise |
Asynchronously check form data |
| checkForField | (fieldName: string, callback?: (checkResult: CheckResult) => void) => boolean | Checklist single field value |
| checkForFieldAsync | (fieldName: string) => Promise |
Asynchronous check form single field value |
| cleanErrorForField | (fieldName: string, callback?: () => void) => void | Clear single field error message |
| cleanErrors | (callback: () => void) => void | Clean error message |
| reset | () => void | Reset form data to initial value and clear all error messages |
| resetErrors | () => void | Reset error message |
| submit | () => void | Trigger form submission and verify data |
Schema
Schema depends on the schema-typed library for defining data models.
Placement
/**
* Placement options for error messages in form controls.
* The `static` option is supported from v6.0.0 onwards.
*/
type ErrorMessagePlacement =
| 'static'
| 'bottomStart'
| 'bottomEnd'
| 'topStart'
| 'topEnd'
| 'leftStart'
| 'leftEnd'
| 'rightStart'
| 'rightEnd';
Resolver
interface ResolverResult<E = Record<string, any>> {
errors: E;
}
type Resolver<V = Record<string, any>, E = Record<string, any>> = (
formValue: V,
context?: any
) => ResolverResult<E> | Promise<ResolverResult<E>>;Hooks
useFormControl
The useFormControl hook provides form control functionality for custom form components. It must be used within a <Form> component.
const {
value, // Current field value
error, // Field error message
plaintext, // Whether the field is in plaintext mode
readOnly, // Whether the field is read-only
disabled, // Whether the field is disabled
onChange, // Handler for field value changes
onBlur, // Handler for field blur events
onCheck, // Handler for manually triggering field validation
setValue // Directly sets the field value
} = useFormControl(props);| Property | Type(default) |
Description |
|---|---|---|
| checkAsync | boolean(false) |
Whether to perform asynchronous validation |
| checkTrigger | 'change' | 'blur' | null | The data validation trigger type, overrides the Form's checkTrigger |
| errorMessage | React.ReactNode | Custom error message to display |
| name | string | The name of the form field (required) |
| rule | CheckType | Validation rule (from Schema) |
| shouldResetWithUnmount | boolean(false) |
Whether to remove field value and error when component unmounts |
| value | any | The current value |
Return Values
| Property | Type | Description |
|---|---|---|
| disabled | boolean | Whether the field is disabled (inherited from Form) |
| error | React.ReactNode | Field error message |
| onBlur | () => void | Handler for field blur events |
| onChange | (value: any, event: SyntheticEvent) => void | Handler for field value changes |
| onCheck | (value: any) => void | Handler for manually triggering field validation |
| plaintext | boolean | Whether the field is in plaintext mode (inherited from Form) |
| readOnly | boolean | Whether the field is read-only (inherited from Form) |
| setValue | (value: any, shouldValidate?: boolean) => void | Directly sets the field value without triggering onChange events. If shouldValidate is true, will trigger validation based on checkTrigger |
| value | any | Current field value |
Example
import { useFormControl } from 'rsuite';
function CustomField({ name, label }) {
const { value, error, onChange, onBlur } = useFormControl({ name });
return (
<div className="custom-field">
<label>{label}</label>
<input value={value || ''} onChange={e => onChange(e.target.value, e)} onBlur={onBlur} />
{error && <div className="error-message">{error}</div>}
</div>
);
}
// Usage
<Form>
<CustomField name="email" label="Email" />
</Form>;