Component
Checkbox
An 18px box with 4px corners and a gray edge that fills purple with a white check.
npx -y github:anwarlemu/inkbox-brand-cli#release add checkboxUsage
Use for independent on or off choices that apply when a form is submitted (event subscriptions, consent). Pair each checkbox with a Label 8px to its right. Use the indeterminate state for a parent that covers some of its children. For a setting that applies at once use Switch.
Avoid
- A pink checked box
- A round checkbox
- A checkbox that acts immediately like a switch
Exports: Checkbox. This component is a client component.
Dependencies: radix-ui, @phosphor-icons/react.
Example
"use client";import * as React from "react";import { Checkbox } from "@/components/ui/checkbox";import { Label } from "@/components/ui/label";const EVENTS = ["message.received", "message.sent", "message.delivered"];export function Preview() { const [chosen, setChosen] = React.useState<string[]>(["message.received"]); const all = chosen.length === EVENTS.length ? true : chosen.length ? "indeterminate" : false; return ( <div className="grid gap-2.5"> <div className="flex items-center gap-2"> <Checkbox id="all-events" checked={all} onCheckedChange={(v) => setChosen(v === true ? EVENTS : [])} /> <Label htmlFor="all-events" className="font-medium">All email events</Label> </div> <div className="grid gap-2.5 pl-6.5"> {EVENTS.map((e) => ( <div key={e} className="flex items-center gap-2"> <Checkbox id={e} checked={chosen.includes(e)} onCheckedChange={(v) => setChosen((c) => (v === true ? [...c, e] : c.filter((x) => x !== e)))} /> <Label htmlFor={e} className="font-mono">{e}</Label> </div> ))} </div> </div> );}export function States() { return ( <div className="grid gap-2.5"> <div className="flex items-center gap-2"> <Checkbox id="c1" /> <Label htmlFor="c1">Unchecked</Label> </div> <div className="flex items-center gap-2"> <Checkbox id="c2" defaultChecked /> <Label htmlFor="c2">Checked</Label> </div> <div className="flex items-center gap-2"> <Checkbox id="c3" checked="indeterminate" /> <Label htmlFor="c3">Some of them</Label> </div> <div className="flex items-center gap-2"> <Checkbox id="c4" disabled /> <Label htmlFor="c4">Disabled</Label> </div> <div className="flex items-center gap-2"> <Checkbox id="c5" aria-invalid /> <Label htmlFor="c5">I accept the Terms of Service (required)</Label> </div> </div> );}Source
"use client";import * as React from "react";import { Checkbox as CheckboxPrimitive } from "radix-ui";import { CheckIcon, MinusIcon } from "@phosphor-icons/react/ssr";import { cn } from "@/lib/utils";// Extrapolated from the console's radios and checks (Figma 427:2715): an 18px box with 4px corners and the radio's// 1.5px gray edge on white; checked or mixed it fills with the action purple and shows a bold white check (or dash).// Its label sits 8px away in 14px ink.function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) { return ( <CheckboxPrimitive.Root data-slot="checkbox" className={cn( "peer inline-flex size-4.5 shrink-0 cursor-pointer items-center justify-center rounded-xs border-[1.5px] border-line-strong bg-surface text-on-primary outline-none transition-[background-color,border-color] duration-150 ease-out hover:border-fg-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-danger data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary motion-reduce:transition-none", className, )} {...props} > <CheckboxPrimitive.Indicator data-slot="checkbox-indicator" className="group/indicator flex items-center justify-center text-current"> <CheckIcon weight="bold" className="size-3.5 group-data-[state=indeterminate]/indicator:hidden" /> <MinusIcon weight="bold" className="hidden size-3.5 group-data-[state=indeterminate]/indicator:block" /> </CheckboxPrimitive.Indicator> </CheckboxPrimitive.Root> );}export { Checkbox };Reference: Extrapolated from the Inkbox console (Figma 427:2715): the radios' 18px size and gray edge, the action purple and the white checks.