Switch

An accessible switch with distinct variants, smooth motion, grouped rows, selectable cards, and fully controlled state.

Loading preview

Examples

Practical examples and common states for the same installable component.

Minimal

Clean pill switch for common settings.

examples/switch-minimal.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchMinimal() {
return (
<Switch
defaultChecked
label="Reduce motion"
description="Use shorter transitions across the interface."
/>
);
}

Elevated

Extra depth on the knob for heavier settings panels.

examples/switch-elevated.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchElevated() {
return (
<Switch
variant="elevated"
defaultChecked
label="Background refresh"
description="Keep content updated while the app is inactive."
/>
);
}

Segmented

On/off labels inside the control for explicit mode switching.

examples/switch-segmented.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchSegmented() {
return (
<Switch
variant="segmented"
defaultChecked
label="Availability"
description="Make your status visible to teammates."
/>
);
}

Power

Icon-first switch for security and critical toggles.

examples/switch-power.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchPower() {
return (
<Switch
variant="power"
defaultChecked
label="Two-factor authentication"
description="Require a verification code when signing in."
/>
);
}

Group

Group related switch controls with shared context.

examples/switch-group.tsx
"use client";
import * as React from "react";
import { Switch, SwitchGroup } from "@/components/wensity/switch";
export function SwitchGroupDemo() {
const [values, setValues] = React.useState({
email: true,
push: true,
sms: false,
});
return (
<SwitchGroup label="Delivery methods">
<Switch
label="Email"
checked={values.email}
onCheckedChange={(checked) =>
setValues((current) => ({ ...current, email: checked }))
}
/>
<Switch
variant="elevated"
label="Push"
checked={values.push}
onCheckedChange={(checked) =>
setValues((current) => ({ ...current, push: checked }))
}
/>
<Switch
variant="segmented"
label="SMS"
checked={values.sms}
onCheckedChange={(checked) =>
setValues((current) => ({ ...current, sms: checked }))
}
/>
</SwitchGroup>
);
}

Error

Validation state for required switches.

examples/switch-error.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchError() {
return (
<Switch
defaultChecked
label="Share workspace publicly"
description="Requires a verified organization profile."
error="Verify your organization before enabling public access."
/>
);
}

Disabled

Disabled switch states stay readable while blocking interaction.

examples/switch-disabled.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchDisabled() {
return (
<div className="space-y-4">
<Switch disabled label="Enterprise SSO" />
<Switch disabled defaultChecked variant="power" label="Audit logging" />
</div>
);
}

Light & dark

Theme-token styling that adapts cleanly to both appearances.

examples/switch-mode.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchThemes() {
return (
<div className="grid gap-4 sm:grid-cols-2">
<div className="rounded-xl border bg-neutral-50 p-4">
<Switch label="Dark mode" defaultChecked />
</div>
<div className="rounded-xl border bg-neutral-950 p-4">
<Switch label="Dark mode" defaultChecked />
</div>
</div>
);
}

Props

PropTypeDefaultDescription
checkedboolean-Controlled on/off state.
defaultCheckedbooleanfalseInitial state when the switch is uncontrolled.
onCheckedChange(checked: boolean, eventDetails?: unknown) => void-Called when the switch is toggled.
labelReact.ReactNode-Label beside the control, wired to it so the text is clickable.
descriptionReact.ReactNode-Secondary copy under the label.
errorReact.ReactNode-Error message under the control, with invalid styling applied.
switchSize"sm" | "md" | "lg""md"Track and thumb size, plus label text size.
variant"minimal" | "elevated" | "segmented" | "power""minimal"Track treatment. power renders the icon-style toggle.
labelPosition"left" | "right""right"Which side of the control the label sits on.
fullWidthbooleantrueStretches the row to fill its container, pushing the control to the far edge.
containerClassNamestring-Classes for the row wrapper around control and label.
controlClassNamestring-Classes for the switch track itself.