# Label

Give a native form control a visible accessible name.

Workspace name label

[Complete TSX file](/examples/label/default.tsx)

```tsx
"use client";

import { Input } from "@/siteplane/components/input";
import { Label } from "@/siteplane/components/label";
import { useId } from "react";

export default function Example() {
  const id = useId();
  return (
    <div className="grid w-full max-w-sm gap-2">
      <Label htmlFor={id}>Workspace name</Label>
      <Input id={id} name="workspace" />
    </div>
  );
}
```

## Installation

Complete [one-time setup](/docs/installation/) first.

```bash
pnpm dlx shadcn@4.18.0 add @siteplane/label
```

With npm: `npx shadcn@4.18.0 add @siteplane/label`. [Registry JSON](/registry/label.json) lists source files and dependencies.

For this page’s examples, also install:

```bash
pnpm dlx shadcn@4.18.0 add @siteplane/checkbox @siteplane/input
```

## Usage

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

<Label htmlFor="workspace">Workspace name</Label>;
```

## Required fields and help

Label marks nothing as required and connects no help text. Compose a [Field](/docs/components/field/) for both: `requiredIndicator` marks its label while the control is `required`, and the Field connects a `FieldDescription` to the control.

Required email with help text

[Complete TSX file](/examples/label/help.tsx)

```tsx
"use client";

import {
  Field,
  FieldDescription,
  FieldLabel,
} from "@/siteplane/components/field";
import { Input } from "@/siteplane/components/input";

export default function Example() {
  return (
    <Field className="w-full max-w-sm" name="email" requiredIndicator>
      <FieldLabel>Contact email</FieldLabel>
      <Input required type="email" />
      <FieldDescription>Used for account notifications.</FieldDescription>
    </Field>
  );
}
```

## With a checkbox

Wrap a Checkbox and its text in Label so clicking the text toggles it. The checkbox sits on the first line of the text, also when the text wraps. Label adds no validation.

A label above a field uses the 16 px line of FieldLabel. A label beside a checkbox, radio or switch keeps the 21 px body line, because such labels are sentences and often wrap.

Terms checkbox label

[Complete TSX file](/examples/label/checkbox.tsx)

```tsx
"use client";

import { Checkbox } from "@/siteplane/components/checkbox";
import { Label } from "@/siteplane/components/label";

export default function Example() {
  return (
    <Label>
      <Checkbox name="terms" />
      Accept terms and conditions
    </Label>
  );
}
```

## Choice cards

Use `variant="card"` around a Checkbox, Radio or Switch. Label owns the shared
border, padding, hover, checked and disabled presentation; do not copy these
state classes into your own components. Keep secondary action buttons outside
the label.

## API reference

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| variant | default \| card | default | Plain association or shared choice-card presentation. |
| htmlFor | string | unset | ID of the labeled control. |
| render | ReactElement \| render function | label | Composed element; replacing label removes native label behavior unless restored by the application. |
| children | ReactNode | unset | Visible label. |
| className | string | unset | Additional styling. |

Remaining props and refs follow the native label and [Base UI composition](https://base-ui.com/react/handbook/composition). Label adds no validation or control state. It dims as disabled when it carries `data-disabled` or holds a disabled form control, such as an input, a textarea, a Select trigger, a checkbox or the segments of a date field. A disabled button inside it does not dim it. There is no owned `disabled` prop.

[Read the installed source](/source/label).

## Usage notes

Use [Field](/docs/components/field/) and FieldLabel when automatic field association and validation are needed. Label and FieldLabel are distinct components. Clicking a native associated label focuses or activates its control.
