Checkbox
freeCheckbox handles independent choices in settings, filters, and multi-select flows.
Preview
Dark
Notification channels
Select the channels that should receive weekly account updates.
import { useState } from 'react';
import Checkbox from '@/components/ui/Checkbox';
import type { CheckboxGroupValue } from '@/components/ui/Checkbox';
const channels = [
{ label: 'Email', value: 'email' },
{ label: 'Product', value: 'product' },
{ label: 'SMS', value: 'sms' },
];
export default function UsageDemo() {
const [selected, setSelected] = useState<CheckboxGroupValue>([
'email',
'product',
]);
return (
<div className="space-y-4">
<div>
<div className="text-base font-semibold text-foreground">
Notification channels
</div>
<p className="text-muted-foreground">
Select the channels that should receive weekly account updates.
</p>
</div>
<Checkbox.Group
value={selected}
onChange={setSelected}
className="flex-wrap"
>
{channels.map((channel) => (
<Checkbox
key={channel.value}
value={channel.value}
className="min-w-20"
>
{channel.label}
</Checkbox>
))}
</Checkbox.Group>
</div>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add CheckboxExamples
Basic
Preview
Dark
import Checkbox from '@/components/ui/Checkbox';
export default function BasicDemo() {
return (
<div className="flex flex-wrap items-center gap-4">
<Checkbox>Unchecked</Checkbox>
<Checkbox defaultChecked>Checked by default</Checkbox>
</div>
);
}Group
Preview
Dark
import { useState } from 'react';
import Checkbox from '@/components/ui/Checkbox';
import type { CheckboxGroupValue } from '@/components/ui/Checkbox';
const options = [
{ label: 'Invoices', value: 'invoices' },
{ label: 'Usage', value: 'usage' },
{ label: 'Security', value: 'security' },
];
export default function GroupDemo() {
const [selected, setSelected] = useState<CheckboxGroupValue>([
'invoices',
'security',
]);
return (
<div className="space-y-4">
<Checkbox.Group
value={selected}
onChange={setSelected}
className="flex-wrap"
>
{options.map((option) => (
<Checkbox key={option.value} value={option.value}>
{option.label}
</Checkbox>
))}
</Checkbox.Group>
</div>
);
}Vertical
Preview
Dark
import Checkbox from '@/components/ui/Checkbox';
export default function VerticalDemo() {
return (
<div className="flex justify-center">
<Checkbox.Group vertical value={['owner']}>
<Checkbox value="owner">Owner approval</Checkbox>
<Checkbox value="finance">Finance review</Checkbox>
<Checkbox value="legal">Legal review</Checkbox>
</Checkbox.Group>
</div>
);
}States
Preview
Dark
import Checkbox from '@/components/ui/Checkbox';
export default function StatesDemo() {
return (
<div className="grid max-w-full gap-4">
<Checkbox defaultChecked>Active selection</Checkbox>
<Checkbox disabled>Disabled unchecked</Checkbox>
<Checkbox defaultChecked disabled>
Disabled checked
</Checkbox>
<Checkbox checked readOnly>
Read-only checked
</Checkbox>
</div>
);
}Indeterminate
Preview
Dark
import { useState } from 'react';
import Checkbox from '@/components/ui/Checkbox';
import type { CheckboxGroupValue } from '@/components/ui/Checkbox';
const permissions = ['create', 'edit', 'archive'];
export default function IndeterminateDemo() {
const [selected, setSelected] = useState<CheckboxGroupValue>([
'create',
'edit',
]);
const allSelected = selected.length === permissions.length;
const partlySelected = selected.length > 0 && !allSelected;
const label = allSelected
? 'All permissions selected'
: partlySelected
? `${selected.length} permissions selected`
: 'No permissions selected';
return (
<div className="flex flex-col gap-4">
<Checkbox
checked={selected.length > 0}
indeterminate={partlySelected}
onChange={(checked) => setSelected(checked ? permissions : [])}
>
{label}
</Checkbox>
<Checkbox.Group value={selected} onChange={setSelected} vertical>
{permissions.map((permission) => (
<Checkbox key={permission} value={permission}>
{permission}
</Checkbox>
))}
</Checkbox.Group>
</div>
);
}Custom Color
Preview
Dark
import Checkbox from '@/components/ui/Checkbox';
export default function CustomColorDemo() {
return (
<div className="grid gap-4">
<Checkbox defaultChecked checkboxClass="text-success">
Success review
</Checkbox>
<Checkbox defaultChecked checkboxClass="text-warning">
Needs attention
</Checkbox>
<Checkbox defaultChecked checkboxClass="text-destructive">
Informational notice
</Checkbox>
</div>
);
}Controlled
Preview
Dark
import { useState } from 'react';
import Button from '@/components/ui/Button';
import Checkbox from '@/components/ui/Checkbox';
export default function ControlledDemo() {
const [approved, setApproved] = useState(false);
return (
<Checkbox checked={approved} onChange={setApproved}>
<span className="flex flex-col gap-1">
<span>I approve the terms and conditions</span>
<span className="text-xs text-muted-foreground">
Current value: {approved ? 'approved' : 'not approved'}
</span>
</span>
</Checkbox>
);
}API
Checkbox exposes a root checkbox input and a compound Checkbox.Group for multiple selections.
Checkbox
Checkbox accepts the props below plus native props for the underlying input.
| Prop | Description | Type | Default |
|---|---|---|---|
checked | Controls the checked state. | boolean | - |
checkboxClass | Class names applied to the checkbox control for color or local styling. | string | - |
children | Label content rendered beside the checkbox control. | ReactNode | - |
className | Class names applied to the root label. | string | - |
defaultChecked | Initial checked state for uncontrolled usage. | boolean | - |
disabled | Prevents pointer interaction and applies disabled styling. | boolean | - |
indeterminate | Renders the indeterminate mark when the checkbox is checked. | boolean | false |
labelRef | Ref forwarded to the root label element. | Ref<HTMLLabelElement> | - |
name | Name passed to the input, or inherited from Checkbox.Group. | string | Group name |
onChange | Called with the next checked state and the input change event. | CheckboxChangeHandler | - |
readOnly | Prevents the component from changing its internal state. | boolean | - |
ref | Ref forwarded to the underlying checkbox input. | Ref<HTMLInputElement> | - |
value | Value used by Checkbox.Group and passed through to the input. | CheckboxValue | - |
...nativeInputProps | Native props for the underlying checkbox input, except onChange. | NativeCheckboxInputProps | - |
Checkbox.Group
Checkbox.Group accepts the props below plus native props for the root div.
| Prop | Description | Type | Default |
|---|---|---|---|
checkboxClass | Class names shared by every checkbox control inside the group. | string | - |
children | Checkbox items rendered inside the group. | ReactNode | - |
className | Class names applied to the group root. | string | - |
name | Name shared by checkbox inputs inside the group. | string | - |
onChange | Called with the next selected value array and the source event. | CheckboxGroupChangeHandler | - |
ref | Ref forwarded to the group root. | Ref<HTMLDivElement> | - |
value | Controlled selected values for the group. | CheckboxGroupValue | - |
vertical | Stacks group items vertically. | boolean | false |
...nativeDivProps | Native props for the group root div, except onChange. | NativeCheckboxGroupDivProps | - |
Types
type CheckboxValue = string | number | boolean;
type CheckboxGroupValue = string[];
type CheckboxChangeHandler = (
checked: boolean,
event: ChangeEvent<HTMLInputElement>,
) => void;
type CheckboxGroupChangeHandler = (
value: CheckboxGroupValue,
event: SyntheticEvent,
) => void;
type NativeCheckboxInputProps = Omit<
ComponentPropsWithRef<'input'>,
'onChange'
>;
type NativeCheckboxGroupDivProps = Omit<
ComponentPropsWithRef<'div'>,
'onChange'
>;