---
title: Checkbox
description: A control that lets the user turn an option on or off, or pick several options from a list, with checked, unchecked and indeterminate states.
icon: check
author:
  name: imskyleen
  url: https://github.com/imskyleen
related:
  - /switch
  - /radio-group
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Base UI', url: 'https://base-ui.com/react/components/checkbox' },
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/checkbox' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/checkbox
```

<ComponentPreview name="checkbox-demo" />

## Usage

The Checkbox component provides a visually appealing checkbox with smooth animations and comprehensive accessibility support.

```tsx
import { Checkbox } from "@/components/redpanda-ui/checkbox"

// Basic checkbox
<Checkbox id="terms" />

// Controlled checkbox
const [checked, setChecked] = useState(false)
<Checkbox
  id="newsletter"
  checked={checked}
  onCheckedChange={setChecked}
/>

// With label
<div className="flex items-center space-x-2">
  <Checkbox id="terms" />
  <label htmlFor="terms" className="text-sm font-medium">
    Accept terms and conditions
  </label>
</div>

// Disabled checkbox
<Checkbox id="disabled" disabled />

// With indeterminate state
<Checkbox id="indeterminate" checked="indeterminate" />
```

## When to use

Use this decision tree to determine when to use the Checkbox component:

```mermaid
graph TD;
    A[❓ Need user selection input?] -->|Yes| B[Yes];
    A -->|No| C[⚠️ No - use Button or Link];
    B --> D{Multiple selections allowed?};
    D -->|Yes| E[✅ Yes - use Checkbox];
    D -->|No| F[No - single selection?];
    F -->|Yes| G[⚠️ Yes - use Radio Group];
    F -->|No| H[No - boolean choice?];
    H -->|Yes| I[✅ Yes - use Checkbox or Switch];
    H -->|No| J[⚠️ No - consider Select];
    E --> K{Part of a list?};
    K -->|Yes| L[✅ Yes - use multiple Checkboxes];
    K -->|No| M[✅ No - single Checkbox];
    I --> N{Toggle functionality?};
    N -->|Yes| O[⚠️ Yes - use Switch];
    N -->|No| P[✅ No - use Checkbox];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class E,I,L,M,P recommended;
    class C,G,J,O discouraged;
    class A,D,F,H,K,N decision;
    class B neutral;
```

**Use Checkbox when:**

- Users need to select multiple options from a list
- Confirming agreement (terms, privacy policy)
- Enabling/disabling individual features or settings
- Creating multi-select forms
- Building data tables with row selection
- Collecting binary preferences (yes/no, on/off)

**Don't use Checkbox for:**

- Single choice from multiple options (use Radio Group)
- Immediate toggle actions (use Switch)
- Navigation or triggering actions (use Button)
- Complex multi-step selections (use Multi-Select)

## Anatomy

The Checkbox component is built on Base UI primitives:

```
Checkbox Component Structure:
┌─────────────────────────────────────────────────────┐
│ <CheckboxPrimitive.Root> (Base UI primitive)       │
│ ┌─────────────────────────────────────────────────┐ │
│ │ <button> (Interactive element)                  │ │
│ │                                                 │ │
│ │ Styles Applied:                                 │ │
│ │ • Size (20x20px)                                │ │
│ │ • Border (2px, changes on state)                │ │
│ │ • Background (transparent → filled)             │ │
│ │ • Focus ring (for accessibility)                │ │
│ │                                                 │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ <CheckboxPrimitive.Indicator>               │ │ │
│ │ │ ┌─────────────────────────────────────────┐ │ │ │
│ │ │ │ <svg> (Checkmark icon)                  │ │ │ │
│ │ │ │                                         │ │ │ │
│ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ <path> (CSS-animated path)          │ │ │ │ │
│ │ │ │ │                                     │ │ │ │ │
│ │ │ │ │ Animation States:                   │ │ │ │ │
│ │ │ │ │ • unchecked: dashoffset 1, opacity 0│ │ │ │ │
│ │ │ │ │ • checked: dashoffset 0, opacity 1  │ │ │ │ │
│ │ │ │ │ • Duration: 0.2s with 0.1s delay   │ │ │ │ │
│ │ │ │ └─────────────────────────────────────┘ │ │ │ │
│ │ │ └─────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

State Management:
• Controlled: Uses checked prop with onCheckedChange
• Uncontrolled: Uses defaultChecked prop
• Supports indeterminate state for partial selections

Accessibility Features:
• Keyboard navigation (Space to toggle)
• Focus management with visible focus ring
• Screen reader support via Base UI primitives
• ARIA attributes automatically applied
• Label association through id/htmlFor

Animation System:
• Pure CSS transitions (no JS animation library)
• Checkmark draws in via stroke-dashoffset + opacity
• 500ms color transition for state changes
• Box fill leads the checkmark stroke draw-in slightly
```

## Props

<div className="flex flex-row gap-x-3">
  <ExternalLink href="https://base-ui.com/react/components/checkbox" text="Docs" />
  <ExternalLink href="https://base-ui.com/react/components/checkbox#api-reference" text="API Reference" />
</div>

## Keyboard interactions

| Key                   | Action                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `Tab` to the checkbox | Focus lands on the checkbox.                                                                      |
| `Space`               | Toggles between checked / unchecked. Cycles through indeterminate when `indeterminate` is in use. |
| `Enter`               | Submits the surrounding form — does not toggle the checkbox.                                      |

## Accessibility

- Renders as a real `<button role="checkbox">` with `aria-checked="true" | "false" | "mixed"`. The component also
  sets `data-state="checked" | "unchecked" | "indeterminate"` so existing Tailwind selectors keep working.
- Always pair with a visible `<Label htmlFor>`; if the checkbox is inside a `<Field>` the label wiring is automatic.
- Use `indeterminate` **visually only** (e.g. parent/child tree selection) — the checkbox still flips to `checked` on
  next toggle; don't try to make indeterminate a persistent form value.
- Group related checkboxes inside a `<fieldset>` with a `<legend>` so screen readers announce the group context.

## Examples

### Default

<ComponentPreview name="checkbox-demo" />

### Days of the week (Maintenance window)

<ComponentPreview
  name="checkbox-days-demo"
  description="A checkbox component with the ability to select days of the week."
/>

### Indeterminate

<ComponentPreview
  name="checkbox-indeterminate-demo"
  description="Checkbox in the indeterminate state for partial or mixed selection."
/>

### Parent / select all

<ComponentPreview
  name="checkbox-parent-demo"
  description="Parent checkbox with indeterminate state controlling a set of child checkboxes."
/>

### Nested hierarchy

<ComponentPreview
  name="checkbox-nested-demo"
  description="Nested checkbox hierarchy with parent/child indeterminate propagation."
/>

### Error state

<ComponentPreview name="checkbox-error-demo" description="Checkbox in an error state with aria-invalid styling." />

### Helper text

<ComponentPreview
  name="checkbox-helper-text-demo"
  description="Checkbox with helper text rendered beneath its label."
/>

### Grouped

<ComponentPreview name="checkbox-group-demo" description="Vertically grouped checkboxes with a shared group label." />

### Form

<ComponentPreview name="checkbox-form-demo" description="A checkbox component used in a form." />

## Credits

- We use [Base UI](https://base-ui.com/react/components/checkbox) for the checkbox component.
- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/checkbox) for the checkbox style.
