Skip to content

Checkbox

A box for a yes/no choice, or for choosing several options. Primary and neutral, three sizes, checked, indeterminate, read-only, disabled and error.

Version 0.4.1 ·

Checkbox states

Installation

bunx --bun shadcn@latest add @dga/checkbox

Installs Field too.

Usage

page.tsx
tsx
import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldContent, FieldLabel } from "@/components/ui/field";

export function ConsentField() {
  return (
    <Field orientation="horizontal" name="consent">
      <Checkbox required />
      <FieldContent>
        <FieldLabel>I confirm the information is correct</FieldLabel>
      </FieldContent>
    </Field>
  );
}

Use a Checkbox when someone can choose none, one or several options, or confirm something before submitting. The choice is applied when the form is submitted; for a setting that takes effect at once use Switch. For exactly one of several options use Radio.

Anatomy

  • Box (<span role="checkbox"> and a hidden <input>): the border and fill.
  • Mark: a check, or a dash when indeterminate.
  • Label, helper text and error: from Field, beside the box.

Examples

States

Unchecked, checked, indeterminate, read-only, disabled, error and the neutral style.

States

Sizes

md is 24px (default), sm 20px and xs 16px. The label, not the box, is the click target, so it stays comfortable at every size.

Sizes

Group with a parent

Set indeterminate on the parent when only some children are checked. The parent checks or clears them all.

Group with a parent

RTL

The box is on the right (start) of its label and the helper text lines up under the label. The check mark is not directional, so it is not flipped.

LTR (English)
RTL (Arabic)

Accessibility

KeyAction
TabMoves focus to the checkbox.
SpaceChecks or unchecks it.
  • The checkbox role with aria-checked (true, false or mixed), and a hidden native input for forms.
  • The label is from Field; clicking it toggles the box.
  • The unchecked border is 3:1 or better on every surface; the checked fill and the mark are 3:1 against the surface and against each other (WCAG 1.4.11).
  • Focus is a 2px outline 2px outside the box. Read-only keeps a 3:1 border.
  • Errors show an icon and text with aria-invalid, not a colour change alone.

API Reference

Checkbox

A box for a yes/no choice, or one of several. `indeterminate` shows a dash for a parent that is partly selected. Label it with a Field (`orientation="horizontal"`) or an enclosing label.

Checkbox props
PropTypeDefault
"xs" | "sm" | "md"

Box size: `md` 24px, `sm` 20px, `xs` 16px.

"md"
"primary" | "neutral"

`primary` (green) or `neutral` (black in light mode).

"primary"
boolean

Whether the checkbox is in a mixed state: neither ticked, nor unticked.

No default
boolean

Whether the checkbox is currently ticked. To render an uncontrolled checkbox, use the `defaultChecked` prop instead.

No default
boolean

Whether the checkbox is initially ticked. To render a controlled checkbox, use the `checked` prop instead.

No default
boolean

Whether the component should ignore user interaction.

No default
string

Identifies the field when a form is submitted.

No default
(checked: boolean, details) => void

Event handler called when the checkbox is ticked or unticked.

No default
boolean

Whether the user should be unable to tick or untick the checkbox.

No default
boolean

Whether the user must tick the checkbox before submitting a form.

No default
string

The checkbox's value. Identifies it within a [Checkbox Group](https://base-ui.com/react/components/checkbox-group), falling back to `name` when omitted. When submitting a form, a checked box submits `value`; with no `value`, it submits the native "on".

No default

Also accepts every prop of the Base UI Checkbox (opens in a new tab).

Deviations from DGA

  • In dark mode the checked fill stays green-600 on hover and press, because Figma's lighter greens give the white mark 1.4–2.1:1.
  • The neutral check mark flips with the fill (new token control-icon-neutral).
  • Read-only has a 3:1 border (Figma: 1.5:1).
ChangeReason
--control-primary-hovered (dark) and 1 moreFigma Dark lightens the checked fill on hover and press (green-300/400). The white check mark on it is 1.4–2.1:1. The fill stays green-600 and hover and press show on the ring and background instead.
--control-icon-neutral (new)The check mark on a neutral checkbox. The neutral fill is near-black in light mode and light grey in dark mode (control-neutral-checked), so the mark needs to flip too. Figma's control-icon-* tokens stay white (1.8:1 on the dark-mode fill).
Checkbox, Radio: hover and pressed fill in dark modeA white mark on the lighter fill is 1.4–2.1:1 (see the control-primary-hovered and -pressed fixes).
Checkbox, Radio, Switch: read-onlyThe pale border is 1.5:1 on white. A read-only control keeps a 3:1 boundary.

View all 6 deviations for this component

Contrast

108 pairs checked · all pass WCAG 2.1 AAShow 20 states
Variant / stateLightDark
unchecked border4.57:1 3:13.80:1 3:1
unchecked border, hovered7.04:1 3:112.04:1 3:1
border, error4.62:1 3:14.65:1 3:1
border, read-only4.57:1 3:13.80:1 3:1
focus ring17.31:1 3:117.49:1 3:1
primary / checked (fill)4.54:1 3:13.68:1 3:1
primary / checked (check mark)4.74:1 3:14.74:1 3:1
primary / hovered (fill)8.18:1 3:13.68:1 3:1
primary / hovered (check mark)8.55:1 3:14.74:1 3:1
primary / pressed (fill)10.34:1 3:13.68:1 3:1
primary / pressed (check mark)10.81:1 3:14.74:1 3:1
neutral / checked (fill)17.93:1 3:19.38:1 3:1
neutral / checked (check mark)18.74:1 3:110.07:1 3:1
neutral / hovered (fill)7.04:1 3:112.04:1 3:1
neutral / hovered (check mark)7.36:1 3:112.93:1 3:1
neutral / pressed (fill)4.57:1 3:16.32:1 3:1
neutral / pressed (check mark)4.77:1 3:16.79:1 3:1
read-only mark4.77:1 3:19.38:1 3:1
label14.53:1 AAA15.87:1 AAA
helper text4.77:1 AA6.32:1 AA

Text needs 4.5:1, icons and focus rings 3:1. Disabled states are exempt. Full contrast report