apps/eclipse/content/design-system/components/checkbox.mdx
import { Checkbox, Field, FieldLabel, FieldDescription, FieldError } from "@prisma/eclipse";
Basic Checkbox
import { Checkbox } from "@prisma/eclipse";
export function BasicCheckbox() {
return <Checkbox />;
}
Live Example:
<div className="flex gap-4 my-4"> <Checkbox /> </div>With Label
Use labels to make checkboxes more accessible and user-friendly:
import { Checkbox } from "@prisma/eclipse";
export function CheckboxWithLabel() {
return (
<div className="flex items-center gap-2">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Accept terms and conditions
</label>
</div>
);
}
Live Example:
<div className="flex items-center gap-2 my-4"> <Checkbox id="terms-example" /> <label htmlFor="terms-example" className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" > Accept terms and conditions </label> </div>With Field Component
Use the Field component for proper form structure with labels and descriptions:
import { Checkbox, Field, FieldLabel, FieldDescription } from "@prisma/eclipse";
export function CheckboxWithField() {
return (
<Field orientation="horizontal" className="items-start">
<Checkbox id="marketing" className="mt-0.5" />
<div className="flex flex-col gap-1">
<FieldLabel htmlFor="marketing">Marketing emails</FieldLabel>
<FieldDescription>Receive emails about new products and features.</FieldDescription>
</div>
</Field>
);
}
Live Example:
<div className="max-w-md my-4"> <Field orientation="horizontal" className="items-start"> <Checkbox id="marketing-field" /> <div className="flex flex-col gap-1"> <FieldLabel htmlFor="marketing-field">Marketing emails</FieldLabel> <FieldDescription>Receive emails about new products and features.</FieldDescription> </div> </Field> </div>Controlled Checkbox
Control the checkbox state with React state:
import { Checkbox } from "@prisma/eclipse";
import { useState } from "react";
export function ControlledCheckbox() {
const [checked, setChecked] = useState(false);
return (
<div className="space-y-4">
<div className="flex items-center gap-2">
<Checkbox
id="controlled"
checked={checked}
onCheckedChange={setChecked}
/>
<label htmlFor="controlled" className="text-sm font-medium">
Enable feature
</label>
</div>
<p className="text-sm text-foreground-neutral-weak">
Status: {checked ? "Enabled" : "Disabled"}
</p>
</div>
);
}
Live Example:
<div className="space-y-4 my-4"> <div className="flex items-center gap-2"> <Checkbox id="controlled-example" /> <label htmlFor="controlled-example" className="text-sm font-medium"> Enable feature </label> </div> </div>Disabled State
import { Checkbox } from "@prisma/eclipse";
export function DisabledCheckbox() {
return (
<div className="space-y-4">
<div className="flex items-center gap-2">
<Checkbox id="disabled-unchecked" disabled />
<label
htmlFor="disabled-unchecked"
className="text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Disabled unchecked
</label>
</div>
<div className="flex items-center gap-2">
<Checkbox id="disabled-checked" disabled checked />
<label
htmlFor="disabled-checked"
className="text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Disabled checked
</label>
</div>
</div>
);
}
Live Example:
<div className="space-y-4 my-4"> <div className="flex items-center gap-2"> <Checkbox id="disabled-unchecked-example" disabled /> <label htmlFor="disabled-unchecked-example" className="text-sm font-medium opacity-70 cursor-not-allowed" > Disabled unchecked </label> </div> <div className="flex items-center gap-2"> <Checkbox id="disabled-checked-example" disabled checked /> <label htmlFor="disabled-checked-example" className="text-sm font-medium opacity-70 cursor-not-allowed" > Disabled checked </label> </div> </div>Checkbox Group
Create groups of related checkboxes:
import { Checkbox } from "@prisma/eclipse";
export function CheckboxGroup() {
return (
<div className="space-y-4">
<div className="flex items-center gap-2 mb-2">
<Checkbox id="notifications" defaultChecked />
<label htmlFor="notifications" className="text-sm font-medium">Notifications</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="emails" />
<label htmlFor="emails" className="text-sm font-medium">Email updates</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="sms" />
<label htmlFor="sms" className="text-sm font-medium">SMS alerts</label>
</div>
</div>
);
}
Live Example:
<div className="space-y-4 my-4"> <div className="flex items-center gap-2 mb-2"> <Checkbox id="notifications-example" defaultChecked /> <label htmlFor="notifications-example" className="text-sm font-medium">Notifications</label> </div> <div className="flex items-center gap-2 mb-2"> <Checkbox id="emails-example" /> <label htmlFor="emails-example" className="text-sm font-medium">Email updates</label> </div> <div className="flex items-center gap-2 mb-2"> <Checkbox id="sms-example" /> <label htmlFor="sms-example" className="text-sm font-medium">SMS alerts</label> </div> </div>With Validation
Use with Field components for validation:
import { Checkbox, Field, FieldLabel, FieldDescription, FieldError } from "@prisma/eclipse";
export function CheckboxWithValidation() {
const [accepted, setAccepted] = useState(false);
const [error, setError] = useState("");
const handleSubmit = () => {
if (!accepted) {
setError("You must accept the terms and conditions");
} else {
setError("");
// Continue with submission
}
};
return (
<div className="space-y-4">
<Field orientation="horizontal" className="items-start">
<Checkbox
id="terms-validation"
checked={accepted}
onCheckedChange={setAccepted}
className="mt-0.5"
/>
<div className="flex flex-col gap-1">
<FieldLabel htmlFor="terms-validation">I accept the terms and conditions</FieldLabel>
<FieldDescription>You must accept to continue.</FieldDescription>
{error && <FieldError>{error}</FieldError>}
</div>
</Field>
</div>
);
}
Live Example:
<div className="max-w-md my-4"> <Field orientation="horizontal" className="items-start"> <Checkbox id="terms-validation-example" className="mt-0.5" /> <div className="flex flex-col gap-1"> <FieldLabel htmlFor="terms-validation-example">I accept the terms and conditions</FieldLabel> <FieldDescription>You must accept to continue.</FieldDescription> </div> </Field> </div>In Forms
import { Checkbox, Button } from "@prisma/eclipse";
export function CheckboxForm() {
return (
<form className="space-y-6 max-w-md">
<div className="space-y-4">
<h3 className="text-lg font-semibold">Privacy Settings</h3>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="analytics" defaultChecked />
<label htmlFor="analytics" className="text-sm font-medium">Allow analytics cookies</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="marketing-cookies" />
<label htmlFor="marketing-cookies" className="text-sm font-medium">Allow marketing cookies</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="third-party" />
<label htmlFor="third-party" className="text-sm font-medium">Allow third-party cookies</label>
</div>
</div>
<Button type="submit">Save preferences</Button>
</form>
);
}
Live Example:
<form className="space-y-6 max-w-md my-4"> <div className="space-y-4"> <h3 className="text-lg font-semibold">Privacy Settings</h3><div className="flex items-center gap-2 mb-2">
<Checkbox id="analytics-form" defaultChecked />
<label htmlFor="analytics-form" className="text-sm font-medium">Allow analytics cookies</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="marketing-cookies-form" />
<label htmlFor="marketing-cookies-form" className="text-sm font-medium">Allow marketing cookies</label>
</div>
<div className="flex items-center gap-2 mb-2">
<Checkbox id="third-party-form" />
<label htmlFor="third-party-form" className="text-sm font-medium">Allow third-party cookies</label>
</div>
Checkbox
The Checkbox component extends all Radix UI Checkbox props:
checked - Controlled checked state (boolean | "indeterminate", optional)defaultChecked - Default checked state for uncontrolled usage (boolean, optional)onCheckedChange - Callback when checked state changes (function, optional)disabled - Whether the checkbox is disabled (boolean, default: false)required - Whether the checkbox is required (boolean, default: false)name - Name for form submission (string, optional)value - Value for form submission (string, default: "on")id - HTML id attribute (string, optional)className - Additional CSS classes (string, optional)htmlFor on labels to match checkbox id for clickable labelshtmlFor attributesThe Checkbox component is perfect for:
The Checkbox component follows accessibility best practices:
role="checkbox", aria-checked)The Checkbox component uses design tokens:
border-primarybg-primarytext-primary-foregroundring-ringrounded-smCustomize by passing className:
<Checkbox className="border-2 border-blue-500 data-[state=checked]:bg-blue-500" />
Checkbox works well with:
The Checkbox component works seamlessly with forms:
<form onSubmit={handleSubmit}>
<Checkbox name="terms" value="accepted" required />
<button type="submit">Submit</button>
</form>
When checked, the form data will include: terms=accepted