Checkbox

free

Checkbox 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 Checkbox

Examples

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.

PropDescriptionTypeDefault
checkedControls the checked state.boolean-
checkboxClassClass names applied to the checkbox control for color or local styling.string-
childrenLabel content rendered beside the checkbox control.ReactNode-
classNameClass names applied to the root label.string-
defaultCheckedInitial checked state for uncontrolled usage.boolean-
disabledPrevents pointer interaction and applies disabled styling.boolean-
indeterminateRenders the indeterminate mark when the checkbox is checked.booleanfalse
labelRefRef forwarded to the root label element.Ref<HTMLLabelElement>-
nameName passed to the input, or inherited from Checkbox.Group.stringGroup name
onChangeCalled with the next checked state and the input change event.CheckboxChangeHandler-
readOnlyPrevents the component from changing its internal state.boolean-
refRef forwarded to the underlying checkbox input.Ref<HTMLInputElement>-
valueValue used by Checkbox.Group and passed through to the input.CheckboxValue-
...nativeInputPropsNative props for the underlying checkbox input, except onChange.NativeCheckboxInputProps-

Checkbox.Group

Checkbox.Group accepts the props below plus native props for the root div.

PropDescriptionTypeDefault
checkboxClassClass names shared by every checkbox control inside the group.string-
childrenCheckbox items rendered inside the group.ReactNode-
classNameClass names applied to the group root.string-
nameName shared by checkbox inputs inside the group.string-
onChangeCalled with the next selected value array and the source event.CheckboxGroupChangeHandler-
refRef forwarded to the group root.Ref<HTMLDivElement>-
valueControlled selected values for the group.CheckboxGroupValue-
verticalStacks group items vertically.booleanfalse
...nativeDivPropsNative 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'
>;