Skip to main content

Checkbox

The Checkbox component allows users to select one or multiple options from a set.
It supports controlled and uncontrolled states, different variants, colors, sizes, accessibility features, and customization via slots.


Basic usage

Live demo

import React, { useState, ChangeEvent, FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const BasicCheckboxDemo: FC = () => {
const [checked, setChecked] = useState<boolean>(false);

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setChecked(e.target.checked);
};

return (
<Box sl={{ display: "flex", gap: 2, p: 2, border: "1px solid", radius: "md" }}>
<Checkbox defaultChecked label="Uncontrolled (defaultChecked)" />
<Checkbox
checked={checked}
onChange={handleChange}
label={\`Controlled (\${checked ? "checked" : "unchecked"})\`}
color="primary"
/>
</Box>
);
};

export default BasicCheckboxDemo;

Variants

Live demo

import React, { FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const CheckboxVariants: FC = () => (
<Box sl={{ display: "flex", gap: 2, p: 2 }}>
<Checkbox defaultChecked variant="plain" color="primary" label="plain" />
<Checkbox defaultChecked variant="soft" color="primary" label="soft" />
<Checkbox defaultChecked variant="outlined" color="primary" label="outlined" />
<Checkbox defaultChecked variant="solid" color="primary" label="solid" />
</Box>
);

export default CheckboxVariants;

Sizes

Live demo

import React, { FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const CheckboxSizes: FC = () => (
<Box sl={{ display: "flex", gap: 2, p: 2 }}>
<Checkbox defaultChecked size="sm" color="success" variant="soft" label="sm" />
<Checkbox defaultChecked size="md" color="success" variant="soft" label="md" />
<Checkbox defaultChecked size="lg" color="success" variant="soft" label="lg" />
</Box>
);

export default CheckboxSizes;

Colors

Live demo

import React, { FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const CheckboxColors: FC = () => (
<Box sl={{ display: "flex", gap: 2, p: 2, border: "1px solid", radius: "md" }}>
<Checkbox defaultChecked color="neutral" label="neutral" />
<Checkbox defaultChecked color="primary" label="primary" />
<Checkbox defaultChecked color="success" label="success" />
<Checkbox defaultChecked color="warning" label="warning" />
<Checkbox defaultChecked color="danger" label="danger" />
<Checkbox defaultChecked color="info" label="info" />
<Checkbox defaultChecked color="secondary" label="secondary" />
</Box>
);

export default CheckboxColors;

Indeterminate

Live demo

import React, { useState, FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const IndeterminateCheckboxDemo: FC = () => {
const [indeterminate, setIndeterminate] = useState<boolean>(true);

return (
<Box sl={{ p: 2 }}>
<Checkbox
checked={!indeterminate}
indeterminate={indeterminate}
onChange={() => setIndeterminate(!indeterminate)}
label="Indeterminate state"
color="warning"
variant="solid"
/>
</Box>
);
};

export default IndeterminateCheckboxDemo;

Select all (group with indeterminate)

Live demo

import React, { useState, FC, ChangeEvent } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const SelectAllDemo: FC = () => {
const [group, setGroup] = useState<{ apple: boolean; banana: boolean; orange: boolean }>({
apple: false,
banana: true,
orange: false,
});

const all = group.apple && group.banana && group.orange;
const none = !group.apple && !group.banana && !group.orange;
const indeterminate = !all && !none;

const setAll = (next: boolean) => setGroup({ apple: next, banana: next, orange: next });
const onItem = (key: keyof typeof group) => (e: ChangeEvent<HTMLInputElement>) =>
setGroup((g) => ({ ...g, [key]: e.target.checked }));

return (
<Box sl={{ p: 2, display: "grid", gap: 1 }}>
<Checkbox
checked={all}
indeterminate={indeterminate}
onChange={(e) => setAll(e.target.checked)}
label="Select all"
color="primary"
variant="solid"
/>
<Box sl={{ pl: 2, display: "grid", gap: 1 }}>
<Checkbox checked={group.apple} onChange={onItem("apple")} label="Apple" color="primary" variant="soft" />
<Checkbox checked={group.banana} onChange={onItem("banana")} label="Banana" color="primary" variant="soft" />
<Checkbox checked={group.orange} onChange={onItem("orange")} label="Orange" color="primary" variant="soft" />
</Box>
</Box>
);
};

export default SelectAllDemo;

Custom icons

Live demo

import React, { useState, FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const CheckIcon: FC = () => <span aria-hidden="true"></span>;
const DashIcon: FC = () => <span aria-hidden="true"></span>;

const CheckboxCustomIcons: FC = () => {
const [news, setNews] = useState<boolean>(true);

return (
<Box sl={{ p: 2 }}>
<Checkbox
checked={news}
onChange={(e) => setNews(e.target.checked)}
checkedIcon={<CheckIcon />}
indeterminateIcon={<DashIcon />}
label="Controlled with custom icons"
color="success"
variant="soft"
size="lg"
/>
</Box>
);
};

export default CheckboxCustomIcons;

Disable icon

Live demo

import React, { FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const DisableIconCheckbox: FC = () => (
<Box sl={{ p: 2 }}>
<Checkbox defaultChecked disableIcon label="Selected style (no icon)" color="info" variant="plain" />
</Box>
);

export default DisableIconCheckbox;

Disabled & ReadOnly

Live demo

import React, { FC } from "react";
import { Checkbox, Box } from "@libdev-ui/base";

const DisabledCheckboxDemo: FC = () => (
<Box sl={{ display: "grid", gap: 1, p: 2 }}>
<Checkbox disabled label="Disabled (unchecked)" />
<Checkbox disabled defaultChecked label="Disabled (checked)" color="secondary" />
<Checkbox readOnly defaultChecked label="Read-only (defaultChecked)" />
</Box>
);

export default DisabledCheckboxDemo;

Overlay mode

Live demo

Try clicking anywhere in this box.

import React, { FC } from "react";
import { Checkbox, Box, Text } from "@libdev-ui/base";

const OverlayCheckboxDemo: FC = () => (
<Box
sl={{
position: "relative",
p: 2,
border: "1px solid",
radius: "md",
}}
>
<Checkbox overlay defaultChecked label="Overlay mode (fills container)" color="neutral" />
<Text sl={{ opacity: 0.7, mt: 1 }}>Try clicking anywhere in this box.</Text>
</Box>
);

export default OverlayCheckboxDemo;

Slots & slotProps

Live demo

import React, { FC } from "react";
import { Checkbox } from "@libdev-ui/base";

const SlotsCheckboxDemo: FC = () => (
<Checkbox
defaultChecked
label="Custom slot props"
color="primary"
slots={{ root: "span" }}
slotProps={{
root: (os) => ({
"data-demo-root": "",
style: { outline: os.focusVisible ? "2px solid #3b82f6" : "none" },
}),
checkbox: { "data-demo-checkbox": "" },
action: { "data-demo-action": "" },
label: { "data-demo-label": "" },
}}
/>
);

export default SlotsCheckboxDemo;

Props

PropTypeDefaultDescription
checkedbooleanControlled checked state.
defaultCheckedbooleanInitial state for uncontrolled usage.
onChange(event: React.ChangeEvent<HTMLInputElement>) => voidCallback fired when state changes.
indeterminatebooleanfalseShows the checkbox as partially selected.
disableIconbooleanfalseHides the checkmark icon and uses background highlight only.
overlaybooleanfalseExpands the clickable area to its parent container.
labelReact.ReactNodeText or element rendered as label.
color"neutral" | "primary" | "success" | "warning" | "danger" | "info" | "secondary""neutral"Thematic color of the checkbox.
variant"plain" | "outlined" | "soft" | "solid""outlined"Visual style variant.
size"sm" | "md" | "lg""md"Checkbox size.
slots{ root?, action?, checkbox?, label? }Replaceable components for composition.
slotPropsPartial<{ root, action, checkbox, label }>Props passed to slots.
slSlPropSystem style props (margin, padding, radius, etc.).

Accessibility

  • Uses a native <input type="checkbox" /> hidden for screen readers.
  • Supports indeterminate ARIA state.
  • Keyboard accessible (focus, space/enter toggle).
  • Works with label for better click area.

Usage tips

  • Use overlay mode for row/list composition.
  • Use disableIcon for selection highlight without a glyph.
  • Prefer indeterminate for partial selection patterns (e.g., lists with sub-items).