docs / patterns / field-group
FieldGroup
a form field that keeps its label, control, description and error message together as one accessible unit. mount a FieldError and the control flips to invalid, with the message linked, on its own.
intensity · structuresrsc · client
provenance
authored in usvalayer
core / patternsintensity
structures · organizes a region, stays out of the contentcomposition
one control per group: Input, Select, whatever FieldControl clonesrender FieldError conditionally, mounting it is the error stateFieldControl takes exactly one child elementnever two controls in one group, every derived id points at one thinga11y
the label is wired viahtmlFor · FieldError is role="alert" · description and error ids land in aria-describedbyjest-axedependencies
Label from the same packagelive demo · try it outtype without an @ to trip the error
type without an @ to trip the error state.
A healthy field: description wired to aria-describedby, no error.
props
| prop | type | default | notes |
|---|---|---|---|
| id | string | — | base id for the field; derived ids power htmlFor and aria-describedby. auto-generated when omitted. |
| className | string | — | merged onto the root wrapper, a flex column. |
| ...div props | HTMLAttributes<HTMLDivElement> | — | any standard div attribute is forwarded to the wrapper. |
get it
bun add @usva-ui/reactusage
import { FieldControl, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@usva-ui/react/patterns/field-group";
import { Input } from "@usva-ui/react/primitives/input";
<FieldGroup>
<FieldLabel>Email address</FieldLabel>
<FieldControl>
<Input type="email" placeholder="you@studio.fi" />
</FieldControl>
<FieldDescription>We only email about releases.</FieldDescription>
<FieldError>Enter a valid email address.</FieldError>
</FieldGroup>