Shadcn Label
Free shadcn/ui label component for React, built on Radix Label — accessible form labels bound to inputs by htmlFor, with required and disabled states. Copy or install in one command.
Installation
{
"registries": {
"@designrevision": "https://registry.designrevision.com/r/{name}.json"
}
}
Add to your existing components.json. Requires shadcn/ui v2.3+.
Packages
Props
htmlFor
= —
string
Id of the input this label is bound to. Clicking the label then focuses that input.
Extends the Radix Label Root (@radix-ui/react-label) — all native <label> attributes are supported.
"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cn } from "@/lib/utils"
function Label({
className,
...props
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
return (
<LabelPrimitive.Root
data-slot="label"
className={cn(
"flex select-none items-center gap-2 text-sm font-medium leading-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
className
)}
{...props}
/>
)
}
export { Label }
Examples
Labelled fields
A label bound to an input by `htmlFor`, a required field with an asterisk, and a disabled field whose label dims automatically via `group-data-[disabled]`.
Packages
Props
No props documented yet.
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export default function LabelFields01() {
return (
<div className="grid w-full max-w-sm gap-6">
<div className="grid gap-2">
<Label htmlFor="name">Full name</Label>
<Input id="name" placeholder="Ada Lovelace" />
</div>
<div className="grid gap-2">
<Label htmlFor="email">
Email
<span className="text-destructive">*</span>
</Label>
<Input id="email" type="email" placeholder="[email protected]" required />
</div>
<div className="group grid gap-2" data-disabled="true">
<Label htmlFor="account">Account ID</Label>
<Input id="account" defaultValue="acct_4Xa92" disabled />
</div>
</div>
)
}
The Shadcn Label names the controls in your forms — the canonical shadcn/ui label, a thin wrapper over Radix Label that adds accessible association and tidy disabled handling. Pair it with an Input — or any form control — to give every field a clear, clickable name.
When to use
Use a label for every form control — inputs, selects, checkboxes, switches, radios. It is not decorative: the association is what lets assistive technology announce the field, and it enlarges the click target so tapping the label focuses or toggles the control. A placeholder is not a substitute, since it vanishes on input and is unreliably announced.
Association
Bind the label to its control by setting htmlFor on the label to the control's id — htmlFor="email" with id="email". Built on Radix Label, the component forwards a click to the bound control and prevents accidental text selection when users double-click the label. Keep the label text short and specific; describe the value, not the action.
States
Mark a required field by adding a small * (or an "Optional" hint on the others) so expectations are clear before submission. When a field is disabled, the label dims automatically: it reads group-data-[disabled] from the surrounding form group and peer-disabled from a sibling control, lowering its opacity so the whole field reads as inactive — no extra classes needed.
Accessibility
A bound label is the most robust way to give a field an accessible name. When a design has no visible label, fall back to an aria-label on the control itself, but prefer a visible Label wherever possible. Group related controls (like a set of radios) with a fieldset and legend in addition to per-control labels.
Theming
The label inherits your typography and --foreground token, so it follows your theme — including dark mode — with zero overrides. It carries no color of its own beyond the text, which keeps it consistent across every form in your app.