# Checkbox

A control that allows the user to toggle between checked and not checked.

Page: https://sui.draco.dev/docs/components/checkbox

### Example: checkbox-demo

```tsx
"use client";

import { Checkbox } from "@workspace/ui/components/checkbox";
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldTitle,
} from "@workspace/ui/components/field";
import { Label } from "@workspace/ui/components/label";
import { useId as usePreviewId } from "react";

export default function CheckboxDemo() {
  const previewId = usePreviewId();

  return (
    <FieldGroup className="max-w-sm">
      <Field orientation="horizontal">
        <Checkbox id={`${previewId}-terms-checkbox`} name="terms-checkbox" />
        <Label htmlFor={`${previewId}-terms-checkbox`}>
          Accept terms and conditions
        </Label>
      </Field>
      <Field orientation="horizontal">
        <Checkbox
          id={`${previewId}-terms-checkbox-2`}
          name="terms-checkbox-2"
          defaultChecked
        />
        <FieldContent>
          <FieldLabel htmlFor={`${previewId}-terms-checkbox-2`}>
            Accept terms and conditions
          </FieldLabel>
          <FieldDescription>
            By clicking this checkbox, you agree to the terms.
          </FieldDescription>
        </FieldContent>
      </Field>
      <Field orientation="horizontal" data-disabled>
        <Checkbox
          id={`${previewId}-toggle-checkbox`}
          name="toggle-checkbox"
          disabled
        />
        <FieldLabel htmlFor={`${previewId}-toggle-checkbox`}>
          Enable notifications
        </FieldLabel>
      </Field>
      <FieldLabel>
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-toggle-checkbox-2`}
            name="toggle-checkbox-2"
          />
          <FieldContent>
            <FieldTitle>Enable notifications</FieldTitle>
            <FieldDescription>
              You can enable or disable notifications at any time.
            </FieldDescription>
          </FieldContent>
        </Field>
      </FieldLabel>
    </FieldGroup>
  );
}
```

## Installation

```bash
bunx --bun shadcn@latest add @sui/checkbox
```

Install with the shadcn CLI or use the shared `@workspace/ui` package. Follow the [installation guide](/docs/installation) to configure the registry, load styles, and choose import aliases.

## Usage

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox"
```

```tsx
<Checkbox />
```

## Checked State

Use `defaultChecked` for uncontrolled checkboxes, or `checked` and
`onCheckedChange` to control the state.

```tsx showLineNumbers
import * as React from "react"

export function Example() {
  const [checked, setChecked] = React.useState(false)

  return <Checkbox checked={checked} onCheckedChange={setChecked} />
}
```

## Invalid State

Set `aria-invalid` on the checkbox and `data-invalid` on the field wrapper to
show the invalid styles.

### Example: checkbox-invalid

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox";
import { Field, FieldGroup, FieldLabel } from "@workspace/ui/components/field";
import { useId as usePreviewId } from "react";

export function CheckboxInvalid() {
  const previewId = usePreviewId();

  return (
    <FieldGroup className="mx-auto w-56">
      <Field orientation="horizontal" data-invalid>
        <Checkbox
          id={`${previewId}-terms-checkbox-invalid`}
          name="terms-checkbox-invalid"
          aria-invalid
        />
        <FieldLabel htmlFor={`${previewId}-terms-checkbox-invalid`}>
          Accept terms and conditions
        </FieldLabel>
      </Field>
    </FieldGroup>
  );
}

export default CheckboxInvalid;
```

## Basic

Pair the checkbox with `Field` and `FieldLabel` for proper layout and labeling.

### Example: checkbox-basic

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox";
import { Field, FieldGroup, FieldLabel } from "@workspace/ui/components/field";
import { useId as usePreviewId } from "react";

export function CheckboxBasic() {
  const previewId = usePreviewId();

  return (
    <FieldGroup className="mx-auto w-56">
      <Field orientation="horizontal">
        <Checkbox
          id={`${previewId}-terms-checkbox-basic`}
          name="terms-checkbox-basic"
        />
        <FieldLabel htmlFor={`${previewId}-terms-checkbox-basic`}>
          Accept terms and conditions
        </FieldLabel>
      </Field>
    </FieldGroup>
  );
}

export default CheckboxBasic;
```

## Description

Use `FieldContent` and `FieldDescription` for helper text.

### Example: checkbox-description

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox";
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
} from "@workspace/ui/components/field";
import { useId as usePreviewId } from "react";

