Checkbox
A customizable checkbox component with support for indeterminate state, built on Base UI primitives.
Features
- Base UI Integration: Built on Base UI Checkbox primitives for accessibility
- Indeterminate State: Support for partial selection states
- Multiple Sizes: Small, default, and large sizes
- Field Integration: Works with labels and descriptions
- Custom Icons: Support for custom check and indeterminate icons
- Dark Mode: Automatically adapts to light and dark themes
Installation
npm install @bao-ui/reactUsage
Basic Checkbox
import { Checkbox } from '@bao-ui/react'
function Example() {
return <Checkbox label="Accept terms and conditions" />
}With Description
import { Checkbox } from '@bao-ui/react'
function Example() {
return (
<Checkbox
label="Send me notifications"
description="Get notified about updates and news."
/>
)
}Controlled Checkbox
import { useState } from 'react'
import { Checkbox } from '@bao-ui/react'
function Example() {
const [checked, setChecked] = useState(false)
return (
<div className="space-y-4">
<Checkbox
label="Controlled checkbox"
checked={checked}
onCheckedChange={setChecked}
description={`Checkbox is ${checked ? 'checked' : 'unchecked'}`}
/>
<button
onClick={() => setChecked(!checked)}
className="rounded bg-secondary px-3 py-1 text-sm hover:bg-secondary/80"
>
Toggle Checkbox
</button>
</div>
)
}Sizes
import { Checkbox } from '@bao-ui/react'
function Example() {
return (
<div className="space-y-4">
<Checkbox size="sm" label="Small checkbox" />
<Checkbox size="default" label="Default checkbox" />
<Checkbox size="lg" label="Large checkbox" />
</div>
)
}States
import { Checkbox } from '@bao-ui/react'
function Example() {
return (
<div className="space-y-4">
<Checkbox label="Default state" />
<Checkbox label="Checked state" defaultChecked />
<Checkbox label="Indeterminate state" indeterminate />
<Checkbox label="Disabled state" disabled />
<Checkbox label="Disabled checked" disabled defaultChecked />
</div>
)
}Checkbox Group
import { useState } from 'react'
import { Checkbox } from '@bao-ui/react'
function Example() {
const [selectedItems, setSelectedItems] = useState(['option1'])
const handleChange = (value, checked) => {
if (checked) {
setSelectedItems([...selectedItems, value])
} else {
setSelectedItems(selectedItems.filter(item => item !== value))
}
}
return (
<div className="space-y-3">
<h3 className="text-sm font-medium">Select your preferences:</h3>
<Checkbox
label="Email notifications"
checked={selectedItems.includes('option1')}
onCheckedChange={checked => handleChange('option1', checked)}
description="Receive updates via email"
/>
<Checkbox
label="SMS notifications"
checked={selectedItems.includes('option2')}
onCheckedChange={checked => handleChange('option2', checked)}
description="Receive updates via SMS"
/>
<Checkbox
label="Push notifications"
checked={selectedItems.includes('option3')}
onCheckedChange={checked => handleChange('option3', checked)}
description="Receive push notifications"
/>
<div className="mt-4 text-sm text-muted-foreground">
Selected: {selectedItems.length > 0 ? selectedItems.join(', ') : 'None'}
</div>
</div>
)
}Parent-Child Checkboxes
import { useState } from 'react'
import { Checkbox } from '@bao-ui/react'
function Example() {
const [parentChecked, setParentChecked] = useState(false)
const [childStates, setChildStates] = useState({
child1: false,
child2: false,
child3: false,
})
const childCount = Object.values(childStates).filter(Boolean).length
const totalChildren = Object.keys(childStates).length
const isIndeterminate = childCount > 0 && childCount < totalChildren
const handleParentChange = checked => {
setParentChecked(checked)
setChildStates({
child1: checked,
child2: checked,
child3: checked,
})
}
const handleChildChange = (childKey, checked) => {
const newChildStates = { ...childStates, [childKey]: checked }
setChildStates(newChildStates)
const newChildCount = Object.values(newChildStates).filter(Boolean).length
setParentChecked(newChildCount === totalChildren)
}
return (
<div className="space-y-3">
<Checkbox
label="Select all features"
checked={parentChecked}
indeterminate={isIndeterminate}
onCheckedChange={handleParentChange}
description="Toggle all features on or off"
/>
<div className="ml-6 space-y-2">
<Checkbox
label="Feature A"
checked={childStates.child1}
onCheckedChange={checked => handleChildChange('child1', checked)}
/>
<Checkbox
label="Feature B"
checked={childStates.child2}
onCheckedChange={checked => handleChildChange('child2', checked)}
/>
<Checkbox
label="Feature C"
checked={childStates.child3}
onCheckedChange={checked => handleChildChange('child3', checked)}
/>
</div>
</div>
)
}Custom Composition
For advanced use cases, you can compose the checkbox using individual components:
import {
CheckboxFieldRoot,
CheckboxRoot,
CheckboxIndicator,
CheckboxLabel,
CheckboxDescription,
} from '@bao-ui/react'
function Example() {
return (
<CheckboxFieldRoot>
<div className="flex items-center space-x-3">
<CheckboxRoot defaultChecked>
<CheckboxIndicator />
</CheckboxRoot>
<div>
<CheckboxLabel>Custom composed checkbox</CheckboxLabel>
<CheckboxDescription>
This uses individual components for maximum flexibility.
</CheckboxDescription>
</div>
</div>
</CheckboxFieldRoot>
)
}API Reference
Checkbox
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | - | Label text for the checkbox |
description | string | - | Helper text below the checkbox |
indeterminate | boolean | false | Whether the checkbox is in indeterminate state |
size | 'sm' | 'default' | 'lg' | 'default' | Size of the checkbox |
checked | boolean | - | Controlled checked state |
defaultChecked | boolean | false | Default checked state |
onCheckedChange | (checked: boolean) => void | - | Callback when checked state changes |
disabled | boolean | false | Whether the checkbox is disabled |
className | string | - | Additional CSS classes |
Individual Components
CheckboxRoot
The root checkbox element (button).
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'default' | 'lg' | 'default' | Size of the checkbox |
className | string | - | Additional CSS classes |
CheckboxIndicator
The visual indicator (checkmark/dash).
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
CheckboxFieldRoot
Container component for field composition.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
CheckboxLabel
Label component for the checkbox.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
CheckboxDescription
Description component for the checkbox.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
Accessibility
The Checkbox component follows WAI-ARIA guidelines:
- Proper ARIA attributes (
aria-checked,aria-labelledby) - Keyboard navigation support (Space to toggle)
- Screen reader announcements for state changes
- Focus management and visual indicators
- Support for indeterminate state announcements
Keyboard Shortcuts
Space- Toggle the checkboxTab- Move focus to the checkboxShift + Tab- Move focus away from the checkbox
Dark Mode
The Checkbox component automatically adapts to your theme:
- Uses semantic color tokens
- Supports both system preference and manual theme switching
- Maintains proper contrast ratios in all themes