# 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.

Source: https://designrevision.com/components/label

The **Shadcn Label** names the controls in your forms — the canonical <a href="https://ui.shadcn.com/docs/components/label" rel="nofollow">shadcn/ui</a> label, a thin wrapper over <a href="https://www.radix-ui.com/primitives/docs/components/label" rel="nofollow">Radix Label</a> that adds accessible association and tidy disabled handling. Pair it with an [Input](/components/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](/components/input) 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.

## Installation

### label

**Install:**

```bash
npx shadcn@latest add @designrevision/label
```

**Dependencies:** @radix-ui/react-label, utils

**Props**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| htmlFor | string | — | Id of the input this label is bound to. Clicking the label then focuses that input. |

**Usage & accessibility:** Extends the Radix Label Root (@radix-ui/react-label) — all native <label> attributes are supported.

```tsx
// components/ui/label.tsx
"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]`.

**Install:**

```bash
npx shadcn@latest add @designrevision/label-fields-01
```

**Dependencies:** label, input

```tsx
// components/ui/label-fields-01.tsx
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="you@example.com" 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>
  )
}
```
