Skip to Content
Hashti Design System
Components

Checkbox

Selection control enabling users to select one or more options from a set.

Checkbox

Checkboxes allow users to select multiple options from a group or toggle a single binary setting. Hashti’s Checkbox and CheckboxGroup components are built on React Aria Components Checkbox, providing native indeterminate state support, tri-state ARIA semantics, group-level validation, and Persian architectural color harmonies.

Live Interactive Selection ControlsTest live Checkbox, RadioGroup, and Switch interactive states.
Checkbox
Radio Group
Switch

Architecture & Visual Form

The Hashti checkbox uses an architectural square glyph with precise corner radius and distinct checked iconography:

[Unchecked]          [Checked]            [Indeterminate]
┌───┐                ┌───┐                ┌───┐
│   │                │ ✓ │                │ − │
└───┘                └───┘                └───┘
  • Dual Mode (Single or Grouped): Use standalone Checkbox for agreement disclosures (e.g. Terms of Service), or wrap in CheckboxGroup for grouped categorical options.
  • Tri-State Support: Supports true, false, and isIndeterminate for parent-child selection trees (e.g., selecting all permissions in a role).
  • Comprehensive Group Layouts: CheckboxGroup includes built-in accessible labeling, helper descriptions, error messages, and optional/required badges.

Import

import { Checkbox, CheckboxGroup } from "@hashti/react";
import type { CheckboxProps, CheckboxGroupProps, SelectionColor } from "@hashti/react";

Usage Examples

Standalone Checkbox

A standalone checkbox is commonly used for terms acceptance or opting into optional settings:

import { useState } from "react";
import { Checkbox } from "@hashti/react";

export function SingleCheckboxDemo() {
  const [agreed, setAgreed] = useState(false);

  return (
    <Checkbox isSelected={agreed} onChange={setAgreed}>
      I agree to the Hashti Architectural Service Terms and Privacy Policy
    </Checkbox>
  );
}

Indeterminate State (Parent-Child Hierarchy)

When a parent checkbox governs a set of child checkboxes where only some are selected, set isIndeterminate={true}. The component renders an architectural minus icon (−) and announces aria-checked="mixed":

import { useState } from "react";
import { Checkbox } from "@hashti/react";

export function IndeterminateCheckboxDemo() {
  const [selectedItems, setSelectedItems] = useState<string[]>(["read"]);

  const allItems = ["read", "write", "admin"];
  const isAllSelected = selectedItems.length === allItems.length;
  const isIndeterminate = selectedItems.length > 0 && !isAllSelected;

  const toggleAll = () => {
    if (isAllSelected) {
      setSelectedItems([]);
    } else {
      setSelectedItems(allItems);
    }
  };

  const toggleItem = (item: string) => {
    setSelectedItems((prev) =>
      prev.includes(item) ? prev.filter((i) => i !== item) : [...prev, item],
    );
  };

  return (
    <div className="flex flex-col gap-2">
      <Checkbox isSelected={isAllSelected} isIndeterminate={isIndeterminate} onChange={toggleAll}>
        Select All Permissions
      </Checkbox>

      <div className="ml-6 flex flex-col gap-2 border-l border-neutral-200 pl-4 dark:border-neutral-800">
        <Checkbox isSelected={selectedItems.includes("read")} onChange={() => toggleItem("read")}>
          Read telemetry logs
        </Checkbox>
        <Checkbox isSelected={selectedItems.includes("write")} onChange={() => toggleItem("write")}>
          Write configuration changes
        </Checkbox>
        <Checkbox isSelected={selectedItems.includes("admin")} onChange={() => toggleItem("admin")}>
          Administer security tokens
        </Checkbox>
      </div>
    </div>
  );
}

CheckboxGroup with Validation & Description

Group multiple related checkboxes under a single accessible fieldset using CheckboxGroup. It coordinates label associations, descriptive helper text, and error states:

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

export function CheckboxGroupDemo() {
  const [notifications, setNotifications] = useState<string[]>(["security"]);

  return (
    <CheckboxGroup
      label="Notification Preferences"
      description="Choose which event digests you wish to receive via email."
      value={notifications}
      onChange={setNotifications}
    >
      <Checkbox value="security">Security incidents and alerts</Checkbox>
      <Checkbox value="deployments">Pipeline deployment completions</Checkbox>
      <Checkbox value="billing">Monthly invoice digests</Checkbox>
      <Checkbox value="newsletter">Hashti architectural community updates</Checkbox>
    </CheckboxGroup>
  );
}

Invalid Validation Error State

When validation fails (such as submitting an empty mandatory group), pass isInvalid and provide an errorMessage:

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

