FormsReact
Labels and validates a form control.
Rendered by React 19.3.1
Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<Field.Root>
<Field.Label />
<Field.Control />
<Field.Description />
<Field.Error />
</Field.Root>
// Not in this example: Field.Item, Field.ValidityExamples
The demo at the top is the one example this component has so far.
API reference
15 props across 7 parts, in React syntax. className, style, render are listed once, under Shared props.
ControlField.Control
The form control to label and validate. You can omit this part and use any Base UI input component instead. For example, Input, Checkbox, or Select, among others, will work with Field out of the box. Renders an <input>.
| Prop | Type | Default |
|---|---|---|
defaultValue | string | number | readonly string[] | — |
onValueChangeCallback fired when the value changes. | ((value: string, eventDetails: { reason: "none"; event: Event; cancel: () => void; allowPropagation: () => void; isCanceled: boolean; isPropagationAllowed: boolean; trigger: Element | undefined; }) => void) | — |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
DescriptionField.Description
A paragraph with additional information about the field. Renders a <p>.
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
ErrorField.Error
An error message displayed if the field control fails validation. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
matchDetermines whether to show the error message according to the field's | boolean | keyof ValidityState | — |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
data-starting-style | Present when the error message begins animating in. |
data-ending-style | Present when the error message is animating out. |
ItemField.Item
Groups individual items in a checkbox group or radio group with a label and description. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
disabledWhether the wrapped control should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
LabelField.Label
An accessible label that is automatically associated with the field control. Renders a <label>.
| Prop | Type | Default |
|---|---|---|
nativeLabelWhether the component renders a native <label> element when replacing it via the render prop. | boolean | true |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-valid | Present when the field is in a valid state. |
data-invalid | Present when the field is in an invalid state. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
RootField.Root
Groups all parts of the field. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
nameIdentifies the field when a form is submitted. | string | — |
actionsRefA ref to imperative actions. | React.RefObject<FieldRootActions | null> | — |
dirtyWhether the field's value has been changed from its initial value. | boolean | — |
touchedWhether the field has been touched. | boolean | — |
disabledWhether the component should ignore user interaction. | boolean | false |
invalidWhether the field is invalid. | boolean | — |
validateA function for custom validation. | ((value: unknown, formValues: Record<string, any>) => string | void | string[] | Promise<string | void | string[] | null> | null) | — |
validationModeDetermines when the field should be validated. | FormValidationMode | 'onSubmit' |
validationDebounceTimeHow long to wait between validate callbacks if | number | 0 |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-touched | Present when the field has been touched. |
data-dirty | Present when the field's value has changed. |
data-valid | Present when the field is valid. |
data-invalid | Present when the field is invalid. |
data-filled | Present when the field is filled. |
data-focused | Present when the field control is focused. |
ValidityField.Validity
Used to display a custom message based on the field's validity. Requires children to be a function that accepts field validity state as an argument.
| Prop | Type | Default |
|---|---|---|
childrenrequiredA function that accepts the field validity state as an argument. | (state: FieldValidityState) => React.ReactNode | — |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
Field adds no keys; the control inside keeps its own. Pressing Enter in a form still submits it, and the field validates first.
Accessibility
| Part | Sets | So that |
|---|---|---|
| Label | a <label> tied to the control, or aria-labelledby on the control when nativeLabel is off | the control is read with its name, and clicking the label focuses it |
| Control | aria-describedby to Description and Error | the hint and the error are read with the control |
| Control | aria-invalid="true" when validation fails | a screen reader says the value is not accepted |
| Error | renders only while there is an error to show | an empty error is never announced |
| Item | groups one checkbox or radio with its own label and description | each option in a group is named on its own |
Focus order
- Control is the field's tab stop; Label, Description and Error are not focusable.
- When a form is submitted with errors, focus moves to the first invalid control (Form).