Skip to content
X 468

Field

Profile

Enter your profile information below.

This appears on invoices and emails.

---
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---
<FieldSet>
<FieldLegend>Profile</FieldLegend>
<FieldDescription>Enter your profile information below.</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="name">Full name</FieldLabel>
<Input id="name" placeholder="Evil Rabbit" />
<FieldDescription>This appears on invoices and emails.</FieldDescription>
</Field>
<Field>
<FieldLabel for="username">Username</FieldLabel>
<Input id="username" placeholder="evilrabbit" />
</Field>
<Field orientation="horizontal">
<Checkbox id="newsletter" />
<FieldLabel for="newsletter">Subscribe to the newsletter</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>

To install the field component, run the following command:

Terminal window
npx shadcn@latest add @fulldev/field
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
FieldTitle,
} from "@/components/ui/field"
<FieldSet>
<FieldLegend>Profile</FieldLegend>
<FieldGroup>
<Field>
<FieldLabel for="name">Full name</FieldLabel>
<Input id="name" placeholder="Evil Rabbit" />
<FieldDescription>Optional helper text.</FieldDescription>
</Field>
</FieldGroup>
</FieldSet>

The Field family is designed for composing accessible forms. A typical field is structured as follows:

<Field>
<FieldLabel for="input-id">Label</FieldLabel>
<!-- Input, Select, Checkbox, etc. -->
<FieldDescription>Optional helper text.</FieldDescription>
</Field>
  • Field is the core wrapper for a single field.
  • FieldContent is a flex column that groups label and description. Not required if you have no description.
  • Wrap related fields with FieldGroup, and use FieldSet with FieldLegend for semantic grouping.

We'll never share your email.

---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---
<div class="w-full max-w-sm">
<Field>
<FieldLabel for="email">Email</FieldLabel>
<Input id="email" type="email" placeholder="email@example.com" />
<FieldDescription>We'll never share your email.</FieldDescription>
</Field>
</div>

Write a short bio about yourself.

---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Textarea } from "@/components/ui/textarea"
---
<div class="w-full max-w-sm">
<Field>
<FieldLabel for="bio">Bio</FieldLabel>
<Textarea id="bio" placeholder="Tell us about yourself" />
<FieldDescription>Write a short bio about yourself.</FieldDescription>
</Field>
</div>

Select your country of residence.

---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"
---
<div class="w-full max-w-sm">
<Field>
<FieldLabel for="country">Country</FieldLabel>
<NativeSelect id="country">
<NativeSelectOption value="">Select a country</NativeSelectOption>
<NativeSelectOption value="us">United States</NativeSelectOption>
<NativeSelectOption value="uk">United Kingdom</NativeSelectOption>
<NativeSelectOption value="ca">Canada</NativeSelectOption>
</NativeSelect>
<FieldDescription>Select your country of residence.</FieldDescription>
</Field>
</div>
Personal Information

Enter your personal details below.

---
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---
<div class="w-full max-w-sm">
<FieldSet>
<FieldLegend>Personal Information</FieldLegend>
<FieldDescription>Enter your personal details below.</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="first-name">First name</FieldLabel>
<Input id="first-name" placeholder="John" />
</Field>
<Field>
<FieldLabel for="last-name">Last name</FieldLabel>
<Input id="last-name" placeholder="Doe" />
</Field>
</FieldGroup>
</FieldSet>
</div>

You agree to our Terms of Service and Privacy Policy.

---
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
} from "@/components/ui/field"
---
<div class="w-full max-w-sm">
<Field orientation="horizontal">
<Checkbox id="terms" />
<FieldContent>
<FieldLabel for="terms">Accept terms and conditions</FieldLabel>
<FieldDescription>
You agree to our Terms of Service and Privacy Policy.
</FieldDescription>
</FieldContent>
</Field>
</div>
Notifications

Choose how you want to be notified.

---
import {
Field,
FieldDescription,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/components/ui/field"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
---
<div class="w-full max-w-sm">
<FieldSet>
<FieldLegend>Notifications</FieldLegend>
<FieldDescription>Choose how you want to be notified.</FieldDescription>
<RadioGroup defaultValue="email">
<Field orientation="horizontal">
<RadioGroupItem value="email" id="email" />
<FieldLabel for="email">Email</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="sms" id="sms" />
<FieldLabel for="sms">SMS</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem value="push" id="push" />
<FieldLabel for="push">Push notification</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
</div>

Stack Field components with FieldGroup. Add FieldSeparator to divide them.

Your primary email address.

Or

Your phone number for SMS updates.

---
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---
<div class="w-full max-w-sm">
<FieldGroup>
<Field>
<FieldLabel for="email-group">Email</FieldLabel>
<Input id="email-group" type="email" placeholder="email@example.com" />
<FieldDescription>Your primary email address.</FieldDescription>
</Field>
<FieldSeparator>Or</FieldSeparator>
<Field>
<FieldLabel for="phone">Phone</FieldLabel>
<Input id="phone" type="tel" placeholder="+1 (555) 000-0000" />
<FieldDescription>Your phone number for SMS updates.</FieldDescription>
</Field>
</FieldGroup>
</div>
  • Vertical fields: Default orientation stacks label, control, and helper text—ideal for mobile-first layouts.
  • Horizontal fields: Set orientation="horizontal" on Field to align the label and control side-by-side. Pair with FieldContent to keep descriptions aligned.
  • Responsive fields: Set orientation="responsive" for automatic column layouts inside container-aware parents. Apply @container/field-group classes on FieldGroup to switch orientations at specific breakpoints.

Help improve the app by sharing anonymous usage data.

Receive emails about new products and features.

---
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/components/ui/field"
---
<div class="w-full max-w-2xl">
<FieldGroup class="@container/field-group">
<Field orientation="responsive">
<Checkbox id="responsive-checkbox" />
<FieldContent>
<FieldLabel for="responsive-checkbox">
Analytics and performance
</FieldLabel>
<FieldDescription>
Help improve the app by sharing anonymous usage data.
</FieldDescription>
</FieldContent>
</Field>
<Field orientation="responsive">
<Checkbox id="responsive-marketing" />
<FieldContent>
<FieldLabel for="responsive-marketing">Marketing emails</FieldLabel>
<FieldDescription>
Receive emails about new products and features.
</FieldDescription>
</FieldContent>
</Field>
</FieldGroup>
</div>

Add data-invalid="true" to Field to switch the entire block into an error state, and add aria-invalid="true" on the input itself for assistive technologies.

Enter a valid email address.

---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---
<div class="w-full max-w-sm">
<Field data-invalid="true">
<FieldLabel for="error-email">Email</FieldLabel>
<Input id="error-email" type="email" aria-invalid="true" />
<FieldDescription>Enter a valid email address.</FieldDescription>
</Field>
</div>
  • FieldSet and FieldLegend keep related controls grouped for keyboard and assistive tech users.
  • Field outputs role="group" so nested controls inherit labeling from FieldLabel and FieldLegend when combined.
  • Apply FieldSeparator sparingly to ensure screen readers encounter clear section boundaries.