Skip to content
Primitives

Checkbox

Sharp checkbox that fills with signal when checked.

● LIVE
npx shadcn@latest add https://okibi.cndr.dev/r/checkbox.json

Installation

Install the theme first, then add the component:

npx shadcn@latest add https://okibi.cndr.dev/r/checkbox.json

Install the required dependencies:

npm install @radix-ui/react-checkbox lucide-react

Copy the source from the Code tab above into components/ui/checkbox.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.

Usage

import { Checkbox } from "@/components/ui/checkbox"

<Checkbox id="arm" defaultChecked />

Examples

With description

Pair the box with a Label and a muted helper line for consent rows and settings toggles.

● LIVE

Auto-engage defenses on breach detection.

Disabled

The native disabled attribute blocks interaction in both the checked and unchecked states.

● LIVE

Accessibility

  • Built on Radix Checkbox.Root, so it exposes role='checkbox' and aria-checked (including 'mixed' for the indeterminate state) for free.
  • Drives the check / minus glyph off data-state (checked, unchecked, indeterminate) — Space toggles it natively.
  • aria-invalid='true' flips the box to the destructive keyline (border-destructive, ring-destructive) for error states.
  • Focus shows the 2px signal ring: focus-visible:ring-2 ring-ring with ring-offset-2.
  • Has no built-in text — always associate a Label via htmlFor pointing at the checkbox id so the click target and announcement are correct.
  • Disabled state is disabled:opacity-60 and removes pointer events; the glyph swap is instant (transition-none) per the motion spec.

Guidelines

Do

  • Pair every checkbox with a Label (matching htmlFor / id) so the whole row is clickable.
  • Use the indeterminate state for a parent that summarizes a partially-selected set of children.
  • Wire aria-invalid when a required checkbox (terms, consent) is left unchecked on submit.

Don't

  • Don't use a checkbox for a single mutually-exclusive choice — reach for RadioGroup or Switch.
  • Don't ship a bare checkbox with no associated label; an adjacent span is not an accessible name.
  • Don't add motion to the glyph — the instant swap is intentional HUD behavior.

On this page