CheckboxGroupNew

A checkbox group component for managing multiple checkbox selections

Import

import { CheckboxGroup, Checkbox, Label, Description } from '@heroui/react';

Usage

Select your interestsChoose all that apply
import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react";

export function Basic() {
  return (
    <CheckboxGroup name="interests">
      <Label>Select your interests</Label>
      <Description>Choose all that apply</Description>
      <Checkbox value="coding">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Coding</Label>
          <Description>Love building software</Description>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="design">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Design</Label>
          <Description>Enjoy creating beautiful interfaces</Description>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="writing">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Writing</Label>
          <Description>Passionate about content creation</Description>
        </Checkbox.Content>
      </Checkbox>
    </CheckboxGroup>
  );
}

Anatomy

Import the CheckboxGroup component and access all parts using dot notation.

import {CheckboxGroup, Checkbox, Label, Description, FieldError} from '@heroui/react';

export default () => (
  <CheckboxGroup name="interests">
    <Label />
    <Description /> {/* Optional */}
    <Checkbox value="option1">
      <Checkbox.Control>
        <Checkbox.Indicator />
      </Checkbox.Control>
      <Checkbox.Content>
        <Label />
        <Description /> {/* Optional */}
      </Checkbox.Content>
    </Checkbox>
    <FieldError /> {/* Optional */}
  </CheckboxGroup>
);

On Surface

When used inside a Surface component, CheckboxGroup automatically applies on-surface styling.

Select your interestsChoose all that apply
import {Checkbox, CheckboxGroup, Description, Label, Surface} from "@heroui/react";

export function OnSurface() {
  return (
    <Surface className="w-full rounded-3xl p-6">
      <CheckboxGroup name="interests">
        <Label>Select your interests</Label>
        <Description>Choose all that apply</Description>
        <Checkbox value="coding">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>Coding</Label>
            <Description>Love building software</Description>
          </Checkbox.Content>
        </Checkbox>
        <Checkbox value="design">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>Design</Label>
            <Description>Enjoy creating beautiful interfaces</Description>
          </Checkbox.Content>
        </Checkbox>
        <Checkbox value="writing">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>Writing</Label>
            <Description>Passionate about content creation</Description>
          </Checkbox.Content>
        </Checkbox>
      </CheckboxGroup>
    </Surface>
  );
}

With Custom Indicator

FeaturesSelect the features you want
"use client";

import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react";

export function WithCustomIndicator() {
  return (
    <CheckboxGroup name="features">
      <Label>Features</Label>
      <Description>Select the features you want</Description>
      <Checkbox value="notifications">
        <Checkbox.Control>
          <Checkbox.Indicator>
            {({isSelected}) =>
              isSelected ? (
                <svg
                  aria-hidden="true"
                  fill="none"
                  stroke="currentColor"
                  strokeLinecap="round"
                  strokeWidth={2}
                  viewBox="0 0 24 24"
                >
                  <path d="M6 18L18 6M6 6l12 12" />
                </svg>
              ) : null
            }
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Email notifications</Label>
          <Description>Receive updates via email</Description>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="newsletter">
        <Checkbox.Control>
          <Checkbox.Indicator>
            {({isSelected}) =>
              isSelected ? (
                <svg
                  aria-hidden="true"
                  fill="none"
                  stroke="currentColor"
                  strokeLinecap="round"
                  strokeWidth={2}
                  viewBox="0 0 24 24"
                >
                  <path d="M6 18L18 6M6 6l12 12" />
                </svg>
              ) : null
            }
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Newsletter</Label>
          <Description>Get weekly newsletters</Description>
        </Checkbox.Content>
      </Checkbox>
    </CheckboxGroup>
  );
}

Indeterminate

"use client";

import {Checkbox, CheckboxGroup, Label} from "@heroui/react";
import {useState} from "react";

export function Indeterminate() {
  const [selected, setSelected] = useState(["coding"]);
  const allOptions = ["coding", "design", "writing"];

  return (
    <div>
      <Checkbox
        isIndeterminate={selected.length > 0 && selected.length < allOptions.length}
        isSelected={selected.length === allOptions.length}
        name="select-all"
        onChange={(isSelected: boolean) => {
          setSelected(isSelected ? allOptions : []);
        }}
      >
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Select all</Label>
        </Checkbox.Content>
      </Checkbox>
      <div className="ml-6 flex flex-col gap-2">
        <CheckboxGroup value={selected} onChange={setSelected}>
          <Checkbox value="coding">
            <Checkbox.Control>
              <Checkbox.Indicator />
            </Checkbox.Control>
            <Checkbox.Content>
              <Label>Coding</Label>
            </Checkbox.Content>
          </Checkbox>
          <Checkbox value="design">
            <Checkbox.Control>
              <Checkbox.Indicator />
            </Checkbox.Control>
            <Checkbox.Content>
              <Label>Design</Label>
            </Checkbox.Content>
          </Checkbox>
          <Checkbox value="writing">
            <Checkbox.Control>
              <Checkbox.Indicator />
            </Checkbox.Control>
            <Checkbox.Content>
              <Label>Writing</Label>
            </Checkbox.Content>
          </Checkbox>
        </CheckboxGroup>
      </div>
    </div>
  );
}

