Skip to main content
The Checkbox component allows users to select one or more items from a set. It supports individual checkboxes and checkbox groups with support for indeterminate states.

Basic usage

import { Checkbox } from '@raystack/apsara';

function App() {
  return <Checkbox />;
}

Props

Checkbox

checked
boolean | 'indeterminate'
The controlled checked state. Can be true, false, or ‘indeterminate’.
defaultChecked
boolean
The default checked state for uncontrolled usage.
onCheckedChange
(checked: boolean | 'indeterminate') => void
Callback fired when the checked state changes.
disabled
boolean
Whether the checkbox is disabled.
required
boolean
Whether the checkbox is required.
name
string
The name of the checkbox input for form submission.
value
string
The value of the checkbox input for form submission.
className
string
Additional CSS classes to apply to the checkbox.

Checkbox.Group

value
string[]
The controlled array of checked values.
defaultValue
string[]
The default array of checked values for uncontrolled usage.
onValueChange
(value: string[]) => void
Callback fired when the checked values change.
disabled
boolean
Whether all checkboxes in the group are disabled.
className
string
Additional CSS classes to apply to the group container.

Single checkbox

function SingleCheckbox() {
  const [checked, setChecked] = useState(false);

  return (
    <label>
      <Checkbox checked={checked} onCheckedChange={setChecked} />
      <span>Accept terms and conditions</span>
    </label>
  );
}

Checkbox group

function CheckboxGroup() {
  const [values, setValues] = useState([]);

  return (
    <Checkbox.Group value={values} onValueChange={setValues}>
      <label>
        <Checkbox value="react" />
        <span>React</span>
      </label>
      <label>
        <Checkbox value="vue" />
        <span>Vue</span>
      </label>
      <label>
        <Checkbox value="angular" />
        <span>Angular</span>
      </label>
    </Checkbox.Group>
  );
}

Indeterminate state

function IndeterminateCheckbox() {
  const [checked, setChecked] = useState('indeterminate');

  return (
    <label>
      <Checkbox checked={checked} onCheckedChange={setChecked} />
      <span>Select all</span>
    </label>
  );
}

Disabled state

<label>
  <Checkbox disabled />
  <span>Disabled checkbox</span>
</label>

<label>
  <Checkbox disabled checked />
  <span>Disabled and checked</span>
</label>

With form integration

<form>
  <label>
    <Checkbox name="subscribe" value="newsletter" />
    <span>Subscribe to newsletter</span>
  </label>
  <button type="submit">Submit</button>
</form>

Required checkbox

<label>
  <Checkbox required />
  <span>I agree to the terms *</span>
</label>

Select all pattern

function SelectAllCheckboxes() {
  const [selectedItems, setSelectedItems] = useState([]);
  const allItems = ['item1', 'item2', 'item3'];
  
  const allSelected = selectedItems.length === allItems.length;
  const someSelected = selectedItems.length > 0 && !allSelected;
  const selectAllState = allSelected ? true : someSelected ? 'indeterminate' : false;

  const handleSelectAll = (checked) => {
    setSelectedItems(checked ? allItems : []);
  };

  return (
    <div>
      <label>
        <Checkbox
          checked={selectAllState}
          onCheckedChange={handleSelectAll}
        />
        <span>Select all</span>
      </label>
      
      <Checkbox.Group value={selectedItems} onValueChange={setSelectedItems}>
        <label>
          <Checkbox value="item1" />
          <span>Item 1</span>
        </label>
        <label>
          <Checkbox value="item2" />
          <span>Item 2</span>
        </label>
        <label>
          <Checkbox value="item3" />
          <span>Item 3</span>
        </label>
      </Checkbox.Group>
    </div>
  );
}

Accessibility

  • Built on Base UI Checkbox primitive with full accessibility support.
  • Proper ARIA attributes are automatically applied.
  • Supports keyboard navigation with Space to toggle.
  • Indeterminate state is properly communicated to screen readers.
  • Works seamlessly within forms with proper name/value attributes.
  • Label association ensures the entire label is clickable.