npm install @thrivecart/uiyarn add @thrivecart/uipnpm add @thrivecart/uibun add @thrivecart/uiImport the Checkbox component from the package:
import { Checkbox, Label } from '@thrivecart/ui';Basic checkbox with label
<div className="flex items-center space-x-2">
<Checkbox id="terms" />
<Label htmlFor="terms" className='font-normal'>Accept terms and conditions</Label>
</div>Checkbox with controlled state
function ControlledCheckbox() {
const [checked, setChecked] = React.useState(true);
return (
<div className="flex items-center space-x-2">
<Checkbox
id="controlled"
checked={checked}
onCheckedChange={setChecked}
/>
<Label htmlFor="controlled" className='font-normal'>
Receive email notifications
</Label>
</div>
);
}Group of related checkboxes
function CheckboxGroup() {
const [selected, setSelected] = React.useState(['email']);
const toggleOption = (option) => {
setSelected(prev =>
prev.includes(option)
? prev.filter(o => o !== option)
: [...prev, option]
);
};
return (
<div className="space-y-3">
<Label className="text-base font-medium">Notification Preferences</Label>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Checkbox
id="email"
checked={selected.includes('email')}
onCheckedChange={() => toggleOption('email')}
/>
<Label htmlFor="email" className='font-normal'>Email notifications</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="sms"
checked={selected.includes('sms')}
onCheckedChange={() => toggleOption('sms')}
/>
<Label htmlFor="sms" className='font-normal'>SMS notifications</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="push"
checked={selected.includes('push')}
onCheckedChange={() => toggleOption('push')}
/>
<Label htmlFor="push" className='font-normal'>Push notifications</Label>
</div>
</div>
</div>
);
}Checkbox with indeterminate state for partial selection
function IndeterminateExample() {
const [items, setItems] = React.useState([
{ id: '1', label: 'Item 1', checked: true },
{ id: '2', label: 'Item 2', checked: false },
{ id: '3', label: 'Item 3', checked: true },
]);
const allChecked = items.every(item => item.checked);
const someChecked = items.some(item => item.checked) && !allChecked;
const toggleAll = () => {
const newValue = !allChecked;
setItems(items.map(item => ({ ...item, checked: newValue })));
};
const toggleItem = (id) => {
setItems(items.map(item =>
item.id === id ? { ...item, checked: !item.checked } : item
));
};
return (
<div className="space-y-3">
<div className="flex items-center space-x-2">
<Checkbox
id="select-all"
checked={someChecked ? 'indeterminate' : allChecked}
onCheckedChange={toggleAll}
/>
<Label htmlFor="select-all" className="font-medium">
Select all items
</Label>
</div>
<div className="ml-6 space-y-2">
{items.map(item => (
<div key={item.id} className="flex items-center space-x-2">
<Checkbox
id={item.id}
checked={item.checked}
onCheckedChange={() => toggleItem(item.id)}
/>
<Label htmlFor={item.id} className='font-normal'>{item.label}</Label>
</div>
))}
</div>
</div>
);
}Non-interactive checkbox
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Checkbox id="disabled-unchecked" disabled />
<Label htmlFor="disabled-unchecked" className="font-normal text-ink-light">
Disabled unchecked
</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="disabled-checked" disabled checked />
<Label htmlFor="disabled-checked" className="font-normal text-ink-light">
Disabled checked
</Label>
</div>
</div>Additional context for the option
Receive tips, trends, and insights about email marketing.
<div className="flex items-start space-x-2">
<Checkbox id="marketing" className="mt-1" />
<div>
<Label htmlFor="marketing" className='font-normal'>Marketing emails</Label>
<p className="text-sm text-ink-light">
Receive tips, trends, and insights about email marketing.
</p>
</div>
</div>Labels should clearly describe what selecting the checkbox does. Use positive phrasing.
Organize checkboxes logically and use a group label when presenting multiple related options.
When a parent checkbox controls child items, use the indeterminate state for partial selection.
Position labels consistently to the right of checkboxes for easy scanning.
For immediate on/off toggles, use a Switch component instead.
When only one option can be selected, use Radio buttons instead.
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | 'indeterminate' | - | Controlled checked state |
defaultChecked | boolean | - | Default checked state |
onCheckedChange | (checked: boolean | 'indeterminate') => void | - | Change handler |
disabled | boolean | false | Disable the checkbox |
required | boolean | false | Mark as required |
name | string | - | Form field name |
value | string | - | Form value when checked |
id | string | - | Element ID for label association |
className | string | - | Additional className |
Label Association
Always associate checkboxes with labels using the htmlFor attribute matching the checkbox id. This ensures proper accessibility and larger click targets.