VayuUI

Checkbox

A control that allows the user to make a binary choice with support for indeterminate state.

Installation

npx vayu-ui init #one time only
npx vayu-ui add checkbox
npx vayu-ui add -t checkbox #with test case needs

Usage

Basic Checkbox
With Description

Receive updates about new products and features

Error State
Indeterminate State
<Checkbox checked={checked} onChange={setChecked}>
  <div className="flex items-start gap-3">
    <Checkbox.Indicator />
    <Checkbox.Label>Accept terms and conditions</Checkbox.Label>
  </div>
</Checkbox>

<Checkbox>
  <div className="flex items-start gap-3">
    <Checkbox.Indicator />
    <div className="flex flex-col gap-1">
      <Checkbox.Label>Marketing emails</Checkbox.Label>
      <Checkbox.Description>
        Receive updates about new products and features
      </Checkbox.Description>
    </div>
  </div>
</Checkbox>

<Checkbox error>
  <div className="flex items-start gap-3">
    <Checkbox.Indicator />
    <div className="flex flex-col gap-1">
      <Checkbox.Label>Required field</Checkbox.Label>
      <Checkbox.Error>You must accept to continue</Checkbox.Error>
    </div>
  </div>
</Checkbox>

<Checkbox indeterminate>
  <div className="flex items-center gap-3">
    <Checkbox.Indicator />
    <Checkbox.Label>Select all</Checkbox.Label>
  </div>
</Checkbox>

<Checkbox disabled>
  <div className="flex items-center gap-3">
    <Checkbox.Indicator />
    <Checkbox.Label>Disabled option</Checkbox.Label>
  </div>
</Checkbox>

Anatomy

import { Checkbox } from 'vayu-ui';

<Checkbox checked={checked} onChange={setChecked}>
  <div className="flex items-start gap-3">
    <Checkbox.Indicator />
    <div className="flex flex-col gap-1">
      <Checkbox.Label>Label</Checkbox.Label>
      <Checkbox.Description>Description text</Checkbox.Description>
      <Checkbox.Error>Error message</Checkbox.Error>
    </div>
  </div>
</Checkbox>;
  • Checkbox — Root container. Manages checked/indeterminate/disabled state and provides context to children.
  • Checkbox.Indicator — Renders a hidden native <input type="checkbox"> and a custom visual checkbox with check or minus icon.
  • Checkbox.Label — Accessible label associated with the checkbox input via htmlFor.
  • Checkbox.Description — Helper text below the label, linked via aria-describedby.
  • Checkbox.Error — Error message with role="alert" and aria-live="polite" for screen reader announcements.

Accessibility

  • Keyboard Support:
    • Space — Toggle the checkbox checked state.
    • Tab — Move focus to the next checkbox.
    • Shift + Tab — Move focus to the previous checkbox.
  • ARIA Attributes:
    • aria-checked reflects checked, unchecked, or mixed (indeterminate) state on the native input.
    • aria-invalid="true" set when error prop is passed.
    • aria-describedby links the input to its description and error elements when present.
    • Error message uses role="alert" and aria-live="polite" for dynamic announcements.
  • Focus Behavior:
    • Visible focus ring (focus-visible) on the checkbox indicator using the focus design token.
    • Focus ring meets WCAG 2.2 AA contrast requirements.

Screen reader behavior

When a user navigates to a checkbox, the screen reader announces the label text, the current state (checked or unchecked), and the name of the control. When in the indeterminate state, the screen reader announces "mixed" as the value. If an error is present, the screen reader announces the error message due to aria-live="polite" and role="alert" on the error element, which is linked to the input via aria-describedby. If a description is provided, it is also announced after the label. The native checkbox input ensures standard checkbox semantics are conveyed without additional ARIA role declarations.

Component Folder Structure

CheckBox/
├── CheckBox.tsx            # Root component with context provider and state management
├── CheckBoxIndicator.tsx   # Hidden native input + custom visual checkbox
├── CheckBoxLabel.tsx       # Accessible label linked to the checkbox input
├── CheckBoxDescription.tsx # Helper description text below the label
├── CheckBoxError.tsx       # Error message with aria-live for screen readers
├── hooks.ts                # Context creation and useCheckboxContext hook
├── types.ts                # TypeScript type definitions
├── index.ts                # Re-exports Checkbox compound component and types
└── README.md               # Component usage reference

Props

Checkbox (Root)

PropTypeDefaultDescription
checkedbooleanControlled checked state.
defaultCheckedbooleanfalseDefault checked state for uncontrolled mode.
indeterminatebooleanfalseShows indeterminate state (minus icon).
disabledbooleanfalseDisables the checkbox.
errorbooleanfalseShows error styling on the indicator.
onChange(checked: boolean) => voidCallback when checked state changes.
namestringForm field name for form submission.
valuestringForm field value.
requiredbooleanMarks the field as required.

Checkbox.Indicator

PropTypeDefaultDescription
classNamestringAdditional classes for the hidden input.

Checkbox.Label

PropTypeDefaultDescription
childrenReactNodeLabel content.
classNamestringAdditional classes for the label.

Checkbox.Description

PropTypeDefaultDescription
childrenReactNodeDescription content.
classNamestringAdditional classes for the description.

Checkbox.Error

PropTypeDefaultDescription
childrenReactNodeError message content.
classNamestringAdditional classes for the error message.

On this page