- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Menubar
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Typography
Component label-demo not found in registry.
For form fields, use the Field component which
includes built-in FieldLabel, FieldDescription, and FieldError.
Installation
pnpm dlx createui@latest add label
Usage
Label is the semantic <label> element — use it directly for simple one-line labels.
import { Label } from "@/components/ui/label"
;<Label htmlFor="email">Email</Label>It also accepts inline slots in the title row (icon, required/optional marker, badge, info tooltip):
<Label htmlFor="email">
<LabelIcon>
<MailIcon />
</LabelIcon>
Email
<LabelRequired />
</Label>For richer layouts that need a description and/or a right-aligned counter, wrap everything in LabelBlock:
import {
Label,
LabelBadgeSlot,
LabelBlock,
LabelCount,
LabelDescription,
LabelIcon,
LabelInfoSlot,
LabelMain,
LabelRequired,
} from "@/components/ui/label"
;<LabelBlock size="xs">
<LabelMain>
<Label htmlFor="email">
<LabelIcon>
<MailIcon />
</LabelIcon>
Email
<LabelRequired />
<LabelBadgeSlot>
<Badge size="xs">NEW</Badge>
</LabelBadgeSlot>
<LabelInfoSlot>
<InfoTooltip variant="inverse" size="sm">
We never share your email.
</InfoTooltip>
</LabelInfoSlot>
</Label>
<LabelDescription>
Description or any kind of additional text.
</LabelDescription>
</LabelMain>
<LabelCount>0/300</LabelCount>
</LabelBlock>Sizes
LabelBlock exposes a size variant (xs | sm | md | lg) that cascades to every sub-component via data-size and the group/label selector. Pass size on a sub-component to override for that child. Gaps (root gap-3, column gap-1, title row gap-1) stay constant; only typography and icon sizes scale.
| size | title text | description text | icon | badge size | info tooltip size |
|---|---|---|---|---|---|
| xs | text-ui-sm | text-ui-sm | size-4 | sm | sm |
| sm | text-ui-md | text-ui-md | size-5 | md | md |
| md | text-ui-lg | text-ui-lg | size-6 | md | md |
| lg | text-ui-xl | text-ui-lg | size-6 | lg | lg |
Label in Field
Inside forms, use the Field component — it provides size context, invalid/disabled propagation, and a FieldLabel that renders a semantic <label> wired to the control.
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
<FieldDescription>We'll never share your email.</FieldDescription>
</Field>Accessibility
Labelrenders a semantic<label>only whenhtmlForis set; without it, it falls back to a<span>with no label semantics. Always passhtmlFor(or use the Field component) when pairing a label with a form control.LabelIconis markedaria-hidden="true"; the meaning must be carried by the title text.LabelRequiredis decorative (aria-hidden="true"). Mirror the requirement on the input itself withrequiredand/oraria-required="true".LabelDescriptionrenders a plain<p>and is not auto-wired. OutsideField, give it anidand reference it from the input'saria-describedby:
<LabelBlock>
<LabelMain>
<Label htmlFor="email">Email</Label>
<LabelDescription id="email-desc">
We'll never share your email.
</LabelDescription>
</LabelMain>
</LabelBlock>
<input id="email" aria-describedby="email-desc" />Inside Field, prefer FieldDescription / FieldError which handle this for you.
API Reference
Label
The semantic <label> element (Radix Label.Root) when htmlFor is set, otherwise a <span>. Hosts icon, text, required, optional, badge slot, and info tooltip slot inline.
| Prop | Type | Default |
|---|---|---|
size | "xs" | "sm" | "md" | "lg" | context size |
htmlFor | string | |
className | string |
LabelBlock
Compound root <div> laid out as a row (flex items-end). Provides size to children via data-size and the group/label selector. Use when the label needs a description and/or a right-aligned LabelCount.
| Prop | Type | Default |
|---|---|---|
size | "xs" | "sm" | "md" | "lg" | "sm" |
asChild | boolean | false |
className | string |
LabelMain
Left column (flex-1 flex-col) that holds Label and LabelDescription. Required when using LabelCount.
LabelIcon
Icon slot (<span>) for leading glyphs. Scales to match size.
LabelRequired
Renders the required marker (default *) in text-primary-base.
LabelOptional
Renders the optional hint (default (Optional)) in text-placeholder.
LabelDescription
Helper <p> below the title in text-placeholder.
LabelBadgeSlot
Inline grouping slot (inline-flex gap-1) for one or more Badge components inside the title row. To right-align, pass className="ml-auto".
LabelInfoSlot
Inline slot for an InfoTooltip trigger, sitting after LabelBadgeSlot in the title row.
LabelCount
Right-side counter (e.g. 0/300) rendered next to LabelMain in text-placeholder. Pass any text as children.