export function CheckboxDescription() {
  const previewId = usePreviewId();

  return (
    <FieldGroup className="mx-auto w-72">
      <Field orientation="horizontal">
        <Checkbox
          id={`${previewId}-terms-checkbox-desc`}
          name="terms-checkbox-desc"
          defaultChecked
        />
        <FieldContent>
          <FieldLabel htmlFor={`${previewId}-terms-checkbox-desc`}>
            Accept terms and conditions
          </FieldLabel>
          <FieldDescription>
            By clicking this checkbox, you agree to the terms and conditions.
          </FieldDescription>
        </FieldContent>
      </Field>
    </FieldGroup>
  );
}

export default CheckboxDescription;
```

## Disabled

Use the `disabled` prop to prevent interaction and add the `data-disabled` attribute to the `<Field>` component for disabled styles.

### Example: checkbox-disabled

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox";
import { Field, FieldGroup, FieldLabel } from "@workspace/ui/components/field";
import { useId as usePreviewId } from "react";

export function CheckboxDisabled() {
  const previewId = usePreviewId();

  return (
    <FieldGroup className="mx-auto w-56">
      <Field orientation="horizontal" data-disabled>
        <Checkbox
          id={`${previewId}-toggle-checkbox-disabled`}
          name="toggle-checkbox-disabled"
          disabled
        />
        <FieldLabel htmlFor={`${previewId}-toggle-checkbox-disabled`}>
          Enable notifications
        </FieldLabel>
      </Field>
    </FieldGroup>
  );
}

export default CheckboxDisabled;
```

## Group

Use multiple fields to create a checkbox list.

### Example: checkbox-group

```tsx
import { Checkbox } from "@workspace/ui/components/checkbox";
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSet,
} from "@workspace/ui/components/field";
import { useId as usePreviewId } from "react";

export function CheckboxGroup() {
  const previewId = usePreviewId();

  return (
    <FieldSet>
      <FieldLegend variant="label">
        Show these items on the desktop:
      </FieldLegend>
      <FieldDescription>
        Select the items you want to show on the desktop.
      </FieldDescription>
      <FieldGroup className="gap-3">
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-finder-pref-9k2-hard-disks-ljj-checkbox`}
            name="finder-pref-9k2-hard-disks-ljj-checkbox"
            defaultChecked
          />
          <FieldLabel
            htmlFor={`${previewId}-finder-pref-9k2-hard-disks-ljj-checkbox`}
            className="font-normal"
          >
            Hard disks
          </FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-finder-pref-9k2-external-disks-1yg-checkbox`}
            name="finder-pref-9k2-external-disks-1yg-checkbox"
            defaultChecked
          />
          <FieldLabel
            htmlFor={`${previewId}-finder-pref-9k2-external-disks-1yg-checkbox`}
            className="font-normal"
          >
            External disks
          </FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-finder-pref-9k2-cds-dvds-fzt-checkbox`}
            name="finder-pref-9k2-cds-dvds-fzt-checkbox"
          />
          <FieldLabel
            htmlFor={`${previewId}-finder-pref-9k2-cds-dvds-fzt-checkbox`}
            className="font-normal"
          >
            CDs, DVDs, and iPods
          </FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-finder-pref-9k2-connected-servers-6l2-checkbox`}
            name="finder-pref-9k2-connected-servers-6l2-checkbox"
          />
          <FieldLabel
            htmlFor={`${previewId}-finder-pref-9k2-connected-servers-6l2-checkbox`}
            className="font-normal"
          >
            Connected servers
          </FieldLabel>
        </Field>
      </FieldGroup>
    </FieldSet>
  );
}

export default CheckboxGroup;
```

## Table

### Example: checkbox-table

```tsx
"use client";

import { Checkbox } from "@workspace/ui/components/checkbox";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@workspace/ui/components/table";
import * as React from "react";
import { useId as usePreviewId } from "react";

const tableData = [
  {
    id: "1",
    name: "Sarah Chen",
    email: "sarah.chen@example.com",
    role: "Admin",
  },
  {
    id: "2",
    name: "Marcus Rodriguez",
    email: "marcus.rodriguez@example.com",
    role: "User",
  },
  {
    id: "3",
    name: "Priya Patel",
    email: "priya.patel@example.com",
    role: "User",
  },
  {
    id: "4",
    name: "David Kim",
    email: "david.kim@example.com",
    role: "Editor",
  },
];

export function CheckboxInTable() {
  const previewId = usePreviewId();

  const [selectedRows, setSelectedRows] = React.useState<Set<string>>(
    new Set(["1"]),
  );

  const selectAll = selectedRows.size === tableData.length;

  const handleSelectAll = (checked: boolean) => {
    if (checked) {
      setSelectedRows(new Set(tableData.map((row) => row.id)));
    } else {
      setSelectedRows(new Set());
    }
  };

  const handleSelectRow = (id: string, checked: boolean) => {
    const newSelected = new Set(selectedRows);
    if (checked) {
      newSelected.add(id);
    } else {
      newSelected.delete(id);
    }
    setSelectedRows(newSelected);
  };

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead className="w-8">
            <Checkbox
              id={`${previewId}-select-all-checkbox`}
              name="select-all-checkbox"
              checked={selectAll}
              onCheckedChange={handleSelectAll}
            />
          </TableHead>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {tableData.map((row) => (
          <TableRow
            key={row.id}
            data-state={selectedRows.has(row.id) ? "selected" : undefined}
          >
            <TableCell>
              <Checkbox
                id={`row-${row.id}-checkbox`}
                name={`row-${row.id}-checkbox`}
                checked={selectedRows.has(row.id)}
                onCheckedChange={(checked) =>
                  handleSelectRow(row.id, checked === true)
                }
              />
            </TableCell>
            <TableCell className="font-medium">{row.name}</TableCell>
            <TableCell>{row.email}</TableCell>
            <TableCell>{row.role}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}

export default CheckboxInTable;
```

