ComponentsPrimitives
Checkbox
Boolean selection control built on Radix UI
The Checkbox component is a boolean selection control built on Radix UI Checkbox. It provides accessible, keyboard-navigable checkboxes that work seamlessly with form patterns.
Import
import { Checkbox } from '@nim-ui/components';Variants
Default
Code
<Checkbox id="default-check" label="Default checkbox" />With Label Pattern
The recommended usage is to pass label directly. The component generates a comfortable option row and keeps the label associated with the control.
Code
<Checkbox id="terms" label="Accept terms and conditions" />
<Checkbox id="newsletter" label="Subscribe to newsletter" />
<Checkbox
id="notifications"
label="Enable notifications"
description="Receive operational alerts for assigned queues."
/>Sizes
Use size="sm" for dense lists and size="lg" when the checkbox sits in a prominent mobile or settings row.
Code
<Checkbox id="compact-check" size="sm" label="Compact row" />
<Checkbox id="default-size-check" size="md" label="Balanced row" />
<Checkbox id="large-check" size="lg" label="Prominent row" />States
Disabled
Code
<Checkbox id="disabled-unchecked" disabled label="Disabled unchecked" />
<Checkbox id="disabled-checked" disabled checked label="Disabled checked" />Props
| Name | Type | Default | Description |
|---|---|---|---|
checked | boolean | "indeterminate" | - | Controlled checked state of the checkbox |
onCheckedChange | (checked: boolean | "indeterminate") => void | - | Callback fired when the checked state changes |
defaultChecked | boolean | - | Initial checked state for uncontrolled usage |
disabled | boolean | false | Whether the checkbox is disabled |
id | string | - | HTML id attribute, used to associate with a label |
label | React.ReactNode | - | Visible label rendered with comfortable spacing from the checkbox |
description | React.ReactNode | - | Optional secondary copy linked through aria-describedby |
size | "sm" | "md" | "lg" | "md" | Control size for denser or more prominent rows |
wrapperClassName | string | - | Additional classes for the generated checkbox row |
className | string | - | Additional CSS classes to apply |
Usage Examples
Terms Agreement
function TermsAgreement() {
const [agreed, setAgreed] = useState(false);
return (
<div className="space-y-4">
<Checkbox
id="terms"
checked={agreed}
onCheckedChange={(checked) => setAgreed(checked === true)}
label="I agree to the Terms of Service and Privacy Policy"
/>
<Button disabled={!agreed}>Continue</Button>
</div>
);
}Settings Panel
function NotificationSettings() {
const [settings, setSettings] = useState({
email: true,
push: false,
sms: false,
});
const toggle = (key: keyof typeof settings) => {
setSettings((prev) => ({ ...prev, [key]: !prev[key] }));
};
return (
<div className="space-y-3">
<h3 className="text-lg font-semibold">Notifications</h3>
<Checkbox
id="email-notif"
checked={settings.email}
onCheckedChange={() => toggle('email')}
label="Email notifications"
/>
<Checkbox
id="push-notif"
checked={settings.push}
onCheckedChange={() => toggle('push')}
label="Push notifications"
/>
<Checkbox
id="sms-notif"
checked={settings.sms}
onCheckedChange={() => toggle('sms')}
label="SMS notifications"
/>
</div>
);
}Filter List
function CategoryFilter({ categories, selected, onChange }) {
return (
<div className="space-y-2">
<h4 className="text-sm font-medium text-gray-700">Categories</h4>
{categories.map((category) => (
<Checkbox
key={category.id}
id={`cat-${category.id}`}
checked={selected.includes(category.id)}
label={category.name}
onCheckedChange={(checked) => {
if (checked) {
onChange([...selected, category.id]);
} else {
onChange(selected.filter((id) => id !== category.id));
}
}}
/>
))}
</div>
);
}Accessibility
The Checkbox component is built on Radix UI and follows WAI-ARIA best practices:
- Uses
role="checkbox"with properaria-checkedstate - Supports
aria-labelandaria-labelledbyfor screen reader announcements - Full keyboard navigation support
- Focus visible states for keyboard users
- Disabled state properly communicated to assistive technology
Keyboard Support
| Key | Action |
|---|---|
| Space | Toggles the checkbox |
| Tab | Moves focus to the next focusable element |
| Shift + Tab | Moves focus to the previous focusable element |
Best Practices
- Prefer the built-in
labelprop, or pair custom layouts with visible labels usingidandhtmlFor - Use
aria-describedbyto link additional descriptive text - Group related checkboxes with a heading or
fieldset/legend - Avoid using checkboxes for actions; use a Switch for on/off toggles