# Checkbox

Select or clear an independent option.

Terms checkbox

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

```tsx
"use client";

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

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

## Installation

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

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

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

For this page’s examples, also install:

```bash
pnpm dlx shadcn@4.18.0 add @siteplane/button @siteplane/form @siteplane/input @siteplane/label
```

Field is installed with Input.

## Usage

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

<Label>
  <Checkbox />
  Accept terms and conditions
</Label>;
```

## With description

Inside a `Field`, wrap the checkbox and its text in `FieldLabel` and add a `FieldDescription`. The Field connects the description to the checkbox, so it is announced separately from the name, and the description starts under the label text.

Checkbox with description

[Complete TSX file](/examples/checkbox/with-description.tsx)

```tsx
"use client";

import { Checkbox } from "@/siteplane/components/checkbox";
import {
  Field,
  FieldDescription,
  FieldLabel,
} from "@/siteplane/components/field";

export default function Example() {
  return (
    <Field>
      <FieldLabel>
        <Checkbox defaultChecked />
        Email me product updates
      </FieldLabel>
      <FieldDescription>
        News about features and releases, at most once a month.
      </FieldDescription>
    </Field>
  );
}
```

## Disabled and invalid

`disabled` blocks interaction and leaves the value out of form data. `aria-invalid` only applies the invalid style; it does not validate.

Disabled and invalid checkboxes

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

```tsx
"use client";

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

export default function Example() {
  return (
    <div className="grid gap-3">
      <Label>
        <Checkbox disabled />
        Share usage data
      </Label>
      <Label>
        <Checkbox defaultChecked disabled />
        Receive security alerts
      </Label>
      <Label>
        <Checkbox aria-invalid />
        Accept terms and conditions
      </Label>
    </div>
  );
}
```

## Card style

Wrap the checkbox and its text in `Label variant="card"` so the whole card toggles the option. Label owns the shared hover, checked and disabled styles, so no extra state is needed.

Checkbox card

[Complete TSX file](/examples/checkbox/card-style.tsx)

```tsx
"use client";

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

export default function Example() {
  return (
    <Label variant="card" className="flex w-full max-w-sm items-start">
      <Checkbox defaultChecked />
      <span className="flex flex-col gap-1">
        <span>Enable notifications</span>
        <span className="text-muted-foreground text-xs">
          You can enable or disable notifications at any time.
        </span>
      </span>
    </Label>
  );
}
```

## Controlled state

Pass `checked` with `onCheckedChange` when your application owns the value; otherwise use `defaultChecked`.

Controlled checkbox

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

```tsx
"use client";

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

export default function Example() {
  const [checked, setChecked] = useState(false);
  return (
    <Label>
      <Checkbox checked={checked} onCheckedChange={setChecked} />
      Show archived projects
    </Label>
  );
}
```

## Form integration

Inside a `Field`, the checkbox uses the field’s `name`. A checked box submits its `value` (`on` when none is set); an unchecked box submits nothing unless you set `uncheckedValue`.

Checkbox in a form

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

```tsx
"use client";

import { Button } from "@/siteplane/components/button";
import { Checkbox } from "@/siteplane/components/checkbox";
import { Field, FieldLabel } from "@/siteplane/components/field";
import { Form } from "@/siteplane/components/form";

export default function Example() {
  return (
    <Form
      className="grid w-full max-w-sm gap-4"
      onSubmit={(event) => {
        event.preventDefault();
      }}
    >
      <Field name="terms">
        <FieldLabel>
          <Checkbox value="yes" />
          Accept terms and conditions
        </FieldLabel>
      </Field>
      <Button type="submit">Continue</Button>
    </Form>
  );
}
```

## Sizes

Omit `size` to inherit the Checkbox Group size, then the provider’s control size.

Checkbox sizes

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

```tsx
"use client";

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

const sizes = [
  ["sm", "Small"],
  ["md", "Medium"],
  ["lg", "Large"],
  ["xl", "Extra large"],
] as const;

export default function Example() {
  return (
    <div className="flex flex-wrap gap-4">
      {sizes.map(([size, label]) => (
        <Label key={size}>
          <Checkbox defaultChecked size={size} />
          {label}
        </Label>
      ))}
    </div>
  );
}
```

## API reference

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| size | sm \| md \| lg \| xl | group / provider / lg | Control dimensions. |
| children | ReactNode | unset | Rendered only for menu-item; the control supplies its own indicator. |
| checked / defaultChecked | boolean | unset / false | Controlled state or initial state. |
| onCheckedChange | (checked, eventDetails) => void | unset | Called when the user changes the checked state. |
| indeterminate | boolean | false | Shows the mixed state. A parent checkbox in Checkbox Group derives it automatically. |
| disabled | boolean | false | Prevents interaction. |
| name / value | string | unset | Native form participation. A checked box submits value (on if value is unset). |
| uncheckedValue | string | unset | Value submitted while the box is unchecked. |

`CheckboxProps` describes the size extension; `CheckboxPrimitive` is the Base UI namespace. Other props, including `required`, `readOnly`, `parent`, `render` and `inputRef`, follow [Base UI Checkbox](https://base-ui.com/react/components/checkbox). Styled className is a string.

`CheckboxSizeContext` is exported with a null default; CheckboxGroup uses it to share size. `checkboxVariants({ className })` returns the utility classes Checkbox adds beside its stylesheet. The look and the size come from the kit stylesheet through the attributes Checkbox renders; the helper does not resolve context or supply indicator behavior.

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

## Usage notes

A checked box fills with the brand accent, and its check takes the text color for accent fills, `--sp-rw-fg-on-accent`, which a light brand sets dark ([Theming](/docs/customization/theming/#override-component-colors)).

Space changes the focused control. Supply a visible associated Label or an accessible name. Use [Checkbox Group](/docs/components/checkbox-group/) for multiple related choices, including a [parent checkbox](/docs/components/checkbox-group/#parent-checkbox), and [Radio Group](/docs/components/radio-group/) for exactly one choice.
