vaiperui

components / checkbox

Checkbox

Accessible checkbox with label, helper and error text, an indeterminate state and colors.

How to use

A native `<input type="checkbox">` (so forms, `ref` and keyboard just work) with a custom look. Pass `label` to make the whole row clickable, and `indeterminate` for a parent that has only some children checked.

preview
Checkbox.tsx
import { Checkbox } from "vaiperui";
<Checkbox label="Accept the terms" />
<Checkbox
defaultChecked
label="Newsletter"
helperText="One email per week"
/>
<Checkbox indeterminate label="Select all" />

Colors

preview
primary
success
warning
danger
colors.tsx
<Checkbox defaultChecked variantColor="primary" label="primary" />
<Checkbox defaultChecked variantColor="success" label="success" />
<Checkbox defaultChecked variantColor="warning" label="warning" />
<Checkbox defaultChecked variantColor="danger" label="danger" />

Sizes

preview
sm
md
lg
sizes.tsx
<Checkbox defaultChecked size="sm" label="sm" />
<Checkbox defaultChecked size="md" label="md" />
<Checkbox defaultChecked size="lg" label="lg" />

Indeterminate

`indeterminate` shows a dash, for a parent checkbox with only some children checked.

preview
indeterminate
indeterminate.tsx
<Checkbox indeterminate label="Select all" />

States

preview
helper
This is required
error
disabled
disabled ✓
states.tsx
<Checkbox label="helper" helperText="..." />
<Checkbox label="error" errorMessage="..." />
<Checkbox label="disabled" disabled />
<Checkbox label="disabled" disabled defaultChecked />

Custom color

`customColor` takes any CSS color, or a `{ light, dark }` pair.

preview
Orange
Violet
custom-color.tsx
<Checkbox defaultChecked customColor="#ff6600" label="Orange" />
<Checkbox defaultChecked customColor={{ light: "#7c3aed", dark: "#a78bfa" }} label="Violet" />

Props

PropValuesDefaultDescription
variantColorprimary | success | warning | dangerprimaryColor of the checked state and focus ring
customColorstring | { light, dark }noneAny CSS color (or a pair per theme). Overrides variantColor
sizesm | md | lgmdSize of the control and its text
radiusnone | sm | md | lg | fullsmCorner rounding of the box
animationnone | smooth | fast | bouncesmoothTransition when it toggles
labelReactNodenoneText next to the control; clicking it toggles
helperTextstringnoneSecondary line under the label
errorMessagestringnoneError text; its presence alone forces the error state
indeterminatebooleanfalseShows a dash instead of the check
(native)InputHTMLAttributes<HTMLInputElement>nonechecked, defaultChecked, onChange, name, value, disabled, required, aria-*, className, ref, etc.

Accessibility

  • Renders a native `<input type="checkbox">` (visually hidden, drawn over by the custom box), so role, Space toggle and form behavior are native.
  • The `<label>` wraps the input, so the label text names it and the whole row is clickable.
  • `indeterminate` sets the DOM `indeterminate` property, which assistive tech reads as "mixed".
  • `errorMessage` sets `aria-invalid="true"`; `aria-describedby` points to the error, or to `helperText` when there is no error.
  • The check and dash icons are `aria-hidden`; state is exposed only by the native input.

Keyboard

KeyAction
SpaceToggles the checkbox.

Keep in mind

  • Without `label`, pass `aria-label`; the control has no other name.
  • `indeterminate` is visual state only: clicking still resolves to checked or unchecked, and you decide what that means.