# Checkbox (Caseroom component)

A native checkbox in the Caseroom style. No JavaScript. Black and white, dark mode, shadcn-compatible; React, Astro and plain HTML.

0.34% of the 2,062 sites in The UI Index have a checkbox (7 sites).

## Install

- React: `npx shadcn@latest add https://www.themes.dev/caseroom/r/checkbox.json`
- Astro: `npx shadcn@latest add https://www.themes.dev/caseroom/r/astro/checkbox.json`
- HTML: https://www.themes.dev/caseroom/r/html/checkbox.html (with https://www.themes.dev/caseroom/r/html/caseroom.css)

Page: https://www.themes.dev/caseroom/components/checkbox/ · Rules for agents: https://www.themes.dev/caseroom/AGENT.md

## Code

### checkbox.astro

```astro
---
import type { HTMLAttributes } from 'astro/types';
import { cn } from '@/lib/utils';
import { CHECK_PATH, checkboxClasses, checkboxMark, checkboxWrap } from './checkbox.variants';

type Props = Omit<HTMLAttributes<'input'>, 'type'>;
const { class: className, ...rest } = Astro.props;
---

<span class={cn(checkboxWrap, className)}>
  <input type="checkbox" class={checkboxClasses} {...rest} />
  <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class={checkboxMark}>
    <path d={CHECK_PATH} />
  </svg>
</span>
```

### checkbox.tsx

```tsx
import type { InputHTMLAttributes } from 'react';
import { cn } from '@/lib/utils';
import { CHECK_PATH, checkboxClasses, checkboxMark, checkboxWrap } from './checkbox.variants';

export type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;

/** A native checkbox: works in forms, with the keyboard and without JavaScript. Pair it with a Label. */
export function Checkbox({ className, ...props }: CheckboxProps) {
  return (
    <span className={cn(checkboxWrap, className)}>
      <input type="checkbox" className={checkboxClasses} {...props} />
      <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={checkboxMark}>
        <path d={CHECK_PATH} />
      </svg>
    </span>
  );
}
```

### checkbox.variants.ts

```tsx
export const checkboxWrap = 'relative inline-flex size-4 shrink-0';
export const checkboxClasses =
  'peer size-4 shrink-0 cursor-pointer appearance-none rounded-[4px] border border-input bg-background transition-[color,background-color,border-color,transform] enabled:not-checked:hover:border-foreground enabled:not-checked:hover:bg-accent enabled:active:scale-90 enabled:not-checked:active:bg-pressed checked:border-primary checked:enabled:hover:border-[color-mix(in_oklab,var(--primary)_var(--hover-amount),var(--background))] checked:enabled:hover:bg-[color-mix(in_oklab,var(--primary)_var(--hover-amount),var(--background))] checked:enabled:active:border-[color-mix(in_oklab,var(--primary)_var(--press-amount),var(--press-mix))] checked:enabled:active:bg-[color-mix(in_oklab,var(--primary)_var(--press-amount),var(--press-mix))] checked:bg-primary indeterminate:border-primary indeterminate:bg-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive';
export const checkboxMark =
  'pointer-events-none absolute inset-0 hidden size-4 text-primary-foreground peer-checked:block';
export const CHECK_PATH = 'M3.5 8.5l3 3 6-7';
```
