# Label

An accessible form label that associates with its input and responds to disabled state.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. An agent skill is available at [/.well-known/agent-skills/site-skill.md](/.well-known/agent-skills/site-skill.md).





<ComponentThemeTabs>
  <ThemeTab name="mint">
    <PreviewWithCode name="label">
      <LabelDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="berries">
    <PreviewWithCode name="label">
      <LabelDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="citrine">
    <PreviewWithCode name="label">
      <LabelDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="cinnamon">
    <PreviewWithCode name="label">
      <LabelDemo />
    </PreviewWithCode>
  </ThemeTab>
</ComponentThemeTabs>

## With input [#with-input]

Associate a label to a field with a matching `htmlFor` / `id` pair. Clicking the label focuses the input.

```tsx
<div className="flex flex-col gap-1.5">
  <Label htmlFor="email">Email address</Label>
  <Input id="email" type="email" placeholder="you@example.com" />
</div>
```

## Required indicator [#required-indicator]

Append a `<span className="text-destructive">*</span>` as a child to mark a required field. `Label` is `flex` so it aligns children naturally.

```tsx
<Label htmlFor="username">
  Username
  <span className="text-destructive">*</span>
</Label>
```

## Disabled [#disabled]

When the associated input is `disabled`, `Label` uses the `peer-disabled:` selectors to reduce opacity and show `cursor-not-allowed`. Place the input **before** the label in the DOM, or use the `Field` component which handles this automatically.

```tsx
<div className="flex flex-col gap-1.5">
  <Label htmlFor="api-key">API key</Label>
  <Input id="api-key" disabled />
</div>
```

## With Field [#with-field]

`Field` auto-generates the `id`, wires `htmlFor`, and propagates `error` / `required` state — no manual `htmlFor` / `id` needed.

```tsx
import {
  Field,
  FieldDescription,
  FieldError,
  FieldLabel,
} from "@/components/ui/field";

<Field required error="Email is required.">
  <FieldLabel>Email</FieldLabel>
  <Input type="email" placeholder="you@example.com" />
  <FieldError />
</Field>
```

## With icon [#with-icon]

`Label` is a flex row — prefix it with any inline element.

```tsx
<Label htmlFor="name" className="cursor-pointer">
  <UserIcon className="size-4" />
  Full name
</Label>
<Input id="name" placeholder="Nuno Santos" />
```

## Props [#props]

<span className="block">
  Extends all props from 

  `LabelPrimitive.Root`

   (Radix UI Label).
</span>

| Prop        | Type     | Default | Description                       |
| ----------- | -------- | ------- | --------------------------------- |
| `htmlFor`   | `string` | —       | ID of the associated form control |
| `className` | `string` | —       | Merged after base classes         |

## Usage [#usage]

```tsx
import { Label } from "@/components/ui/label";

<Label htmlFor="email">Email address</Label>
```

## Specs [#specs]

```md
# Mint — Label Specs

## Component
- name: label
- file: registry/mint/label.tsx
- installs to: components/ui/label.tsx
- dependencies: radix-ui
- registryDependencies: none

## What is it
A styled wrapper around Radix UI Label.Root that renders a native `<label>`
element. Its primary use case is associating a visible text label with a form
control via `htmlFor` / `id`. Prefer the `Field` compound component when the
field also needs a description or error message — `Field` handles ID generation
and aria wiring automatically.

## Visual identity
Plain text treatment in Mint: 14px medium-weight type, tight leading, and
`select-none` to prevent accidental text selection. Rendered as a flex row so
icons or required-field markers align without extra layout work.

## Design tokens
No explicit colour tokens — inherits `--foreground` from the page. Disabled
states rely on opacity reduction rather than a dedicated token.

## States
- peer-disabled:cursor-not-allowed: shows `not-allowed` cursor when the
  preceding sibling input is disabled; input must appear before label in DOM
- peer-disabled:opacity-70: reduces label opacity when the peer input is
  disabled
- group-data-[disabled=true]:pointer-events-none: disables pointer events when
  a parent group (e.g. Field / fieldset) carries `data-disabled=true`
- group-data-[disabled=true]:opacity-50: reduces opacity when the parent group
  is disabled

## Conventions
- Always pair with a form control via `htmlFor` + matching `id`; Radix
  Label.Root clicks forward to the associated control automatically
- Required-field indicator: add `<span className="text-destructive">*</span>`
  as a child — the flex layout aligns it inline
- Icon prefix: prepend any `size-4` inline element as a child; gap-2 handles
  spacing automatically
- For full form fields (description, error), use the `Field` compound
  component instead of wiring `htmlFor` / `id` manually
- Sub-components expose `data-slot="label"` for CSS targeting
```

## Installation [#installation]

<CommandBox componentName="label" className="mt-2" />
