Skip to main content

Import

import { CheckboxGroup } from "@kuzenbo/core";

Usage

The CheckboxGroup component manages multiple checkboxes as a coordinated set. It handles selection state and provides callbacks for value changes.
import { Checkbox, CheckboxGroup, Label } from "@kuzenbo/core";
import { useState } from "react";

const permissions = [
  { label: "View finance dashboard", value: "view-finance-dashboard" },
  { label: "Approve reimbursements", value: "approve-reimbursements" },
  { label: "Export vendor ledger", value: "export-vendor-ledger" },
];

export default function PermissionsForm() {
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([
    "view-finance-dashboard",
  ]);

  return (
    <CheckboxGroup
      value={selectedPermissions}
      onValueChange={setSelectedPermissions}
    >
      {permissions.map((permission) => (
        <Label
          className="flex items-center gap-2"
          key={permission.value}
        >
          <Checkbox value={permission.value} />
          {permission.label}
        </Label>
      ))}
    </CheckboxGroup>
  );
}

With Description

Provide additional context for each checkbox option:
import { Checkbox, CheckboxGroup, Label } from "@kuzenbo/core";
import { useState } from "react";

const governanceOptions = [
  {
    description: "Required for security sign-off during procurement reviews.",
    label: "Attach SOC 2 summary",
    value: "soc2-report",
  },
  {
    description: "Includes legal language for EU and UK data handling.",
    label: "Attach DPA template",
    value: "dpa-template",
  },
  {
    description: "Lists open exceptions and compensating controls.",
    label: "Attach risk register",
    value: "risk-register",
  },
];

export default function GovernanceAttachments() {
  const [selectedAttachments, setSelectedAttachments] = useState<string[]>([
    "soc2-report",
    "dpa-template",
  ]);

  return (
    <CheckboxGroup
      className="gap-2"
      value={selectedAttachments}
      onValueChange={setSelectedAttachments}
    >
      {governanceOptions.map((option) => (
        <Label
          className="border-border grid gap-0.5 rounded-md border px-3 py-2"
          key={option.value}
        >
          <span className="flex items-center gap-2">
            <Checkbox value={option.value} />
            {option.label}
          </span>
          <span className="text-muted-foreground pl-6 text-sm">
            {option.description}
          </span>
        </Label>
      ))}
    </CheckboxGroup>
  );
}

Disabled Option

Disable individual checkboxes within the group:
import { Checkbox, CheckboxGroup, Label } from "@kuzenbo/core";
import { useState } from "react";

export default function ConditionalPermissions() {
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([
    "audit-log-read",
  ]);

  return (
    <CheckboxGroup
      value={selectedPermissions}
      onValueChange={setSelectedPermissions}
    >
      <Label className="flex items-center gap-2">
        <Checkbox value="audit-log-read" />
        Read audit logs
      </Label>
      <Label className="flex items-center gap-2">
        <Checkbox value="manage-sso" />
        Manage SSO provider
      </Label>
      <Label className="flex items-center gap-2">
        <Checkbox disabled value="create-custom-roles" />
        Create custom roles (Enterprise only)
      </Label>
    </CheckboxGroup>
  );
}

Controlled with Summary

import { Checkbox, CheckboxGroup, Label } from "@kuzenbo/core";
import { useState, useMemo } from "react";

const permissions = [
  { label: "View finance dashboard", value: "view-finance-dashboard" },
  { label: "Approve reimbursements", value: "approve-reimbursements" },
  { label: "Export vendor ledger", value: "export-vendor-ledger" },
];

export default function PermissionsWithSummary() {
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([
    "view-finance-dashboard",
  ]);

  const summary = useMemo(() => {
    if (selectedPermissions.length === permissions.length) {
      return "All finance permissions are granted.";
    }
    if (selectedPermissions.length === 0) {
      return "No finance permissions are granted.";
    }
    return `${selectedPermissions.length} of ${permissions.length} permissions granted.`;
  }, [selectedPermissions.length]);

  return (
    <div className="grid gap-2">
      <CheckboxGroup
        value={selectedPermissions}
        onValueChange={setSelectedPermissions}
      >
        {permissions.map((permission) => (
          <Label
            className="flex items-center gap-2"
            key={permission.value}
          >
            <Checkbox value={permission.value} />
            {permission.label}
          </Label>
        ))}
      </CheckboxGroup>
      <p className="text-muted-foreground text-sm">{summary}</p>
    </div>
  );
}

Props

value
string[]
Array of currently selected checkbox values. Controls the checked state.
onValueChange
(value: string[]) => void
Callback fired when the selection changes. Receives the new array of selected values.
defaultValue
string[]
Initial selection for uncontrolled usage.
disabled
boolean
default:false
Disables all checkboxes in the group.
className
string
Additional CSS classes for the container.
children
ReactNode
Checkbox elements to manage. Typically wrapped in Label components.

Types

export type CheckboxGroupProps = ComponentProps<typeof BaseCheckboxGroup>;

Accessibility

  • Uses proper ARIA attributes for group semantics
  • Each checkbox is keyboard-navigable with Tab
  • Space toggles the focused checkbox
  • Screen readers announce group context and selection state
  • Disabled state is communicated to assistive technologies

Build docs developers (and LLMs) love