> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devreadykit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkbox

> A checkbox component with support for checked, unchecked, and indeterminate states

export const CheckboxValidationExamplePreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxValidationExample" frameBorder="0" width="100%" height="360"></iframe>;

export const CheckboxIndeterminateExamplePreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxIndeterminateExample" frameBorder="0" width="100%" height="360"></iframe>;

export const CheckboxFormExamplePreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxFormExample" frameBorder="0" width="100%" height="360"></iframe>;

export const CheckboxCustomIconsPreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxCustomIcons" frameBorder="0" width="100%" height="280"></iframe>;

export const CheckboxVisualStatesPreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxVisualStates" frameBorder="0" width="100%" height="320"></iframe>;

export const CheckboxLabelsPreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxLabels" frameBorder="0" width="100%" height="300"></iframe>;

export const CheckboxStatesPreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxStates" frameBorder="0" width="100%" height="280"></iframe>;

export const CheckboxBasicExamplePreview = () => <iframe src="https://kerny-custom.vercel.app/preview/CheckboxBasicExample" frameBorder="0" width="100%" height="260"></iframe>;

## Overview

The Checkbox component provides a flexible checkbox input with support for checked, unchecked, and indeterminate states, along with labels and error handling.

## Basic Usage

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    import { Checkbox } from '@peppermint-design/devreadykit-custom';
    import type { CheckboxValue } from "@/ui/checkbox";

    export default function App() {
      const [checked, setChecked] = useState<CheckboxValue>("unchecked");

      return (
        <Checkbox
          value={checked}
          onValueChange={setChecked}
          label="Accept terms and conditions"
        />
      );
    }
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxBasicExamplePreview />
  </Tab>
</Tabs>

## States

### Checked

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    <Checkbox value="checked" label="Checked checkbox" />
    <Checkbox value="unchecked" label="Unchecked checkbox" />
    <Checkbox 
      value="indeterminate" 
      label="Indeterminate checkbox"
      allowIndeterminate
    />
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxStatesPreview />
  </Tab>
</Tabs>

## With Labels

### Text Label

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    <Checkbox value="checked" label="I agree to the terms" />
    <Checkbox value="unchecked" label="Subscribe to newsletter" />

    <Checkbox 
      value="checked" 
      label={
        <span>
          I agree to the <a href="/terms" className="text-blue-500 underline">Terms of Service</a>
        </span>
      } 
    />
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxLabelsPreview />
  </Tab>
</Tabs>

## Visual States

### Focus

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    <Checkbox 
      value="unchecked" 
      label="Focused checkbox"
      visualState="focus"
    />

    <Checkbox 
      value="unchecked" 
      label="Error checkbox"
      visualState="error"
      errorMessage="This field is required"
    />

    <Checkbox 
      value="checked" 
      label="Disabled checked"
      visualState="disabled"
    />
    <Checkbox 
      value="unchecked" 
      label="Disabled unchecked"
      visualState="disabled"
    />
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxVisualStatesPreview />
  </Tab>
</Tabs>

## Props

| Prop               | Type                                                                   | Default         | Description               |
| :----------------- | :--------------------------------------------------------------------- | :-------------- | :------------------------ |
| value              | `"unchecked" \| "checked" \| "indeterminate"`                          | `"unchecked"`   | Checkbox state            |
| onValueChange      | `(value: CheckboxValue, event: ChangeEvent) => void`                   | —               | Change handler            |
| visualState        | `"rest" \| "focus" \| "error" \| "disabled" \| "default" \| "focused"` | `"rest"`        | Visual state              |
| label              | `React.ReactNode`                                                      | —               | Label content             |
| required           | `boolean`                                                              | `false`         | Required field indicator  |
| errorMessage       | `React.ReactNode`                                                      | —               | Error message             |
| checkIcon          | `React.ReactElement<SVGProps>`                                         | `<Checkmark />` | Check icon                |
| indeterminateIcon  | `React.ReactElement<SVGProps>`                                         | Default line    | Indeterminate icon        |
| allowIndeterminate | `boolean`                                                              | `false`         | Allow indeterminate state |
| disabled           | `boolean`                                                              | `false`         | Disabled state            |
| className          | `string`                                                               | —               | Additional CSS classes    |

