Skip to content
  1. Keyline UI
  2. Checkbox group
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Checkbox group

Several choices that answer one question, in one frame. An All row sits above a 2px rule and shows how many are checked; disabled rows keep their state.

Loading the live example…

"use client"

import { useState } from "react"
import { CheckboxGroup } from "@/components/keyline/ui/checkbox-group"

const REPS = [
  { value: "dwight", label: "Dwight Schrute", meta: "41" },
  { value: "jim", label: "Jim Halpert", meta: "33" },
  { value: "phyllis", label: "Phyllis Vance", meta: "28" },
  { value: "stanley", label: "Stanley Hudson", meta: "26" },
  { value: "andy", label: "Andy Bernard", description: "Away until Friday", meta: "19", disabled: true },
]

export function PriceListRecipients() {
  const [to, setTo] = useState(["dwight", "jim"])
  const names = REPS.filter((r) => to.includes(r.value)).map((r) => r.label.split(" ")[0])

  return (
    <div className="grid max-w-[420px] gap-3">
      <CheckboxGroup legend="Send the new price list to" description="Open accounts per rep." selectAll="All of sales" options={REPS} value={to} onValueChange={setTo} />
      <p role="status" className="m-0 text-[14px] text-kl-ink-2">
        {names.length ? `${names.join(", ")} will get it at 9 tomorrow.` : "Nobody gets it yet."}
      </p>
    </div>
  )
}

Installation

npx shadcn@latest add @keyline-ui/checkbox-group

Run it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.

Usage

import { CheckboxGroup } from "@/components/keyline/ui/checkbox-group"
<CheckboxGroup
  legend="Send the new price list to"
  selectAll="All of sales"
  options={[
    { value: "dwight", label: "Dwight Schrute", meta: "41" },
    { value: "jim", label: "Jim Halpert", meta: "33" },
  ]}
  value={to}
  onValueChange={setTo}
/>

Examples

In a form

With a name, the checked values go to onFormSubmit. Submit with nothing checked to see validate fail.

Loading the live example…

"use client"

import { useState } from "react"
import { Button } from "@/components/keyline/ui/button"
import { CheckboxGroup } from "@/components/keyline/ui/checkbox-group"
import { Form, FormActions } from "@/components/keyline/ui/field"

const SUPPLIES = [
  { value: "cake", label: "Sheet cake", meta: "$38" },
  { value: "balloons", label: "Balloons", meta: "$12" },
  { value: "streamers", label: "Streamers", description: "Not red. Angela was clear.", meta: "$6" },
  { value: "plates", label: "Plates and forks", meta: "$9" },
]

export function PartySupplies() {
  const [sent, setSent] = useState<string | null>(null)

  return (
    <Form className="max-w-[420px]" onFormSubmit={(v) => {
        const n = (v.supplies as string[]).length
        setSent(`List sent to Angela: ${n} ${n === 1 ? "item" : "items"}.`)
      }}>
      <CheckboxGroup
        name="supplies"
        legend="For Meredith's birthday, buy"
        options={SUPPLIES}
        validate={(value) => ((value as string[]).length ? null : "Pick at least one. The party is at 3.")}
      />
      <FormActions>
        <Button type="submit" variant="primary">
          Send to Angela
        </Button>
      </FormActions>
      <p role="status" className="m-0 min-h-5 text-[14px] text-kl-ink-2">
        {sent}
      </p>
    </Form>
  )
}

Props

PropTypeDefaultDescription
legendReactNodeDefault —The question the group answers. Required.
options{ value, label, description?, meta?, disabled? }[]Default []meta is a cell at the end of the row, for a count or a price.
valuestring[]Default —The checked values, with onValueChange. Or start with defaultValue.
selectAllboolean | ReactNodeDefault —Adds a row that checks or clears every enabled option. It shows a bar while some are checked, and counts them.
namestringDefault —Puts the checked values in the Form values under this name.
validate(value: string[]) => string | nullDefault —Return a message to fail, such as when nothing is checked.
layout"control" | "cell"Default "control"cell drops the frame and hides the legend, for rows inside a panel or popover.

Also exported: CheckboxGroupItem, for a row the options can't describe. Tab visits each box and Space toggles it. Built on Base UI Checkbox Group.

Sheet 18 of 73PreviousCheckboxNextRadio group
On this page