FormField
A composable form field wrapper that combines label, control, description, and error message into a consistent accessible layout.
Overview
The FormField component composes a label, form control slot, optional description/helper text, and error message into a single consistent layout. It automatically generates and wires up htmlFor, aria-describedby, and aria-invalid attributes for full accessibility.
Installation
Install the component via the CLI in one command.
npx @work-rjkashyap/unified-ui add form-fieldpnpm dlx @work-rjkashyap/unified-ui add form-fieldnpx @work-rjkashyap/unified-ui add form-fieldbunx @work-rjkashyap/unified-ui add form-fieldIf you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for details.
Or install the full package
Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.
npm install @work-rjkashyap/unified-uipnpm add @work-rjkashyap/unified-uiyarn add @work-rjkashyap/unified-uibun add @work-rjkashyap/unified-uiAnatomy
import { FormField } from "@work-rjkashyap/unified-ui";Examples
Basic Usage
Required Fields
Error State
Sizes
Horizontal Layout
Disabled State
Render Function (Auto-wired Accessibility)
For maximum accessibility, use the render function form of children to receive and spread control props automatically:
<FormField label="Email" required error={errors.email}>
{(controlProps) => (
<Input {...controlProps} type="email" placeholder="you@example.com" />
)}
</FormField>The render function receives:
| Prop | Type | Description |
|---|---|---|
id | string | Auto-generated id to set on the control. |
aria-describedby | string | ID(s) of description and/or error elements. |
aria-invalid | boolean | true when an error is present. |
aria-required | boolean | true when the field is required. |
disabled | boolean | true when the field is disabled. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Label text for the form field. |
description | ReactNode | — | Helper text below the label or control. |
error | ReactNode | — | Error message (replaces description when present). |
size | "sm" | "md" | "lg" | "md" | Controls label size, spacing, and context. |
orientation | "vertical" | "horizontal" | "vertical" | Layout orientation for label + control. |
required | boolean | false | Shows a red asterisk and sets aria-required via render fn. |
disabled | boolean | false | Reduces opacity on all visual elements. |
htmlFor | string | auto | ID for the form control. Auto-generated if omitted. |
children | ReactNode | (props: ControlProps) => ReactNode | — | The form control(s) or render function. |
labelClassName | string | — | Additional CSS classes for the label. |
descriptionClassName | string | — | Additional CSS classes for the description. |
errorClassName | string | — | Additional CSS classes for the error message. |
controlClassName | string | — | Additional CSS classes for the control wrapper. |
className | string | — | Additional CSS classes for the root element. |
Accessibility
Use the render function form of children for automatic id,
aria-describedby, aria-invalid, and aria-required wiring on the
control.
- Label linkage — The label's
htmlForis automatically linked to the control'sid. - Description — Linked to the control via
aria-describedby. - Error message — Replaces description in
aria-describedbyand renders withrole="alert". - Required — Visual indicator plus
aria-required(via render function). - Disabled — Visual reduction on all elements; disable the control separately.
Design Tokens
| Token | Usage |
|---|---|
--foreground | Label text color |
--danger | Required indicator & error text |
--muted-foreground | Description text color |