Checkbox Group

A set of checkboxes that share one value array, with an optional list style and option descriptions.

Notifications
Choose what we email you about.

Usage

import { Checkbox } from '@epilot/spark-ui/checkbox'
import { CheckboxGroup } from '@epilot/spark-ui/checkbox-group'
function Notifications() {
  return (
    <CheckboxGroup defaultValue={['invoice']} aria-label="Notifications">
      <label className="flex items-center gap-3">
        <Checkbox value="meter" />
        <span>Meter reading reminder</span>
      </label>
      <label className="flex items-center gap-3">
        <Checkbox value="invoice" />
        <span>New invoice</span>
      </label>
    </CheckboxGroup>
  )
}

CheckboxGroup holds the checked values as a string[]: each Checkbox takes a value, and the group reports the ticked ones through onValueChange. Props and slots mirror Radio's RadioGroup.

Wrap the group in FieldSet, FieldLegend, FieldDescription and FieldError to give it a shared label, hint and error. See Selection groups for slot order and for choosing between checkboxes, switches and radios.

Use CheckboxGroup when several options can be on at once and the form saves them together. Use Switch Group when each option applies immediately. Use RadioGroup when exactly one option is allowed.

Examples

List styles

Set listStyle to show the options as a list of SelectionItem rows: soft, surface, outlined or ghost. The styles reuse the input chrome, so a list sits next to Input and Select in a form. SelectionItem takes the Checkbox as control, plus a label and an optional description.

soft
surface
outlined
ghost

Required with an error

Put indicator="required" on FieldSet to mark the legend. A FieldError inside the set renders as an error callout above the options, turns the legend red and tints the list.

Notifications required
Choose at least one.

API Reference

CheckboxGroup

This component wraps Base UI Checkbox Group. It accepts value, defaultValue, onValueChange, allValues and disabled.

PropTypeDefaultDescription
listStyle"soft" | "surface" | "outlined" | "ghost"noneShows the options as a styled list of SelectionItem rows. Without it the group is a plain stack. Ignores gap.
styleVariant"solid" | "soft" | "surface" | "outline"solidStyle of each checkbox control. Independent of listStyle.
color"accent" | "neutral" | "danger"accentRe-colors each checkbox control.
gapnumber3--spark-layout-gap units between checkboxes. Ignored when listStyle is set.
classNamestring—Merges with the base styles.

SelectionItem

Extends <label> props, except children. See Selection groups.

PropTypeDefaultDescription
controlReactElement—A Checkbox, Switch or Radio. Spark adds its label and description ids to any aria-labelledby and aria-describedby it already has, so skip your own aria-label.
labelReactNode—The option name. It becomes the control's accessible name.
descriptionReactNode—Text under the label. It becomes the control's accessible description.

Accessibility

  • CheckboxGroup renders role="group". Inside a FieldSet, the <fieldset> and <legend> name the set; outside one, pass aria-label or aria-labelledby to the group.
  • The FieldSet announces its error first, then its description, through aria-describedby. A group-level FieldError keeps role="alert", so screen readers read it when it appears.
  • indicator="required" adds a visible * hidden from assistive tech, plus visually hidden text ("required"). Pass indicatorLabel on FieldSet to translate it. indicator="optional" shows the visible text "(optional)".
  • SelectionItem names each checkbox by its label and describes it by its description, so a screen reader reads both without merging them.
  • Keyboard: Tab moves between checkboxes, Space toggles the focused one.
  • Do not rely on color alone for the error: the callout text states the problem.

On this page