The Label component associates descriptive text with form controls, improving accessibility and user experience.
Installation
npx shadcn@latest add @eo-n/label
Copy component code
Copy and paste the label component code into your project at components/ui/label.tsx.
Update imports
Update the import paths to match your project setup.
import { Label } from "@/components/ui/label";
export default function Example() {
return <Label htmlFor="email">Email</Label>;
}
Examples
Default
<Label>Accept terms and conditions</Label>
With Input
import { Input } from "@/components/ui/input";
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="email@example.com" />
</div>
With Checkbox
import { Checkbox } from "@/components/ui/checkbox";
<div className="flex items-center space-x-2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</div>
With Radio
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
<RadioGroup defaultValue="option1">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option1" id="opt1" />
<Label htmlFor="opt1">Option 1</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option2" id="opt2" />
<Label htmlFor="opt2">Option 2</Label>
</div>
</RadioGroup>
With Switch
import { Switch } from "@/components/ui/switch";
<div className="flex items-center space-x-2">
<Switch id="airplane-mode" />
<Label htmlFor="airplane-mode">Airplane Mode</Label>
</div>
With Textarea
import { Textarea } from "@/components/ui/textarea";
<div className="space-y-2">
<Label htmlFor="message">Message</Label>
<Textarea id="message" placeholder="Type your message here..." />
</div>
Required Field
import { Input } from "@/components/ui/input";
<div className="space-y-2">
<Label htmlFor="username">
Username <span className="text-destructive">*</span>
</Label>
<Input id="username" required />
</div>
With Description
import { Input } from "@/components/ui/input";
<div className="space-y-2">
<Label htmlFor="username">Username</Label>
<Input id="username" />
<p className="text-sm text-muted-foreground">
This is your public display name.
</p>
</div>
Disabled State
The label automatically inherits disabled styles from parent groups or peer elements.
import { Input } from "@/components/ui/input";
<div className="space-y-2">
<Label htmlFor="disabled-input">Disabled Field</Label>
<Input id="disabled-input" disabled />
</div>
Multiple Labels
import { NumberInput, NumberInputGroup, NumberInputField, NumberInputDecrement, NumberInputIncrement } from "@/components/ui/number-input";
<NumberInput defaultValue={25}>
<Label>Age</Label>
<NumberInputGroup>
<NumberInputDecrement />
<NumberInputField />
<NumberInputIncrement />
</NumberInputGroup>
</NumberInput>
With Error State
import { Input } from "@/components/ui/input";
<div className="space-y-2">
<Label htmlFor="error-input">Email</Label>
<Input id="error-input" type="email" aria-invalid />
<p className="text-sm text-destructive">
Please enter a valid email address.
</p>
</div>
API Reference
Extends all props from the native HTML label element.
The id of the form control this label is associated with. Clicking the label will focus the associated control.
Additional CSS classes to apply to the label.
TypeScript
type LabelProps = React.ComponentProps<"label">;
Styling Features
- Medium font weight for emphasis
- Small text size (text-sm)
- No leading for compact spacing
- User-select disabled for clean interactions
- Automatic disabled state when used with disabled controls
- Peer-aware styling (responds to sibling input states)
- Group-aware styling (responds to parent group states)
Accessibility
- Proper label-control association via
htmlFor/id
- Clicking label focuses associated control
- Screen reader support
- Respects disabled state of associated controls
- Works with all form controls
Best Practices
- Always use
htmlFor to associate labels with form controls
- Keep label text concise and descriptive
- Place labels above or beside form controls consistently
- Mark required fields clearly
- Use consistent spacing between labels and controls
- Provide helpful descriptions for complex fields
- Ensure labels remain visible (avoid placeholder-only forms)
Related