## Examples

### Form with Multiple Checkboxes

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    function PreferencesForm() {
      const [preferences, setPreferences] = useState({
        newsletter: "unchecked",
        notifications: "checked",
        analytics: "unchecked"
      });

      const handleChange = (key: string) => (value: CheckboxValue) => {
        setPreferences(prev => ({ ...prev, [key]: value }));
      };

      return (
        <form className="space-y-4">
          <div className="space-y-3">
            <h3 className="font-medium">Preferences</h3>
            
            <Checkbox
              value={preferences.newsletter}
              onValueChange={handleChange('newsletter')}
              label="Subscribe to newsletter"
            />
            
            <Checkbox
              value={preferences.notifications}
              onValueChange={handleChange('notifications')}
              label="Enable push notifications"
            />
            
            <Checkbox
              value={preferences.analytics}
              onValueChange={handleChange('analytics')}
              label="Allow analytics tracking"
            />
          </div>
        </form>
      );
    }
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxFormExamplePreview />
  </Tab>
</Tabs>

### Checkbox with Indeterminate Support

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    import { useMemo, useState } from "react";
    import Checkbox, { type CheckboxValue } from "@peppermint-design/devreadykit-custom";

    type Task = { id: number; name: string; completed: CheckboxValue };

    const INITIAL_TASKS: Task[] = [
      { id: 1, name: "Task 1", completed: "checked" },
      { id: 2, name: "Task 2", completed: "unchecked" },
      { id: 3, name: "Task 3", completed: "checked" },
    ];

    export default function CheckboxIndeterminateExample() {
      const [tasks, setTasks] = useState<Task[]>(INITIAL_TASKS);

      const { allCompleted, selectAllValue } = useMemo(() => {
        const allChecked = tasks.every((t) => t.completed === "checked");
        const someChecked = tasks.some((t) => t.completed === "checked");
        const selectAll: CheckboxValue = allChecked
            ? "checked"
            : someChecked
                ? "indeterminate"
                : "unchecked";

        return {
          allCompleted: allChecked,
          selectAllValue: selectAll,
        };
      }, [tasks]);

      const handleSelectAll = (_: CheckboxValue) => {
        const next: CheckboxValue = allCompleted ? "unchecked" : "checked";
        setTasks((prev) => prev.map((task) => ({ ...task, completed: next })));
      };

      const handleTaskChange = (id: number) => (value: CheckboxValue) => {
        setTasks((prev) =>
            prev.map((task) =>
                task.id === id ? { ...task, completed: value } : task
            )
        );
      };

      return (
          <div className="flex items-center flex-col gap-4 w-full">
            <div className="w-full max-w-md space-y-3">
              <Checkbox
                  value={selectAllValue}
                  onValueChange={handleSelectAll}
                  label="Select All"
                  allowIndeterminate
              />

              {tasks.map((task) => (
                  <Checkbox
                      key={task.id}
                      value={task.completed}
                      onValueChange={handleTaskChange(task.id)}
                      label={task.name}
                  />
              ))}
            </div>
          </div>
      );
    }
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxIndeterminateExamplePreview />
  </Tab>
</Tabs>

### Validation Example

<Tabs>
  <Tab title="Code">
    ```tsx theme={null}
    function TermsCheckbox() {
      const [accepted, setAccepted] = useState("unchecked");
      const [error, setError] = useState("");

      const handleSubmit = (e: FormEvent) => {
        e.preventDefault();
        
        if (accepted !== "checked") {
          setError("You must accept the terms to continue");
          return;
        }
        
        setError("");
        // Submit form
      };

      return (
        <form onSubmit={handleSubmit}>
          <Checkbox
            value={accepted}
            onValueChange={(value) => {
              setAccepted(value);
              if (error && value === "checked") {
                setError("");
              }
            }}
            label="I accept the terms and conditions"
            required
            visualState={error ? "error" : "rest"}
            errorMessage={error}
          />
          
          <button type="submit" className="mt-4 px-4 py-2 bg-blue-500 text-white rounded">
            Continue
          </button>
        </form>
      );
    }
    ```
  </Tab>

  <Tab title="Preview">
    <CheckboxValidationExamplePreview />
  </Tab>
</Tabs>
