Form Field
A wrapper component that provides consistent label, description, and error handling for form inputs. Includes FormFieldHint and FormFieldGroup for contextual help and grouping.
Preview
FormField wraps any input with label and description
Enter your first and last name
Tell us a bit about yourself
Required Fields
Mark fields as required with a visual indicator
Minimum 8 characters
Error State
Display validation errors below the input
Type an invalid email above to see the error state.
Disabled State
Disable the entire field including label styling
Contact support to change
With Other Components
FormField works with any form component
FormFieldHint
Add contextual help below form fields
FormFieldGroup
Group related fields with a shared legend
Props
FormField component API reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Label text above the input |
description | string | — | Helper text below label |
error | string | — | Error message to display |
required | boolean | false | Show required indicator (*) |
disabled | boolean | false | Disable field and input |
children* | ReactNode | — | Input component to wrap |
className | string | — | Additional CSS classes |
FormFieldGroup Props
| Prop | Type | Default | Description |
|---|---|---|---|
legend* | string | — | Group title (fieldset legend) |
description | string | — | Group description text |
children* | ReactNode | — | FormField components |
Usage
Import and implementation example
import { FormField, FormFieldHint, FormFieldGroup } from '@/components/ui/form-field'
import { Input } from '@/components/ui/input'
export default function Example() {
const [errors, setErrors] = useState({})
return (
<>
{/* Basic usage */}
<FormField label="Email" description="We'll never share your email">
<Input type="email" placeholder="Enter email" />
</FormField>
{/* With validation error */}
<FormField
label="Password"
required
error={errors.password}
>
<Input type="password" />
</FormField>
{/* With hint */}
<FormField label="API Key">
<Input type="password" />
</FormField>
<FormFieldHint>Find your API key in Settings.</FormFieldHint>
{/* Grouped fields */}
<FormFieldGroup legend="Address" description="Your shipping address">
<FormField label="Street">
<Input placeholder="123 Main St" />
</FormField>
<FormField label="City">
<Input placeholder="New York" />
</FormField>
</FormFieldGroup>
</>
)
}Features
Built-in functionality
- Automatic ID linking: Label automatically linked to input
- Error handling: Error message with icon and ARIA support
- Required indicator: Visual asterisk for required fields
- Disabled state: Propagates disabled to child input
- ARIA support: aria-invalid, aria-describedby included
- FormFieldGroup: Group related fields with fieldset/legend
- FormFieldHint: Contextual help with icon
- Dark mode: Full dark mode support
Accessibility
Accessibility considerations
ARIA Attributes
Labels linked to inputs via htmlForaria-invalid on inputs with errorsaria-describedby links error messagesFormFieldGroup uses fieldset/legendKeyboard Navigation
| Key | Action |
|---|---|
| Tab | Navigate between form fields |
Notes
- Required fields indicated with asterisk
- Error messages use role="alert"
- Disabled state visible on label and input
- Legend provides context for grouped fields