implement
Checkbox

Checkbox

A box that is on, off, or partly on.

import { Div, Label } from "@implementjs/core";
import { Checkbox } from "@/lib/components/ui/checkbox";

export default function CheckboxDemo() {
	return Div(
		{ class: "flex flex-col gap-4" },
		Div(
			{ class: "flex items-center gap-2" },
			Checkbox({ id: "terms" }),
			Label(
				{ for: "terms", class: "text-sm leading-none font-medium" },
				"Accept terms and conditions",
			),
		),
		Div(
			{ class: "flex items-center gap-2" },
			Checkbox({ id: "emails", checked: true }),
			Label(
				{ for: "emails", class: "text-sm leading-none font-medium" },
				"Send me product updates",
			),
		),
		Div(
			{ class: "flex items-center gap-2" },
			Checkbox({ id: "partial", indeterminate: true }),
			Label(
				{ for: "partial", class: "text-sm leading-none font-medium" },
				"Select all notifications",
			),
		),
		Div(
			{ class: "flex items-center gap-2" },
			Checkbox({ id: "disabled", checked: true, disabled: true }),
			Label(
				{
					for: "disabled",
					class:
						"text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
				},
				"Disabled",
			),
		),
	);
}

Installation

npx jsrepo add @implementjs/ui/checkbox

It installs @implementjs/lucide at the same time.

Usage

Pass nothing and the checkbox renders its own indicator: a check while checked, a dash while indeterminate. Pass children and they replace it.

checked takes a signal for a controlled box, and "indeterminate" for the third state — the parent of a partly-selected list.

import { signal } from "@implementjs/core";
import { Checkbox } from "@/lib/components/ui/checkbox";

const accepted = signal(false);

Checkbox({ id: "terms", checked: accepted });

With a label

The checkbox is a Button, not an input, so a Label points at it by for and id like any other control:

Div(
	{ class: "flex items-center gap-2" },
	Checkbox({ id: "terms" }),
	Label({ for: "terms", class: "text-sm leading-none font-medium" }, "Accept terms"),
);

Invalid state

aria-invalid is styled as well as announced — the border and focus ring turn destructive:

Checkbox({ id: "terms", "aria-invalid": true });

API Reference

Every prop the styling does not consume is forwarded to the Checkbox primitive, so the tables below are the whole surface — the behavior props and the styling ones together.

Checkbox

A toggle that is checked, unchecked, or indeterminate. Sets role="checkbox" and aria-checked. Give it a look and an indicator; it handles the state. Renders a check — or a dash while indeterminate — unless you pass children of your own. Renders a Button; extra props are forwarded onto it.

PropTypeDefaultDescription
checkedSignal<boolean> | booleanfalseThe checked state. Pass a signal to control it from outside; a boolean seeds uncontrolled state.
indeterminateSignal<boolean> | booleanfalsePartial selection. While true, data-state is "indeterminate" and aria-checked is "mixed". A click clears it and checks the box.
namestringIf set, a hidden checkbox is rendered so the value submits with a form.
valuestring"on"The value submitted while checked. Only used when name is set.
requiredbooleanfalseMarks the hidden input as required. Sets aria-required on the button.
Data attributeValue
[data-checkbox-root]Present
[data-state]"checked" | "unchecked" | "indeterminate"