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
- TypeScript
- JavaScript
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;
import React, { useState } from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function BasicCheckboxDemo() {
const [checked, setChecked] = useState(false);
return (
<Box sl={{ display: "flex", gap: 2, p: 2, border: "1px solid", radius: "md" }}>
<Checkbox defaultChecked label="Uncontrolled (defaultChecked)" />
<Checkbox
checked={checked}
onChange={(e) => setChecked(e.target.checked)}
label={\`Controlled (\${checked ? "checked" : "unchecked"})\`}
color="primary"
/>
</Box>
);
}
Variants
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function CheckboxVariants() {
return (
<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>
);
}
Sizes
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function CheckboxSizes() {
return (
<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>
);
}
Colors
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function CheckboxColors() {
return (
<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>
);
}
Indeterminate
Live demo
- TypeScript
- JavaScript
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;
import React, { useState } from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function IndeterminateCheckboxDemo() {
const [indeterminate, setIndeterminate] = useState(true);
return (
<Box sl={{ p: 2 }}>
<Checkbox
checked={!indeterminate}
indeterminate={indeterminate}
onChange={() => setIndeterminate(!indeterminate)}
label="Indeterminate state"
color="warning"
variant="solid"
/>
</Box>
);
}
Select all (group with indeterminate)
Live demo
- TypeScript
- JavaScript
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;
import React, { useState } from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function SelectAllDemo() {
const [group, setGroup] = useState({ 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) => setGroup({ apple: next, banana: next, orange: next });
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={(e) => setGroup(g => ({ ...g, apple: e.target.checked }))} label="Apple" color="primary" variant="soft" />
<Checkbox checked={group.banana} onChange={(e) => setGroup(g => ({ ...g, banana: e.target.checked }))} label="Banana" color="primary" variant="soft" />
<Checkbox checked={group.orange} onChange={(e) => setGroup(g => ({ ...g, orange: e.target.checked }))} label="Orange" color="primary" variant="soft" />
</Box>
</Box>
);
}
Custom icons
Live demo
- TypeScript
- JavaScript
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;
import React, { useState } from "react";
import { Checkbox, Box } from "@libdev-ui/base";
const CheckIcon = () => <span aria-hidden="true">✓</span>;
const DashIcon = () => <span aria-hidden="true">–</span>;
export default function CheckboxCustomIcons() {
const [news, setNews] = useState(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>
);
}
Disable icon
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function DisableIconCheckbox() {
return (
<Box sl={{ p: 2 }}>
<Checkbox defaultChecked disableIcon label="Selected style (no icon)" color="info" variant="plain" />
</Box>
);
}
Disabled & ReadOnly
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box } from "@libdev-ui/base";
export default function DisabledCheckboxDemo() {
return (
<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>
);
}
Overlay mode
Live demo
Try clicking anywhere in this box.
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox, Box, Text } from "@libdev-ui/base";
export default function OverlayCheckboxDemo() {
return (
<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>
);
}
Slots & slotProps
Live demo
- TypeScript
- JavaScript
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;
import React from "react";
import { Checkbox } from "@libdev-ui/base";
export default function SlotsCheckboxDemo() {
return (
<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": "" },
}}
/>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled checked state. |
defaultChecked | boolean | — | Initial state for uncontrolled usage. |
onChange | (event: React.ChangeEvent<HTMLInputElement>) => void | — | Callback fired when state changes. |
indeterminate | boolean | false | Shows the checkbox as partially selected. |
disableIcon | boolean | false | Hides the checkmark icon and uses background highlight only. |
overlay | boolean | false | Expands the clickable area to its parent container. |
label | React.ReactNode | — | Text 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. |
slotProps | Partial<{ root, action, checkbox, label }> | — | Props passed to slots. |
sl | SlProp | — | System style props (margin, padding, radius, etc.). |
Accessibility
- Uses a native
<input type="checkbox" />hidden for screen readers. - Supports
indeterminateARIA state. - Keyboard accessible (focus, space/enter toggle).
- Works with
labelfor better click area.
Usage tips
- Use
overlaymode for row/list composition. - Use
disableIconfor selection highlight without a glyph. - Prefer
indeterminatefor partial selection patterns (e.g., lists with sub-items).