Controlled

Your skillsSelected: coding, design
"use client";

import {Checkbox, CheckboxGroup, Label} from "@heroui/react";
import {useState} from "react";

export function Controlled() {
  const [selected, setSelected] = useState(["coding", "design"]);

  return (
    <CheckboxGroup className="min-w-[320px]" name="skills" value={selected} onChange={setSelected}>
      <Label>Your skills</Label>
      <Checkbox value="coding">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Coding</Label>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="design">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Design</Label>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="writing">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Writing</Label>
        </Checkbox.Content>
      </Checkbox>
      <Label className="text-muted my-4 text-sm">Selected: {selected.join(", ") || "None"}</Label>
    </CheckboxGroup>
  );
}

Validation

Preferences
"use client";

import {Button, Checkbox, CheckboxGroup, FieldError, Form, Label} from "@heroui/react";

export function Validation() {
  return (
    <Form
      className="flex flex-col gap-4 px-4"
      onSubmit={(e) => {
        e.preventDefault();

        const formData = new FormData(e.currentTarget);
        const values = formData.getAll("preferences");

        alert(`Selected preferences: ${values.join(", ")}`);
      }}
    >
      <CheckboxGroup isRequired name="preferences">
        <Label>Preferences</Label>
        <Checkbox value="email">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>Email notifications</Label>
          </Checkbox.Content>
        </Checkbox>
        <Checkbox value="sms">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>SMS notifications</Label>
          </Checkbox.Content>
        </Checkbox>
        <Checkbox value="push">
          <Checkbox.Control>
            <Checkbox.Indicator />
          </Checkbox.Control>
          <Checkbox.Content>
            <Label>Push notifications</Label>
          </Checkbox.Content>
        </Checkbox>
        <FieldError>Please select at least one notification method.</FieldError>
      </CheckboxGroup>
      <Button type="submit">Submit</Button>
    </Form>
  );
}

Disabled

FeaturesFeature selection is temporarily disabled
import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react";

export function Disabled() {
  return (
    <CheckboxGroup isDisabled name="disabled-features">
      <Label>Features</Label>
      <Description>Feature selection is temporarily disabled</Description>
      <Checkbox value="feature1">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Feature 1</Label>
          <Description>This feature is coming soon</Description>
        </Checkbox.Content>
      </Checkbox>
      <Checkbox value="feature2">
        <Checkbox.Control>
          <Checkbox.Indicator />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Feature 2</Label>
          <Description>This feature is coming soon</Description>
        </Checkbox.Content>
      </Checkbox>
    </CheckboxGroup>
  );
}

Styling

Passing Tailwind CSS classes

You can customize the CheckboxGroup component:

import { CheckboxGroup, Checkbox, Label } from '@heroui/react';

function CustomCheckboxGroup() {
  return (
    <CheckboxGroup className="gap-4" name="custom">
      <Checkbox value="option1">
        <Checkbox.Control className="border-2 border-purple-500 data-[selected=true]:bg-purple-500">
          <Checkbox.Indicator className="text-white" />
        </Checkbox.Control>
        <Checkbox.Content>
          <Label>Option 1</Label>
        </Checkbox.Content>
      </Checkbox>
    </CheckboxGroup>
  );
}

Customizing the component classes

To customize the CheckboxGroup component classes, you can use the @layer components directive.
Learn more.

@layer components {
  .checkbox-group {
    @apply flex flex-col gap-2;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The CheckboxGroup component uses these CSS classes (View source styles):

  • .checkbox-group - Base checkbox group container

API Reference

CheckboxGroup Props

Inherits from React Aria CheckboxGroup.

PropTypeDefaultDescription
valuestring[]-The current selected values (controlled)
defaultValuestring[]-The default selected values (uncontrolled)
onChange(value: string[]) => void-Handler called when the selected values change
isDisabledbooleanfalseWhether the checkbox group is disabled
isRequiredbooleanfalseWhether the checkbox group is required
isReadOnlybooleanfalseWhether the checkbox group is read only
isInvalidbooleanfalseWhether the checkbox group is in an invalid state
namestring-The name of the checkbox group, used when submitting an HTML form
childrenReact.ReactNode | (values: CheckboxGroupRenderProps) => React.ReactNode-Checkbox group content or render prop

CheckboxGroupRenderProps

When using the render prop pattern, these values are provided:

PropTypeDescription
valuestring[]The currently selected values
isDisabledbooleanWhether the checkbox group is disabled
isReadOnlybooleanWhether the checkbox group is read only
isInvalidbooleanWhether the checkbox group is in an invalid state
isRequiredbooleanWhether the checkbox group is required