Components

Checkbox Group

A React checkbox group with Liquid Glass controls, labels, and descriptions.

CheckboxGroup renders a labelled set of independent checkbox choices on one shared state. Each option is a real checkbox with its own label and description, and the group value is an array of the checked values.

Options are passed through the items array. The group owns the checked values, supports controlled and uncontrolled usage, and shares one label and description across the set.

Basic example

label and description name the group and explain its purpose. Set defaultValue to start with options checked, or use value with onValueChange for a controlled group.

NotificationsChoose the channels you want to hear about.
CommentsReplies and mentions on your posts.ReleasesA summary when a new version ships.BillingInvoices, receipts, and plan changes.

Parent checkbox

A parent checkbox is composed from Checkbox and CheckboxGroup rather than built into the group. Keep the checked values in state, derive the parent's checked and indeterminate props from that state, and select or clear every option in onCheckedChange. The parent sits above the indented group. Pass the same size to both controls so their rows stay aligned.

Notifications
CommentsReleasesBilling

Nested parent checkbox

Nest a second Checkbox and CheckboxGroup one level deeper. Derive each parent from its own array and the outer parent from both arrays. Selecting the outer parent updates both arrays, so repeated clicks always alternate between every option and none.

User Permissions
View DashboardAccess Reports
Manage Users
Create UserEdit UserDelete UserAssign Roles

Controlled usage

value and onValueChange let external state fully control the selection. The callback receives the next array of checked values and the Base UI event details.

NotificationsSelect every channel you want to keep.
CommentsReleasesBilling

Selected: comments, billing

Sizes

Supports xs / sm / md / lg / xl, defaulting to md. The control, label, description, and spacing scale together.

Size xs
CommentsReleases
Size sm
CommentsReleases
Size md
CommentsReleases
Size lg
CommentsReleases
Size xl
CommentsReleases

Disabled and read-only

Set disabled on the group to disable every option, or on a single item to disable only that option. readOnly keeps every checkbox focusable while preventing changes.

Disabled groupEvery option inherits the disabled state.
CommentsReleasesBilling
One disabled optionThe remaining options stay interactive.
CommentsReleasesBilling
Read onlyFocus stays available, but values cannot change.
CommentsReleasesBilling

Form usage

Set name to submit every checked value through hidden native checkboxes with the same field name. Read them with FormData.getAll(name). form links the inputs to a form elsewhere in the document.

NotificationsEach checked option submits its value.
CommentsReleasesBilling

Submitted: nothing yet

Accessibility

CheckboxGroup exposes a group named by label or by aria-label / aria-labelledby. Each option is a checkbox with its visible label and description linked automatically. Space toggles the focused checkbox, and Tab moves between options because a checkbox group is not a composite widget.

A parent checkbox is a separate Checkbox: give the group its own accessible name, derive the parent's checked and indeterminate state from the shared arrays, and keep both levels in sync. Parent checkboxes are controls only, so they do not submit a value unless you give them a name and value.

Disabled options remain announced but cannot change. Each checked option submits its own hidden native checkbox; there is no native required for a group, so validate that at least one value is selected in your form handler. See the accessibility guide for form patterns.

API reference

CheckboxGroup

PropTypeDefaultDescription
itemsreadonly CheckboxGroupItemProps[]—Options rendered by the group. Required.
labelReactNode—Visible label for the group.
descriptionReactNode—Supporting text under the group label, linked with aria-describedby.
valuereadonly string[]—Controlled checked values.
defaultValuereadonly string[][]Initial checked values when uncontrolled.
onValueChange(value: string[], details) => void—Called when a checkbox is ticked or unticked.
namestring—Form field name applied to every checkbox in the group.
formstring—ID of the form that owns the hidden inputs.
disabledbooleanfalseDisables every option.
readOnlybooleanfalsePrevents changes while keeping every option focusable.
size"xs" | "sm" | "md" | "lg" | "xl""md"Control, label, description, and spacing size.
aria-labelstring—Accessible name when no visible label is rendered.
aria-labelledbystring—ID reference for an external accessible name.
aria-describedbystring—ID reference for external supporting text. A visible description is merged with this value.
renderReactElement | ((props, state) => ReactElement)—Replaces the group root element.
refRef<HTMLDivElement>—Ref forwarded to the group root.
classNamestring—Tailwind classes merged into the group root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; header?: ClassValue; label?: ClassValue; description?: ClassValue; items?: ClassValue; item?: ClassValue; box?: ClassValue; fill?: ClassValue; glass?: ClassValue; overlay?: ClassValue; indicator?: ClassValue; indicatorIcon?: ClassValue; wrapper?: ClassValue; itemLabel?: ClassValue; itemDescription?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.

CheckboxGroupItemProps

PropTypeDefaultDescription
valuestring—Identifies the option in the group value. Required.
indeterminatebooleanfalseForces the mixed state.
labelReactNode—Visible label next to the control. It becomes the accessible name unless aria-label or aria-labelledby is provided.
descriptionReactNode—Supporting copy under the label, linked with aria-describedby when the control has a name.
disabledbooleanfalseDisables this option.
readOnlybooleanfalsePrevents changes while remaining focusable.
requiredbooleanfalseMarks this checkbox as required for form submission.
namestring—Form field name for this option. Defaults to the group name.
formstring—ID of the form that owns this option's hidden input. Defaults to the group form.
uncheckedValuestring—Value submitted when this option is unchecked.
idstring—ID of the hidden input, or of the root element when nativeButton is true.
inputRefRef<HTMLInputElement>—Ref to the hidden native input.
nativeButtonbooleanfalseWhether the rendered element is a native <button>.
renderReactElement | ((props, state) => ReactElement)—Replaces the entry root element.
aria-labelstring—Accessible name when no visible label is rendered.
aria-labelledbystring—ID of an external label.
aria-describedbystring—ID of external supporting text.
refRef<HTMLElement>—Ref forwarded to the entry root.
classNamestring—Tailwind classes merged into the entry root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ item?: ClassValue; box?: ClassValue; fill?: ClassValue; glass?: ClassValue; overlay?: ClassValue; indicator?: ClassValue; indicatorIcon?: ClassValue; wrapper?: ClassValue; itemLabel?: ClassValue; itemDescription?: ClassValue }—Tailwind classes for control slots, keyed by data-slot.

Parent checkboxes are not part of the component API. Compose them with Checkbox and keep the arrays in sync, as shown above.

ui keys map to the data-slot values listed below. All other Base UI CheckboxGroup props are forwarded. Each item also forwards the remaining Base UI Checkbox props.

AttributeDescription
data-disabledPresent when the group or an option is disabled.
data-readonlyPresent when an option is read-only.
data-requiredPresent when an option is required.
data-checkedPresent on a checked option.
data-uncheckedPresent on an unchecked option.
data-indeterminatePresent when an option is mixed.
data-slotMarks internal group parts (root, header, label, description, items) and each control (item, box, fill, glass, overlay, indicator, indicator-icon, wrapper, item-label, item-description).

Theming

The component reuses the shared glass material and the Checkbox item styling. Tune shared --ui-glass-* tokens on an ancestor, adjust group spacing with --ui-checkbox-group-gap and --ui-checkbox-group-item-gap, and use ui for internal slots keyed by data-slot. ui.item styles every option root; per-entry ui targets the same control slots. Component-specific values live in src/theme/checkbox-group.ts. See the theming guide for token layers and presets.

  • Checkbox — For a single independent choice outside a group.
  • Radio Group — When exactly one option can be selected.
  • Switch — For a setting that takes effect immediately.