eo-n/ui

Checkbox Group

Lets the user select multiple options via individual checkboxes.

import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
 
const diets = [
  {
    label: "Vegetarian",
    value: "vegetarian",
  },
  {
    label: "Vegan",
    value: "vegan",
  },
  {
    label: "Gluten-free",
    value: "gluten-free",
  },
] as const;
 
export function CheckboxGroupDemo() {
  return (
    <CheckboxGroup defaultValue={["vegetarian"]}>
      {diets.map((diet, i) => (
        <Label key={i} id={diet.value} className="flex items-center space-x-2">
          <Checkbox name={diet.value} />
          {diet.label}
        </Label>
      ))}
    </CheckboxGroup>
  );
}

Installation

npx shadcn@latest add @eo-n/checkbox-group

Import all parts and piece them together.

import { CheckboxGroup } from "@components/ui/checkbox-group";
<CheckboxGroup>
  <Checkbox />
</CheckboxGroup>

Examples

Parent Checkbox

import * as React from "react";
 
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
 
const apples = ["fuji", "gala", "granny-smith"];
 
export function CheckboxGroupDemo() {
  const [value, setValue] = React.useState<string[]>(["fuji"]);
 
  return (
    <CheckboxGroup
      aria-labelledby="apples"
      value={value}
      onValueChange={setValue}
      allValues={apples}
    >
      <Label id="apples" className="flex items-center space-x-2">
        <Checkbox name="apples" parent />
        Apples
      </Label>
      {apples.map((apple, i) => (
        <Label
          key={i}
          id={apple}
          className="flex items-center space-x-2 capitalize"
        >
          <Checkbox name={apple} />
          {apple}
        </Label>
      ))}
    </CheckboxGroup>
  );
}

Nested Parent Checkbox

import * as React from "react";
 
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
 
const mainPermissions = [
  {
    label: "View Dashboard",
    value: "view-dashboard",
  },
  {
    label: "Access Reports",
    value: "access-reports",
  },
  {
    label: "Manage Users",
    value: "manage-users",
  },
] as const;
 
const userManagementPermissions = [
  {
    label: "Create User",
    value: "create-user",
  },
  {
    label: "Edit User",
    value: "edit-user",
  },
  {
    label: "Delete User",
    value: "delete-user",
  },
  {
    label: "assign Roles",
    value: "assign-roles",
  },
];
 
export function CheckboxGroupNestedParent() {
  const [mainValue, setMainValue] = React.useState<string[]>([
    "view-dashboard",
  ]);
  const [managementValue, setManagementValue] = React.useState<string[]>([
    "create-user",
  ]);
 
  return (
    <CheckboxGroup
      aria-labelledby="permissions"
      value={mainValue}
      onValueChange={(value) => {
        if (value.includes("manage-users")) {
          setManagementValue(userManagementPermissions.map((p) => p.value));
        } else if (
          managementValue.length === userManagementPermissions.length
        ) {
          setManagementValue([]);
        }
        setMainValue(value);
      }}
      allValues={mainPermissions.map((p) => p.value)}
    >
      <Label id="permissions" className="flex items-center space-x-2">
        <Checkbox name="permissions" parent />
        User Permissions
      </Label>
      {mainPermissions
        .filter((permission) => permission.value !== "manage-users")
        .map((permission, i) => (
          <Label
            key={i}
            id={permission.value}
            className="flex items-center space-x-2"
          >
            <Checkbox name={permission.value} />
            {permission.label}
          </Label>
        ))}
      <CheckboxGroup
        aria-labelledby="manage-users"
        value={managementValue}
        onValueChange={(value) => {
          if (value.length === userManagementPermissions.length) {
            setMainValue((prev) =>
              Array.from(new Set([...prev, "manage-users"]))
            );
          } else {
            setMainValue((prev) => prev.filter((v) => v !== "manage-users"));
          }
          setManagementValue(value);
        }}
        allValues={userManagementPermissions.map((p) => p.value)}
      >
        <Label id="mangage-users" className="flex items-center space-x-2">
          <Checkbox name="mangage-users" parent />
          Manage Users
        </Label>
        {userManagementPermissions.map((permission, i) => (
          <Label
            key={i}
            id={permission.value}
            className="flex items-center space-x-2 capitalize"
          >
            <Checkbox name={permission.value} />
            {permission.label}
          </Label>
        ))}
      </CheckboxGroup>
    </CheckboxGroup>
  );
}