Checkbox
A composable checkbox control for boolean and indeterminate selection states.
API Reference
Original primitive API
Behavior, accessibility details, and low-level props are documented by Base UI.
Basic
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";export function CheckboxDemo() { return ( <CheckboxField> <Checkbox defaultChecked /> <CheckboxLabel>Enable notifications</CheckboxLabel> </CheckboxField> );}Full list of component variables available for project-level overrides.
| Property | Default | Description |
|---|---|---|
| --checkbox-bg | var(--color-background) | Controls unchecked background color. |
| --checkbox-bg-checked | var(--color-primary) | Controls checked background color. |
| --checkbox-bg-hover | var(--color-accent) | Controls unchecked hover background color. |
| --checkbox-border-color | var(--color-border) | Controls unchecked border color. |
| --checkbox-border-color-checked | var(--color-primary) | Controls checked and indeterminate border color. |
| --checkbox-border-width | var(--border-width-sm) | Controls checkbox border width. |
| --checkbox-color | var(--color-primary-foreground) | Controls indicator icon color. |
| --checkbox-focus-ring-color | var(--color-ring) | Controls focus ring color. |
| --checkbox-focus-ring-offset | var(--border-width-sm) | Controls focus ring offset. |
| --checkbox-focus-ring-width | var(--border-width-sm) | Controls focus ring width. |
| --checkbox-disabled-opacity | var(--opacity-disabled) | Controls disabled opacity. |
| --checkbox-gap | var(--spacing-2) | Controls spacing between control and label. |
| --checkbox-icon-size-xs | 0.5rem | Controls `xs` indicator icon size. |
| --checkbox-icon-size-sm | 0.625rem | Controls `sm` indicator icon size. |
| --checkbox-icon-size-md | 0.75rem | Controls `md` indicator icon size. |
| --checkbox-icon-size-lg | 0.875rem | Controls `lg` indicator icon size. |
| --checkbox-icon-size-xl | 1rem | Controls `xl` indicator icon size. |
| --checkbox-indicator-bg | transparent | Controls indicator background color. |
| --checkbox-indicator-bg-checked | var(--checkbox-indicator-bg, transparent) | Controls checked and indeterminate indicator background color. |
| --checkbox-indicator-border-color | transparent | Controls indicator border color. |
| --checkbox-indicator-border-color-checked | var(--checkbox-indicator-border-color, transparent) | Controls checked and indeterminate indicator border color. |
| --checkbox-indicator-border-width | 0 | Controls indicator border width. |
| --checkbox-indicator-radius | inherit | Controls indicator border radius. |
| --checkbox-label-color | var(--color-foreground) | Controls label text color. |
| --checkbox-label-font-size | var(--text-sm) | Controls label font size. |
| --checkbox-label-font-weight | var(--weight-medium) | Controls label font weight. |
| --checkbox-label-line-height | var(--line-height-text-sm) | Controls label line height. |
| --checkbox-radius | var(--radius-xs) | Controls checkbox corner radius. |
| --checkbox-size-xs | 0.875rem | Controls `xs` checkbox size. |
| --checkbox-size-sm | 1rem | Controls `sm` checkbox size. |
| --checkbox-size-md | 1.25rem | Controls `md` checkbox size. |
| --checkbox-size-lg | 1.5rem | Controls `lg` checkbox size. |
| --checkbox-size-xl | 1.75rem | Controls `xl` checkbox size. |
| --checkbox-transition | var(--transition-default) | Controls state transition timing. |
Interactive variables scoped for docs preview without changing size scale tokens.
| Property | Value | Default | Description |
|---|---|---|---|
| --checkbox-bg | var(--color-background) | Controls unchecked background color. | |
| --checkbox-bg-checked | var(--color-primary) | Controls checked background color. | |
| --checkbox-bg-hover | var(--color-accent) | Controls unchecked hover background color. | |
| --checkbox-border-color | var(--color-border) | Controls unchecked border color. | |
| --checkbox-border-color-checked | var(--color-primary) | Controls checked and indeterminate border color. | |
| --checkbox-border-width | var(--border-width-sm) | Controls checkbox border width. | |
| --checkbox-color | var(--color-primary-foreground) | Controls indicator icon color. | |
| --checkbox-focus-ring-color | var(--color-ring) | Controls focus ring color. | |
| --checkbox-focus-ring-offset | var(--border-width-sm) | Controls focus ring offset. | |
| --checkbox-focus-ring-width | var(--border-width-sm) | Controls focus ring width. | |
| --checkbox-disabled-opacity | var(--opacity-disabled) | Controls disabled opacity. | |
| --checkbox-gap | var(--spacing-2) | Controls spacing between control and label. | |
| --checkbox-icon-size-xs | 0.5rem | Controls `xs` indicator icon size. | |
| --checkbox-icon-size-sm | 0.625rem | Controls `sm` indicator icon size. | |
| --checkbox-icon-size-md | 0.75rem | Controls `md` indicator icon size. | |
| --checkbox-icon-size-lg | 0.875rem | Controls `lg` indicator icon size. | |
| --checkbox-icon-size-xl | 1rem | Controls `xl` indicator icon size. | |
| --checkbox-indicator-bg | transparent | Controls indicator background color. | |
| --checkbox-indicator-bg-checked | var(--checkbox-indicator-bg, transparent) | Controls checked and indeterminate indicator background color. | |
| --checkbox-indicator-border-color | transparent | Controls indicator border color. | |
| --checkbox-indicator-border-color-checked | var(--checkbox-indicator-border-color, transparent) | Controls checked and indeterminate indicator border color. | |
| --checkbox-indicator-border-width | 0 | Controls indicator border width. | |
| --checkbox-indicator-radius | inherit | Controls indicator border radius. | |
| --checkbox-label-color | var(--color-foreground) | Controls label text color. | |
| --checkbox-label-font-size | var(--text-sm) | Controls label font size. | |
| --checkbox-label-font-weight | var(--weight-medium) | Controls label font weight. | |
| --checkbox-label-line-height | var(--line-height-text-sm) | Controls label line height. | |
| --checkbox-radius | var(--radius-xs) | Controls checkbox corner radius. | |
| --checkbox-size-xs | 0.875rem | Controls `xs` checkbox size. | |
| --checkbox-size-sm | 1rem | Controls `sm` checkbox size. | |
| --checkbox-size-md | 1.25rem | Controls `md` checkbox size. | |
| --checkbox-size-lg | 1.5rem | Controls `lg` checkbox size. | |
| --checkbox-size-xl | 1.75rem | Controls `xl` checkbox size. | |
| --checkbox-transition | var(--transition-default) | Controls state transition timing. |
Composition
Checkbox forwards Base UI root props and includes the indicator by default. Use it
uncontrolled with defaultChecked, controlled with checked and onCheckedChange, or
connect it to forms with name, value, uncheckedValue, form, required, readOnly,
and inputRef. It also supports Base UI composition props such as render and
nativeButton.
Pass className to style the root control. Use classNames to style the automatically
rendered indicator parts. Use slotProps.indicator for Base UI indicator props such as
keepMounted, render, and state-aware style. Compose CheckboxIndicator and
CheckboxIndicatorIcon yourself only when you need full control over the indicator slot:
<Checkbox
className={styles.checkbox}
classNames={{
indicator: styles.indicator,
indicatorIcon: styles.indicatorIcon,
checkedIcon: styles.checkedIcon,
indeterminateIcon: styles.indeterminateIcon,
}}
slotProps={{
indicator: { keepMounted: true },
}}
/>Anatomy
Checkbox is composed around one interactive root and optional label wrappers. Use
CheckboxField and CheckboxLabel for the common clickable-label pattern, and keep
them grouped so focus, disabled state, and text association stay aligned.
CheckboxField
├─ Checkbox
│ └─ CheckboxIndicator
│ └─ CheckboxIndicatorIcon
└─ CheckboxLabel<CheckboxField>
<Checkbox defaultChecked>
<CheckboxIndicator>
<CheckboxIndicatorIcon />
</CheckboxIndicator>
</Checkbox>
<CheckboxLabel>Enable notifications</CheckboxLabel>
</CheckboxField>| Part | Role |
|---|---|
Checkbox | Interactive root. Controls checked, indeterminate, and disabled states and exposes styling attributes. |
CheckboxIndicator | Indicator slot inside the root. Renders automatically by default, or can be composed manually. |
CheckboxIndicatorIcon | Icon slot inside the indicator. Switches between checked and indeterminate visuals by state. |
CheckboxField | Optional wrapper that groups the checkbox and label into one accessible field pattern. |
CheckboxLabel | Optional text label associated with the checkbox for pointer and keyboard interaction. |
Checkbox does not use service slots such as portal, backdrop, or viewport.
In most cases, keep behavior defaults and customize visible slots via className,
classNames, and CSS variables.
Examples
Indeterminate
Use indeterminate when a parent option represents a mixed selection state.
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";export function IndeterminateCheckboxDemo() { return ( <CheckboxField> <Checkbox indeterminate /> <CheckboxLabel>Select all team members</CheckboxLabel> </CheckboxField> );}Sizes
Use size to align the control with different form densities.
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";export function CheckboxSizesDemo() { return ( <div className={styles.stack}> <CheckboxField> <Checkbox size="xs" defaultChecked /> <CheckboxLabel>Extra-small</CheckboxLabel> </CheckboxField> <CheckboxField> <Checkbox size="sm" defaultChecked /> <CheckboxLabel>Small</CheckboxLabel> </CheckboxField> <CheckboxField> <Checkbox size="md" defaultChecked /> <CheckboxLabel>Medium</CheckboxLabel> </CheckboxField> <CheckboxField> <Checkbox size="lg" defaultChecked /> <CheckboxLabel>Large</CheckboxLabel> </CheckboxField> <CheckboxField> <Checkbox size="xl" defaultChecked /> <CheckboxLabel>Extra-large</CheckboxLabel> </CheckboxField> </div> );}.stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-3);}Disabled
Use disabled to prevent interaction while preserving the selection state in the UI.
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";export function DisabledCheckboxDemo() { return ( <div className={styles.stack}> <CheckboxField> <Checkbox disabled /> <CheckboxLabel>Receive weekly summary</CheckboxLabel> </CheckboxField> <CheckboxField> <Checkbox defaultChecked disabled /> <CheckboxLabel>Share anonymous usage data</CheckboxLabel> </CheckboxField> </div> );}.stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-3);}Controlled
Control checked from React state when the checkbox needs to coordinate with other UI.
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";import { useState } from "react";export function ControlledCheckboxDemo() { const [checked, setChecked] = useState(false); return ( <div className={styles.stack}> <CheckboxField> <Checkbox checked={checked} onCheckedChange={setChecked} /> <CheckboxLabel>{checked ? "Enabled" : "Disabled"}</CheckboxLabel> </CheckboxField> <span className={styles.hint}>Current value: {String(checked)}</span> </div> );}.stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-3);}.hint { color: var(--color-muted-foreground); font-size: var(--text-xs); line-height: var(--line-height-text-xs);}Indicator Icon
Pass icon nodes to checkedIcon and indeterminateIcon, or compose CheckboxIndicator directly when you need full control over the indicator slot.
import { Checkbox, CheckboxField, CheckboxLabel,} from "moduix";import type { ComponentProps } from "react";function CustomPlusIcon(props: ComponentProps<"svg">) { return ( <svg viewBox="0 0 10 10" fill="none" aria-hidden="true" focusable="false" {...props}> <path d="M5 1.5V8.5M1.5 5H8.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" /> </svg> );}export function IndicatorIconCheckboxDemo() { return ( <CheckboxField> <Checkbox defaultChecked checkedIcon={<CustomPlusIcon />} /> <CheckboxLabel>Use custom indicator icon</CheckboxLabel> </CheckboxField> );}Custom Styles
Pass className to the field, root, and label slots. Use classNames for the automatically rendered indicator slots.
import { Checkbox, CheckboxField, CheckboxLabel } from "moduix";export function CustomStylesCheckboxDemo() { return ( <CheckboxField className={styles.customField}> <Checkbox className={styles.customCheckbox} classNames={{ indicator: styles.customIndicator, indicatorIcon: styles.customIndicatorIcon, checkedIcon: styles.customCheckedIcon, indeterminateIcon: styles.customIndeterminateIcon, }} defaultChecked /> <CheckboxLabel className={styles.customLabel}>Styled with className</CheckboxLabel> </CheckboxField> );}.customField { gap: var(--spacing-3);}.customCheckbox { border-color: var(--color-primary); &[data-checked] { background-color: var(--color-primary); }}.customIndicator { color: var(--color-primary-foreground);}.customIndicatorIcon { transform: rotate(-8deg);}.customCheckedIcon { filter: drop-shadow(0 0 0.25rem rgb(255 255 255 / 0.4));}.customIndeterminateIcon { opacity: 0.86;}.customLabel { color: var(--color-primary);}Sibling Label
Use nativeButton with render={<button />} for the sibling label pattern with htmlFor and id.
import { Checkbox } from "moduix";import { useId } from "react";export function SiblingLabelCheckboxDemo() { const id = useId(); return ( <div className={styles.siblingRow}> <Checkbox nativeButton render={<button />} id={id} defaultChecked /> <label htmlFor={id} className={styles.label}> Keep me signed in </label> </div> );}.siblingRow { display: flex; align-items: center; gap: var(--checkbox-gap, var(--spacing-2));}.label { color: var(--checkbox-label-color, var(--color-foreground)); font-size: var(--checkbox-label-font-size, var(--text-sm)); font-weight: var(--checkbox-label-font-weight, var(--weight-medium)); line-height: var(--checkbox-label-line-height, var(--line-height-text-sm));}