## RTL

To enable RTL support in shadcn/ui, see the [RTL configuration guide](https://ui.shadcn.com/docs/rtl).

### Example: checkbox-rtl

```tsx
"use client";

import { Checkbox } from "@workspace/ui/components/checkbox";
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldTitle,
} from "@workspace/ui/components/field";
import { Label } from "@workspace/ui/components/label";
import { useId as usePreviewId } from "react";
import { type Translations, useTranslation } from "./support";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      acceptTerms: "Accept terms and conditions",
      acceptTermsDescription:
        "By clicking this checkbox, you agree to the terms.",
      enableNotifications: "Enable notifications",
      enableNotificationsDescription:
        "You can enable or disable notifications at any time.",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      acceptTerms: "قبول الشروط والأحكام",
      acceptTermsDescription: "بالنقر على هذا المربع، فإنك توافق على الشروط.",
      enableNotifications: "تفعيل الإشعارات",
      enableNotificationsDescription:
        "يمكنك تفعيل أو إلغاء تفعيل الإشعارات في أي وقت.",
    },
  },
  he: {
    dir: "rtl",
    values: {
      acceptTerms: "קבל תנאים והגבלות",
      acceptTermsDescription:
        "על ידי לחיצה על תיבת הסימון הזו, אתה מסכים לתנאים.",
      enableNotifications: "הפעל התראות",
      enableNotificationsDescription:
        "אתה יכול להפעיל או להשבית התראות בכל עת.",
    },
  },
};

export function CheckboxRtl() {
  const previewId = usePreviewId();

  const { dir, t } = useTranslation(translations, "ar");

  return (
    <FieldGroup className="max-w-sm" dir={dir}>
      <Field orientation="horizontal">
        <Checkbox
          id={`${previewId}-terms-checkbox-rtl`}
          name="terms-checkbox"
        />
        <Label htmlFor={`${previewId}-terms-checkbox-rtl`}>
          {t.acceptTerms}
        </Label>
      </Field>
      <Field orientation="horizontal">
        <Checkbox
          id={`${previewId}-terms-checkbox-2-rtl`}
          name="terms-checkbox-2"
          defaultChecked
        />
        <FieldContent>
          <FieldLabel htmlFor={`${previewId}-terms-checkbox-2-rtl`}>
            {t.acceptTerms}
          </FieldLabel>
          <FieldDescription>{t.acceptTermsDescription}</FieldDescription>
        </FieldContent>
      </Field>
      <Field orientation="horizontal" data-disabled>
        <Checkbox
          id={`${previewId}-toggle-checkbox-rtl`}
          name="toggle-checkbox"
          disabled
        />
        <FieldLabel htmlFor={`${previewId}-toggle-checkbox-rtl`}>
          {t.enableNotifications}
        </FieldLabel>
      </Field>
      <FieldLabel>
        <Field orientation="horizontal">
          <Checkbox
            id={`${previewId}-toggle-checkbox-2`}
            name="toggle-checkbox-2"
          />
          <FieldContent>
            <FieldTitle>{t.enableNotifications}</FieldTitle>
            <FieldDescription>
              {t.enableNotificationsDescription}
            </FieldDescription>
          </FieldContent>
        </Field>
      </FieldLabel>
    </FieldGroup>
  );
}

export default CheckboxRtl;
```

## API Reference

See the [Base UI](https://base-ui.com/react/components/checkbox#api-reference) documentation for more information.

- [Documentation](https://base-ui.com/react/components/checkbox)
- [API reference](https://base-ui.com/react/components/checkbox#api-reference)
