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.
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
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"
/>
);
}
States
Checked
<Checkbox value="checked" label="Checked checkbox" />
<Checkbox value="unchecked" label="Unchecked checkbox" />
<Checkbox
value="indeterminate"
label="Indeterminate checkbox"
allowIndeterminate
/>
With Labels
Text Label
<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>
}
/>
Visual States
Focus
<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"
/>
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
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>
);
}
Checkbox with Indeterminate Support
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>
);
}
Validation Example
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>
);
}