Skip to content

Checkbox

SM, under 950B gzipped

A checkbox with a real, clickable, bound label.

Category
Forms & input
Budget
sm, single-purpose control
Runtime deps
None

Preview

Preview language

This is the exact fixture the conformance suite renders in CI. Switch the language to see the component mirror and reformat.

Install

npx shadcn@latest add https://kata-ui-rho.vercel.app/r/checkbox.json

Copies the source into your project. Pulls in 1 primitive: cn.

Source

"use client";

import { useId } from "react";
import { cn } from "../lib/cn";

export interface CheckboxProps {
  checked: boolean | "indeterminate";
  onCheckedChange: (checked: boolean) => void;
  label: string;
  disabled?: boolean;
  className?: string;
}

/** A checkbox with a real, clickable, bound label — not an icon next to text. */
export function Checkbox({ checked, onCheckedChange, label, disabled, className }: CheckboxProps) {
  const id = useId();
  const indeterminate = checked === "indeterminate";

  return (
    <label htmlFor={id} className={cn("flex items-center gap-2 text-sm", className)}>
      <input
        id={id}
        type="checkbox"
        checked={indeterminate ? false : checked}
        ref={(node) => {
          if (node) node.indeterminate = indeterminate;
        }}
        disabled={disabled}
        onChange={(event) => onCheckedChange(event.target.checked)}
        className="size-4 rounded border-neutral-300 text-blue-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 dark:border-neutral-700"
      />
      {label}
    </label>
  );
}

What CI checks

← All components