Marble UI
← Components

Checkbox Group

Preview: Default

Checkbox with label and description; supports indeterminate, groups and a card style.

Import

import { Checkbox, CheckboxGroup } from '@marbleui/ui'

This is a style of checkbox; see its examples for all variants.

Props

<Checkbox>

PropTypeDefaultDescription
descriptionReactNode—
variant'default' | 'card''default'

Also accepts React Aria props (111).

<CheckboxGroup>

PropTypeDefaultDescription
childrenReactNode—
descriptionReactNode—
errorMessagestring | ((validation: ValidationResult) => string)—
labelReactNode—

Also accepts React Aria props (94).

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Checkbox · React Aria CheckboxGroup. Follow the primitive's docs for the full keyboard map.

Usage notes

CheckboxGroup for picking any number of options from a visible list. This page covers group patterns; see Checkbox for the basics.

const all = ['email', 'push', 'sms']
const [channels, setChannels] = useState(['email'])
<Checkbox isSelected={channels.length === all.length} isIndeterminate={channels.length > 0 && channels.length < all.length} onChange={(on) => setChannels(on ? all : [])}>All channels</Checkbox>
<CheckboxGroup aria-label="Channels" value={channels} onChange={setChannels}>
  <Checkbox value="email">Email</Checkbox>
  <Checkbox value="push">Push</Checkbox>
  <Checkbox value="sms">SMS</Checkbox>
</CheckboxGroup>
  • Keep a select-all checkbox outside the group, as above, and derive its state from the array.
  • isRequired on the group means at least one must be checked; validate receives the array for other rules.
  • name submits each checked value with a native form; isDisabled and isReadOnly apply to every checkbox.
  • The group stacks vertically (no orientation prop); className="flex-row" lays it out in a row.
Example source · show
import { useState } from 'react'
import { Checkbox, CheckboxGroup } from './checkbox'

function SelectAll() {
  const all = ['email', 'push', 'sms']
  const [selected, setSelected] = useState<string[]>(['email'])
  return (
    <div className="flex flex-col gap-2.5">
      <Checkbox
        isSelected={selected.length === all.length}
        isIndeterminate={selected.length > 0 && selected.length < all.length}
        onChange={(on) => setSelected(on ? all : [])}
      >
        All channels
      </Checkbox>
      <CheckboxGroup aria-label="Channels" value={selected} onChange={setSelected} className="pl-6">
        <Checkbox value="email">Email</Checkbox>
        <Checkbox value="push">Push</Checkbox>
        <Checkbox value="sms">SMS</Checkbox>
      </CheckboxGroup>
    </div>
  )
}

export const styles = {
  Default: () => (
    <CheckboxGroup label="Notifications" defaultValue={['mentions']}>
      <Checkbox value="mentions">Mentions</Checkbox>
      <Checkbox value="replies" description="Only threads you started.">Replies</Checkbox>
      <Checkbox value="digest" isDisabled>Weekly digest</Checkbox>
    </CheckboxGroup>
  ),
  Indeterminate: SelectAll,
  Card: () => (
    <CheckboxGroup aria-label="Add-ons" defaultValue={['backups']} className="w-80">
      <Checkbox variant="card" value="backups" description="Daily snapshots, kept 30 days.">Automatic backups</Checkbox>
      <Checkbox variant="card" value="sso" description="SAML and SCIM provisioning.">Single sign-on</Checkbox>
    </CheckboxGroup>
  ),
}

Source: packages/ui/src/checkbox/checkbox.tsx

Catalog

Category
selection
Priority
Core
Primitive
react-aria
React Aria
CheckboxGroup
Base UI
Checkbox Group