import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxBasicDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Checkbox
      label="Accept terms and conditions"
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}

Installation

Barrel

import { Checkbox } from "@cloudflare/kumo";

Granular

import { Checkbox } from "@cloudflare/kumo/components/checkbox";

Usage

import { Checkbox } from "@cloudflare/kumo";

export default function Example() {
  return <Checkbox label="Accept terms" />;
}

Examples

Default

Checkbox with built-in label. The label automatically displays in a horizontal layout (checkbox before label).

import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxDefaultDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Checkbox
      label="Enable notifications"
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}

Checked

import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxCheckedDemo() {
  const [checked, setChecked] = useState(true);
  return (
    <Checkbox label="I agree" checked={checked} onCheckedChange={setChecked} />
  );
}

Indeterminate

Used for “select all” patterns when some but not all items are selected.

import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxIndeterminateDemo() {
  const [indeterminate, setIndeterminate] = useState(true);
  return (
    <Checkbox
      label="Select all"
      indeterminate={indeterminate}
      onCheckedChange={setIndeterminate}
    />
  );
}

Label First Layout

Use controlFirst={false} to place the label before the checkbox.

import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxLabelFirstDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Checkbox
      label="Remember me"
      controlFirst={false}
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}

Disabled

import { Checkbox } from "@cloudflare/kumo";

export function CheckboxDisabledDemo() {
  return <Checkbox label="Disabled option" disabled />;
}

Error

Error variant provides visual styling (red ring). For error messages, use Checkbox.Group.

import { Checkbox } from "@cloudflare/kumo";

export function CheckboxErrorDemo() {
  return <Checkbox label="Invalid option" variant="error" />;
}

Checkbox Group

Group multiple checkboxes with a legend, description, and shared error messages. Uses Checkbox.Group and Checkbox.Item.

Email preferences

Choose how you'd like to receive updates

import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

export function CheckboxGroupDemo() {
  const [preferences, setPreferences] = useState<string[]>(["email"]);

  return (
    <Checkbox.Group
      legend="Email preferences"
      description="Choose how you'd like to receive updates"
      value={preferences}
      onValueChange={setPreferences}
    >
      <Checkbox.Item value="email" label="Email notifications" />
      <Checkbox.Item value="sms" label="SMS notifications" />
      <Checkbox.Item value="push" label="Push notifications" />
    </Checkbox.Group>
  );
}

Checkbox Group with Error

Show validation errors at the group level. Error replaces description when present.

Required preferences

Please select at least one notification method

import { Checkbox } from "@cloudflare/kumo";

export function CheckboxGroupErrorDemo() {
  return (
    <Checkbox.Group
      legend="Required preferences"
      error="Please select at least one notification method"
      value={[]}
      onValueChange={() => {}}
    >
      <Checkbox.Item value="email" label="Email" variant="error" />
      <Checkbox.Item value="sms" label="SMS" variant="error" />
    </Checkbox.Group>
  );
}

Visually Hidden Legend

Use Checkbox.Legend with className="sr-only" to keep the legend accessible to screen readers while hiding it visually. This is useful when the group is already labeled by a parent Field or heading, and showing the legend would create a redundant label.

Notification preferences
import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

/** Shows Checkbox.Legend with sr-only to visually hide the legend while keeping it accessible, useful when a parent Field already provides a visible label */
export function CheckboxLegendSrOnlyDemo() {
  const [preferences, setPreferences] = useState<string[]>(["email"]);
  return (
    <Checkbox.Group value={preferences} onValueChange={setPreferences}>
      <Checkbox.Legend className="sr-only">
        Notification preferences
      </Checkbox.Legend>
      <Checkbox.Item value="email" label="Email notifications" />
      <Checkbox.Item value="sms" label="SMS notifications" />
      <Checkbox.Item value="push" label="Push notifications" />
    </Checkbox.Group>
  );
}

Custom Legend Styling

Checkbox.Legend accepts className for full control over legend presentation. Use it instead of the legend string prop when you need custom typography, colors, or layout.

Notification preferences
import { useState } from "react";
import { Checkbox } from "@cloudflare/kumo";

/** Shows Checkbox.Legend with custom styling for full control over legend presentation */
export function CheckboxLegendCustomDemo() {
  const [preferences, setPreferences] = useState<string[]>(["email"]);
  return (
    <Checkbox.Group value={preferences} onValueChange={setPreferences}>
      <Checkbox.Legend className="text-sm font-normal text-kumo-subtle">
        Notification preferences
      </Checkbox.Legend>
      <Checkbox.Item value="email" label="Email notifications" />
      <Checkbox.Item value="sms" label="SMS notifications" />
      <Checkbox.Item value="push" label="Push notifications" />
    </Checkbox.Group>
  );
}

API Reference

Checkbox

Single checkbox component with built-in label and horizontal layout.

PropTypeDefaultDescription
variant"default" | "error""default"Visual variant: "default" or "error" for validation failures (visual only, no error text)
labelReactNode-Label content for the checkbox (enables built-in Field wrapper) - can be a string or any React node
labelTooltipReactNode-Tooltip content to display next to the label via an info icon
controlFirstboolean-When true (default), checkbox appears before label. When false, label appears before checkbox.
checkedboolean-Whether the checkbox is checked (controlled)
indeterminateboolean-Whether the checkbox is in indeterminate state
disabledboolean-Whether the checkbox is disabled
namestring-Name for form submission
requiredboolean-Whether the field is required
classNamestring-Additional class name
onValueChange(checked: boolean) => void-Callback when checkbox value changes

Checkbox.Group

Wrapper for multiple checkboxes with legend, description, and error support.

PropTypeDefault
legendstring-
children*ReactNode-
errorstring-
descriptionReactNode-
valuestring[]-
allValuesstring[]-
disabledboolean-
controlFirstboolean-
classNamestring-

Checkbox.Legend

Composable legend sub-component for Checkbox.Group. Accepts className for full styling control (e.g. className="sr-only" to visually hide). Use instead of the legend string prop when you need custom legend styling.

PropTypeDefault
children*ReactNode-
classNamestring-

Checkbox.Item

Individual checkbox within Checkbox.Group.

PropTypeDefault

No component-specific props. Accepts standard HTML attributes.

Accessibility

Label Requirement

Single checkboxes require a label prop or aria-label for accessibility. Missing labels trigger console warnings in development.

Keyboard Navigation

Space toggles the checkbox. Tab moves focus between checkboxes.

Screen Readers

Checkbox.Group uses semantic <fieldset> and <legend> elements for proper grouping announcement.