Skip to main content

Overview

Unchecked
Checked
Indeterminate
Disabled
Disabled checked
Checkbox allows users to select one or more items from a list, or toggle a single setting on or off. It supports labels, descriptions, disabled states, and an indeterminate state for “select all” patterns.

Installation

npm install @araf-ds/core

Usage

import { Checkbox } from "@araf-ds/core"

export default function Example() {
  return (
    <Checkbox label="Accept terms and conditions" />
  )
}

Variants

Basic

Accept terms and conditions
<Checkbox label="Accept terms and conditions" />

Checked

Subscribe to newsletter
<Checkbox label="Subscribe to newsletter" defaultChecked />

With Description

Enable notifications
Receive email updates about your account activity.
<Checkbox
  label="Enable notifications"
  description="Receive email updates about your account activity."
  defaultChecked
/>

Disabled

Admin access
Super admin
<Checkbox label="Admin access" disabled />
<Checkbox label="Super admin" disabled defaultChecked />

Indeterminate (Select All)

Use the indeterminate state to represent a “select all” parent checkbox when only some children are selected.
Select all
Design
Engineering
Product
const [items, setItems] = useState([true, false, false]);
const allChecked = items.every(Boolean);
const someChecked = items.some(Boolean) && !allChecked;

<Checkbox
  checked={allChecked ? true : someChecked ? "indeterminate" : false}
  onCheckedChange={(checked) => setItems(items.map(() => !!checked))}
  label="Select all"
/>

Checkbox Group Pattern

const options = ["Design", "Engineering", "Product"];
const [selected, setSelected] = useState<string[]>(["Design"]);

const toggle = (val: string) =>
  setSelected((prev) =>
    prev.includes(val) ? prev.filter((v) => v !== val) : [...prev, val]
  );

<div className="flex flex-col gap-3">
  {options.map((opt) => (
    <Checkbox
      key={opt}
      label={opt}
      checked={selected.includes(opt)}
      onCheckedChange={() => toggle(opt)}
    />
  ))}
</div>

API Reference

checked
boolean | 'indeterminate'
Controlled checked state. Use "indeterminate" to show a dash/mixed state.
defaultChecked
boolean
default:"false"
Uncontrolled initial checked state.
onCheckedChange
(checked: boolean) => void
Callback fired when the checked state changes.
label
string
Label text displayed next to the checkbox.
description
string
Supporting description shown below the label.
disabled
boolean
default:"false"
Disables the checkbox and applies the disabled visual style.
id
string
HTML id for associating a custom <label> element via htmlFor.
className
string
Additional Tailwind classes for custom overrides.

Accessibility

  • Checkbox uses a native <input type="checkbox"> element for full keyboard and screen reader support
  • Label is associated via htmlFor / id — clicking the label also toggles the checkbox
  • description is linked via aria-describedby so screen readers announce it after the label
  • disabled uses the native disabled attribute, removing the element from tab order
  • Indeterminate state is set via aria-checked="mixed" — screen readers will announce “mixed”
  • Focus ring (0 0 0 4px #CDE4F5) meets WCAG 2.1 AA contrast requirements

Do’s & Don’ts

Do

  • Use checkbox for multi-select or toggleable settings
  • Always provide a visible label — never a checkbox alone
  • Use the indeterminate state for “select all” parent checkboxes
  • Group related checkboxes under a clear section heading

Don't

  • Don’t use checkbox for exclusive single-selection — use Radio Group instead
  • Don’t use checkbox for immediate actions — use Switch instead
  • Don’t stack more than 8 checkboxes without grouping or filtering
  • Don’t disable without explaining why in nearby helper text