FormField

Alpha

A compound component that provides label, hint, error, and required indicator for any form control. Unlike Input, it is control-agnostic — wrap native inputs, selects, textareas, switches, or custom components.

Import

import { FormField } from "@compa11y/react";

Usage

Example.tsx
import { FormField } from "@compa11y/react";

// Props mode
function EmailExample() {
  return (
    <FormField label="Email" hint="We'll never share it." error={emailError} required>
      <FormField.Control>
        {({ controlId, ariaProps }) => (
          <input id={controlId} type="email" {...ariaProps} />
        )}
      </FormField.Control>
    </FormField>
  );
}

// Compound mode — full layout control
function PasswordExample() {
  return (
    <FormField error={pwError} required>
      <FormField.Label>Password</FormField.Label>
      <FormField.Control>
        {({ controlId, ariaProps }) => (
          <input id={controlId} type="password" {...ariaProps} />
        )}
      </FormField.Control>
      <FormField.Hint>Minimum 8 characters.</FormField.Hint>
      <FormField.Error>{pwError}</FormField.Error>
    </FormField>
  );
}

Features

  • Control-agnostic — works with any native or custom input
  • aria-labelledby and aria-describedby wired automatically
  • aria-invalid set when error is present
  • aria-required and aria-disabled support
  • Required asterisk rendered with aria-hidden
  • Error live region with role='alert'
  • Props mode and compound mode
  • Dev warning if label is missing

Props

FormField component props
PropTypeDefaultDescription
labelstring-Label text (props mode)
hintstring-Help text shown below the label
errorstring-Error message (sets aria-invalid on the control)
requiredbooleanfalseMarks the field as required
disabledbooleanfalseMarks the field as disabled
unstyledbooleanfalseRemoves all default styles

Sub-components

FormField.Label

FormField.Label props
PropTypeDefaultDescription
children*ReactNode-Label text

FormField.Control

FormField.Control props
PropTypeDefaultDescription
children*(props: { controlId: string; ariaProps: object }) => ReactNode-Render prop providing controlId and ariaProps to spread onto the control

FormField.Hint

FormField.Hint props
PropTypeDefaultDescription
children*ReactNode-Hint text; registers itself in aria-describedby

FormField.Error

FormField.Error props
PropTypeDefaultDescription
children*ReactNode-Error message; renders with role='alert' only when children are truthy

Keyboard Interactions

Accessibility
All keyboard interactions follow WAI-ARIA best practices and work without any additional configuration.
Keyboard shortcuts for FormField
KeyAction
TabFocuses the wrapped form control