implement
Switch

Switch

A control that toggles between on and off.

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

export default function SwitchDemo() {
	return Div(
		{ class: "flex flex-col gap-4" },
		Div(
			{ class: "flex items-center gap-2" },
			Switch({ id: "airplane" }),
			Label({ for: "airplane", class: "text-sm leading-none font-medium" }, "Airplane mode"),
		),
		Div(
			{ class: "flex items-center gap-2" },
			Switch({ id: "marketing", checked: true }),
			Label({ for: "marketing", class: "text-sm leading-none font-medium" }, "Marketing emails"),
		),
		Div(
			{ class: "flex items-center gap-2" },
			Switch({ id: "disabled-switch", checked: true, disabled: true }),
			Label(
				{
					for: "disabled-switch",
					class:
						"text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
				},
				"Disabled",
			),
		),
	);
}

A switch is a button that turns a setting on and off. Switch renders a Button with role="switch" and keeps aria-checked in sync — you give it a track and a thumb.

import { Switch, SwitchThumb } from "@implementjs/primitives";

Switch(SwitchThumb());

It accepts optional props and children — pass a props object when you need attributes, or pass children directly. See createComponent. Extra props are forwarded onto the underlying Button.

A switch has only two states. For a control that can also be mixed, use Checkbox.

Checked state

checked defaults to false. Pass a boolean to seed it, or a signal to control it from outside (signal() returns a writable unchanged, so the same prop accepts both):

const enabled = signal(false);

Switch({ checked: enabled }, SwitchThumb());

Button({ onClick: () => enabled.set(true) }, "Turn on");

Clicking the switch toggles checked. Space and Enter do the same, because it is a real Button.

Thumb

SwitchThumb is the knob that slides. Put it inside the switch and style it against data-state, which is "checked" or "unchecked" on both parts:

Switch(
	{
		class: "inline-flex h-5 w-8 items-center rounded-full bg-input data-[state=checked]:bg-primary",
	},
	SwitchThumb({
		class:
			"block size-4 rounded-full bg-background transition-transform data-[state=checked]:translate-x-3.5",
	}),
);

Labels

Pair it with a Label whose for matches the switch id. Clicking the text then toggles the control:

import { Label } from "@implementjs/core";

Div(
	{ class: "flex items-center gap-2" },
	Switch({ id: "airplane" }, SwitchThumb()),
	Label({ for: "airplane" }, "Airplane mode"),
);

Forms

Pass name and the switch renders a visually hidden checkbox that submits with the form. The value is "on" while checked; pass value to change it. required and disabled apply to that input too:

Form(
	{ method: "post" },
	Switch({ name: "newsletter", value: "yes" }, SwitchThumb()),
	Button({ type: "submit" }, "Save"),
);

Without name, no hidden input is rendered.

API Reference

Switch

A toggle that is on or off. Sets role="switch" and aria-checked. Give it a track and a thumb; it handles the state. 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.
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-switch-root]Present
[data-state]"checked" | "unchecked"

SwitchThumb

The knob. Put it inside the switch and slide it with data-state. Renders a Span; extra props are forwarded onto it.

Data attributeValue
[data-switch-thumb]Present
[data-state]"checked" | "unchecked"