Unified UI

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-field
pnpm dlx @work-rjkashyap/unified-ui add form-field
npx @work-rjkashyap/unified-ui add form-field
bunx @work-rjkashyap/unified-ui add form-field

If 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-ui
pnpm add @work-rjkashyap/unified-ui
yarn add @work-rjkashyap/unified-ui
bun add @work-rjkashyap/unified-ui

Anatomy

import { FormField } from "@work-rjkashyap/unified-ui";

Examples

Basic Usage

Required Fields

Error State

Please enter a valid email address.
Password must be at least 8 characters.

Sizes

Horizontal Layout

Please enter a valid URL.

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:

PropTypeDescription
idstringAuto-generated id to set on the control.
aria-describedbystringID(s) of description and/or error elements.
aria-invalidbooleantrue when an error is present.
aria-requiredbooleantrue when the field is required.
disabledbooleantrue when the field is disabled.

Props

PropTypeDefaultDescription
labelReactNodeLabel text for the form field.
descriptionReactNodeHelper text below the label or control.
errorReactNodeError 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.
requiredbooleanfalseShows a red asterisk and sets aria-required via render fn.
disabledbooleanfalseReduces opacity on all visual elements.
htmlForstringautoID for the form control. Auto-generated if omitted.
childrenReactNode | (props: ControlProps) => ReactNodeThe form control(s) or render function.
labelClassNamestringAdditional CSS classes for the label.
descriptionClassNamestringAdditional CSS classes for the description.
errorClassNamestringAdditional CSS classes for the error message.
controlClassNamestringAdditional CSS classes for the control wrapper.
classNamestringAdditional 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 htmlFor is automatically linked to the control's id.
  • Description — Linked to the control via aria-describedby.
  • Error message — Replaces description in aria-describedby and renders with role="alert".
  • Required — Visual indicator plus aria-required (via render function).
  • Disabled — Visual reduction on all elements; disable the control separately.

Design Tokens

TokenUsage
--foregroundLabel text color
--dangerRequired indicator & error text
--muted-foregroundDescription text color

On this page