Label
<Label> is the form-field label primitive. Composes Radix Label for proper htmlFor / focus semantics and styles to match the design system’s 12px medium label scale.
When to use
- Above any form input — required for accessibility.
- Before a Checkbox / Radio / Switch when the row needs a clickable text label.
Don’t use Label for: section headings (use H4), table column labels (use <Text variant="label">), or arbitrary metadata text (use <Text>).
With Input
The two patterns: htmlFor (label sits above) or wrapping (label is the entire clickable area).
<Label htmlFor="email">Email</Label><Input id="email" type="email" />With Checkbox
Wrapping pattern — clicking the label toggles the checkbox.
<Label className="flex items-center gap-2"> <Checkbox id="terms" /> I agree to the terms</Label>API
| Prop | Type | Default | Description |
|---|---|---|---|
htmlFor | string | — | ID of the input this label describes. |
className | string | — | Forwarded. |
children | ReactNode | — | Label text — sentence case, end in no punctuation. |
Design guidelines
✓ Do
- Tie every Label to an input via `htmlFor` or by wrapping. Both work; pick by layout.
- Sentence case, no colon, no asterisk for required. "Email" not "Email:". Required-marker is implicit by being on a form.
- Keep labels short — one to three words. Long descriptions go below as a Text variant="muted".
✗ Don't
- Use Label for non-form text. There are dedicated Typography primitives for that.
- End the label with a colon. Visual designers in 1998 thought it was clarifying; we know better now.
- Hide a Label visually with display:none. Use sr-only or set aria-label on the input instead.
Accessibility
- Composes Radix Label which forwards focus to the associated input on click.
- Either
htmlFor={input.id}or wrap the input — both are equally valid. Wrapping has a slightly larger click target. - For visually-hidden labels, use Tailwind’s
sr-onlyutility (kept in DOM, hidden from sighted users).