Checkbox
Binary choice input component with support for indeterminate state and custom styling.
Basic Usage
import { Checkbox } from '@akitectio/aki-ui'
function BasicCheckbox() {
return (
<div className="space-y-4">
<Checkbox label="Accept terms and conditions" />
<Checkbox label="Subscribe to newsletter" defaultChecked />
<Checkbox label="Enable notifications" disabled />
<Checkbox label="Disabled checked" disabled checked />
</div>
)
}
Controlled Component
Current state: Unchecked
import { useState } from 'react'
import { Checkbox } from '@akitectio/aki-ui'
function ControlledCheckbox() {
const [checked, setChecked] = useState(false)
return (
<div className="space-y-4">
<Checkbox
label="Controlled checkbox"
checked={checked}
onChange={setChecked}
/>
<p>Current state: {checked ? 'Checked' : 'Unchecked'}</p>
</div>
)
}
Colors
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
<Checkbox label="Primary" color="primary" defaultChecked />
<Checkbox label="Secondary" color="secondary" defaultChecked />
<Checkbox label="Success" color="success" defaultChecked />
<Checkbox label="Danger" color="danger" defaultChecked />
<Checkbox label="Warning" color="warning" defaultChecked />
<Checkbox label="Info" color="info" defaultChecked />
</div>
Sizes
<div className="space-y-4">
<Checkbox label="Small checkbox" size="sm" defaultChecked />
<Checkbox label="Medium checkbox" size="md" defaultChecked />
<Checkbox label="Large checkbox" size="lg" defaultChecked />
</div>
Indeterminate State
import { useState } from 'react'
import { Checkbox } from '@akitectio/aki-ui'
function IndeterminateCheckbox() {
const [parentChecked, setParentChecked] = useState(false)
const [childChecked, setChildChecked] = useState([false, false, false])
const handleParentChange = (checked: boolean) => {
setParentChecked(checked)
setChildChecked([checked, checked, checked])
}
const handleChildChange = (index: number, checked: boolean) => {
const newChildChecked = [...childChecked]
newChildChecked[index] = checked
setChildChecked(newChildChecked)
const checkedCount = newChildChecked.filter(Boolean).length
setParentChecked(checkedCount === newChildChecked.length)
}
const isIndeterminate = childChecked.some(Boolean) && !childChecked.every(Boolean)
return (
<div className="space-y-4">
<Checkbox
label="Select all"
checked={parentChecked}
indeterminate={isIndeterminate}
onChange={handleParentChange}
/>
<div className="ml-6 space-y-2">
{childChecked.map((checked, index) => (
<Checkbox
key={index}
label={`Option ${index + 1}`}
checked={checked}
onChange={(checked) => handleChildChange(index, checked)}
/>
))}
</div>
</div>
)
}
API Reference
Prop | Type | Default | Description |
---|---|---|---|
label | React.ReactNode | - | The label for the checkbox |
checked | boolean | - | Whether the checkbox is checked (controlled) |
defaultChecked | boolean | false | Default checked state (uncontrolled) |
onChange | (checked: boolean) => void | - | Called when the checked state changes |
indeterminate | boolean | false | Whether the checkbox is in an indeterminate state |
disabled | boolean | false | Whether the checkbox is disabled |
color | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'primary' | The checkbox color |
size | 'sm' | 'md' | 'lg' | 'md' | The size of the checkbox |
className | string | - | Additional CSS classes |
Accessibility
- ✅ Full keyboard navigation support
- ✅ Screen reader compatible with proper ARIA attributes
- ✅ Supports focus management
- ✅ High contrast mode support
- ✅ Proper labeling for assistive technologies
Keyboard Navigation
- Space - Toggle checkbox state
- Tab - Move focus to next focusable element
- Shift + Tab - Move focus to previous focusable element
Best Practices
✅ Do
- Use clear and descriptive labels
- Group related checkboxes logically
- Use indeterminate state for parent/child relationships
- Provide sufficient spacing between checkboxes
- Use consistent sizing throughout your application
❌ Don't
- Use checkboxes for mutually exclusive options (use radio buttons instead)
- Make labels too long or confusing
- Use only icons without text labels
- Forget to handle the indeterminate state properly
- Use disabled checkboxes without explanation