Prototyper UI

FormField

A react-hook-form helper that wires Field, label, description, and error to a Controller in one component

Loading...

Installation

pnpm dlx shadcn@latest add https://prototyper-ui.com/r/form-field.json
npx shadcn@latest add https://prototyper-ui.com/r/form-field.json
yarn dlx shadcn@latest add https://prototyper-ui.com/r/form-field.json
bunx --bun shadcn@latest add https://prototyper-ui.com/r/form-field.json

This will add the following files to your project:

  • components/ui/form-field.tsx

Peer dependency: This component requires react-hook-form. Install it alongside:

npm install react-hook-form @hookform/resolvers zod

Note: This component depends on Field. It will be installed automatically.

Usage

import { useForm, FormProvider } from "react-hook-form"
import { FormField } from "@/components/ui/form-field"
import { Input } from "@/components/ui/input"

const form = useForm({ defaultValues: { email: "" } })

<FormProvider {...form}>
  <form onSubmit={form.handleSubmit(onSubmit)}>
    <FormField name="email" label="Email" required>
      <Input type="email" placeholder="you@example.com" />
    </FormField>
  </form>
</FormProvider>

FormField uses Controller + useFormContext internally, so it must be rendered inside a <FormProvider>. It auto-wires value, onChange, onBlur, and ref to the child input via cloneElement.

When to use FormField vs raw Field

Use FormFieldUse raw Field + Controller
Standard text inputs, textareasSelect, NumberField, Checkbox, Switch, RadioGroup
Quick forms with minimal boilerplateComponents that use onValueChange / onCheckedChange
Inputs accepting value + onChangeCustom controlled components

For components with non-standard change handlers, use Controller directly with Field as shown in the Forms guide.

Examples

Validation

Loading...

All Input Types

Loading...

Dynamic Fields

Loading...

Multi-Step Form

Loading...

Styling

Data Slots

Use data-slot attributes to target specific parts of the component:

Slot nameElement
form-fieldRoot Field wrapper
field-labelLabel element
field-descriptionDescription paragraph
field-errorError message container

Customization Examples

/* Increase spacing between form fields */
[data-slot="form-field"] {
  @apply gap-2;
}
{
  /* Override width via className */
}
<FormField name="email" label="Email" className="max-w-xs">
  <Input />
</FormField>;

API Reference

FormField

A helper component that wires a Controller to Field + FieldLabel + FieldDescription + FieldError.

PropTypeDefaultDescription
namestring-Field name matching the form schema
labelstring-Label text displayed above the input
descriptionstring-Help text displayed below the label
requiredboolean-Shows a required indicator on the label
classNamestring-Additional CSS classes on the root Field
childrenReact.ReactElement-The input component to wire up

Accessibility

Keyboard Interactions

KeyAction
TabMoves focus to the input within the field

ARIA Attributes

  • The Field wrapper renders with role="group".
  • FieldLabel is associated with the input via Base UI's label mechanism.
  • FieldError renders with role="alert" and aria-live="polite" for screen reader announcements.
  • When invalid is true, data-invalid is set on the field for styling hooks.

On this page