Skip to content

Checkbox

Turns one option on or off, or shows a mixed state for a group.

Library
What’s this?

Reps won't see this contact in call lists.

Installation

pnpm dlx shadcn@latest add @wisty/checkbox

The CLI installs the Radix or Base UI file to match your project.

If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.

When to use

Use it

  • People turn one option on or off, like a contact's Email Opt Out or Do Not Call.
  • People pick any number of options from a short list. Group the checkboxes in a FieldSet.
  • A row in a table can be selected. Put a checkbox in the row's first cell.
  • The choice takes effect when people save, not at once.

Don't use it

  • The choice takes effect at once, like turning a setting on. Use Switch.
  • People pick exactly one option. Use Radio Group, or Select for a long list.
  • The list is long or searchable. Use Combobox.

Usage

Give each checkbox a label: a Label after it with htmlFor set to its id, or a Field with orientation="horizontal", as the Contact preferences example shows.

import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
<div className="flex items-center gap-2">
  <Checkbox id="fax-opt-out" />
  <Label htmlFor="fax-opt-out">Fax Opt Out</Label>
</div>

To control it, pass checked and onCheckedChange; to only set where it starts, pass defaultChecked.

For the mixed state, in Radix projects pass checked="indeterminate", and onCheckedChange may then receive "indeterminate" as well as true or false. In Base UI projects, pass the separate indeterminate prop. Both draw the same dash.

Examples

States

Unchecked and checked, then `disabled` and `aria-invalid`, each unchecked and checked.

API reference

Checkbox

Also takes every Radix Checkbox.Root (opens in a new tab) prop.

SLDS mapping

Checkbox is slds-checkbox_faux, the box SLDS draws for slds-checkbox. Checked is its :checked fill, the mixed state its :indeterminate dash, aria-invalid is slds-has-error, and disabled is SLDS's gray box. A Label beside a checkbox is regular weight, as SLDS's checkbox labels are.

Known gaps:

  • The check is lucide's CheckIcon, sized to SLDS's mark. SLDS draws its check with borders, so the stroke ends differ a little.

Accessibility

  • In a table, name a row's checkbox with aria-label, like "Select Acme Corporation".
  • In a choice card, where a label wraps the whole card, point the checkbox's aria-labelledby at the FieldTitle and its aria-describedby at the description, as the Contact preferences example does. Otherwise the card's whole text becomes its name.
  • Group related checkboxes in a FieldSet with a FieldLegend, so the group has a name.
  • Pair aria-invalid with an error message the checkbox points to through aria-describedby.

Responsive behavior

  • Long labels wrap next to the box. Align the box to the first line with items-start on the row.

Rules

  • Use aria-invalid for errors. Don't add border or color classes: the error look differs per theme.
  • Don't dim a disabled checkbox with opacity classes. The gray box is the disabled look, and the label beside it stays readable.