export function InvalidCheckboxGroupDemo() {
  const [selected, setSelected] = useState<string[]>([]);
  const isInvalid = selected.length === 0;

  return (
    <CheckboxGroup
      label="Required Compliance Attestation"
      description="You must select at least one compliance standard before provisioning."
      errorMessage="Please select at least one standard."
      isInvalid={isInvalid}
      value={selected}
      onChange={setSelected}
    >
      <Checkbox value="soc2">SOC 2 Type II</Checkbox>
      <Checkbox value="iso27001">ISO / IEC 27001</Checkbox>
      <Checkbox value="hipaa">HIPAA Compliance</Checkbox>
    </CheckboxGroup>
  );
}

Color Palettes

Checkboxes support five semantic color tokens (primary, secondary, success, warning, danger):

import { Checkbox } from "@hashti/react";

export function CheckboxColorsDemo() {
  return (
    <div className="flex flex-wrap gap-4">
      <Checkbox defaultSelected color="primary">
        Primary
      </Checkbox>
      <Checkbox defaultSelected color="secondary">
        Secondary
      </Checkbox>
      <Checkbox defaultSelected color="success">
        Success
      </Checkbox>
      <Checkbox defaultSelected color="warning">
        Warning
      </Checkbox>
      <Checkbox defaultSelected color="danger">
        Danger
      </Checkbox>
    </div>
  );
}

Props Reference

Checkbox Props

Checkbox extends RACCheckboxProps from react-aria-components.

PropTypeDefaultDescription
isSelectedboolean—Whether the checkbox is currently checked (controlled).
defaultSelectedbooleanfalseInitial selection state (uncontrolled).
onChange(isSelected: boolean) => void—Handler invoked when the checked state changes.
isIndeterminatebooleanfalseSets tri-state indeterminate visual icon and aria-checked="mixed".
isDisabledbooleanfalseWhether the checkbox cannot be interacted with.
isInvalidbooleanfalseIndicates validation failure and highlights the control.
color'primary' | 'secondary' | 'success' | 'warning' | 'danger''primary'Semantic color token for the checked surface.
valuestring—Value associated with the checkbox when used inside a CheckboxGroup.
childrenReactNode—Text label or content rendered adjacent to the checkbox box.
classNamestring—Additional CSS class names.

CheckboxGroup Props

CheckboxGroup extends RACCheckboxGroupProps from react-aria-components.

PropTypeDefaultDescription
labelReactNode—Accessible label for the group of checkboxes.
descriptionReactNode—Descriptive helper text displayed underneath the label.
errorMessageReactNode—Error text displayed when isInvalid is true.
valuestring[]—Controlled array of selected checkbox values.
defaultValuestring[]—Initial array of selected checkbox values (uncontrolled).
onChange(value: string[]) => void—Callback invoked when the group selection changes.
isInvalidbooleanfalseWhether the group currently fails validation.
isDisabledbooleanfalseDisables all child checkboxes within the group.
isOptionalbooleanfalseRenders an optional badge next to the group label.
colorSelectionColor'primary'Inherited color accent applied to child checkboxes.

Accessibility & Keyboard Interaction

Hashti checkboxes adhere strictly to the W3C WAI-ARIA Checkbox Pattern:

Keyboard Interaction

  • Space: Toggles the focused checkbox between checked and unchecked (or clears indeterminate state).
  • Tab: Moves keyboard focus sequentially through each individual checkbox control.

ARIA Semantics

  • Indeterminate State: Sets aria-checked="mixed", signalling to screen readers that a partial subset of child items is active.
  • Group Association: CheckboxGroup renders a semantic <div role="group"> linked to its label via aria-labelledby and its helper/error message via aria-describedby.
  • Validation Signals: When isInvalid is true, the group applies aria-invalid="true".
  • High Contrast Focus: Features an outer offset focus ring meeting the WCAG 2.2 AAA minimum 3:1 contrast ratio against both light and dark canvas surfaces.

Keyboard Interactions

KeyAction
SpaceToggles checkbox between checked, unchecked, or indeterminate.
TabMoves focus to or from the checkbox control.

WAI-ARIA & Data Attributes

AttributeTargetDescription
[data-hovered]CheckboxPresent when hovered by pointer.
[data-focused]CheckboxPresent when receiving keyboard focus.
[data-pressed]CheckboxActive during mouse or space key press.
[data-selected]CheckboxActive when checkbox is checked.
[data-indeterminate]CheckboxActive when checkbox is in indeterminate state.
[data-disabled]CheckboxPresent when checkbox is disabled.