Checkbox group
Several checkboxes answering one question together, holding the ticked ones as one list of values.
ui.checkbox-group
components/ui/checkbox-group.tsxUse case
Use it when one question takes several answers: the channels a client is notified by, the services included in a quote, the days a crew works. The group holds the ticked values as one string array (`value` and `onValueChange`), so the form saves a list rather than a row of separate booleans. Each option can carry a line of detail under its name.
Use it when
- One question, several answers allowed
- The options are few enough to read at a glance
- Each option needs a line of detail under its name
- A Select All box over the options (a `parent` checkbox with `allValues`)
Use something else when
- Only one answer may be picked: Radio group
- Many options, or options that come from data (several clients, tags): Combobox
- A single yes or no: Checkbox
- Formatting options in a toolbar (bold, italic): Toggle group
Examples
Code
Import
import { useState } from "react"
import { Checkbox } from "@/components/ui/checkbox"
import { CheckboxGroup } from "@/components/ui/checkbox-group"
import { Label } from "@/components/ui/label"Usage
const CHANNELS = [
{ value: "email", name: "Email", hint: "A letter the moment it happens" },
{ value: "text", name: "Text", hint: "On your phone, for what is urgent" },
]
export function NotifyBy() {
const [value, setValue] = useState(["email"])
return (
<CheckboxGroup value={value} onValueChange={setValue} aria-label="Notify by" className="grid gap-3">
{CHANNELS.map((c) => (
<Label key={c.value} className="flex cursor-pointer items-start gap-3 font-normal">
<Checkbox value={c.value} className="mt-0.5" />
<span className="grid gap-0.5">
<span className="text-[14px] font-medium text-foreground">{c.name}</span>
<span className="text-[12.5px] text-ink-4">{c.hint}</span>
</span>
</Label>
))}
</CheckboxGroup>
)
}Rules
- Every `Checkbox` inside carries a `value`; the group's `value` is the array of the ticked ones.
- Name the group with `aria-label`, or `aria-labelledby` pointing at a visible heading.
- Each option's name is sentence case, its detail under it in `text-ink-4`, both inside one `Label` with the box.
- A `parent` checkbox needs a controlled group (`value`, `onValueChange`) and `allValues` listing every option's value.