Switch

A native input-backed switch primitive for settings and product control panels. It includes minimal, elevated, segmented, and power visual variants, label and description copy, error state, disabled state, controlled/uncontrolled state, switch groups, and card-style setting rows.

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>
);
}

Settings

Card switches for admin panels and app settings pages.

examples/switch-settings.tsx
import {
SwitchCard,
SwitchSettingsGroup,
} from "@/components/wensity/switch";
import { IconShieldLock, IconUsers, IconWorld } from "@tabler/icons-react";
export function SwitchSettings() {
return (
<div className="space-y-6">
<SwitchSettingsGroup
title="General"
description="Defaults applied across this workspace."
>
<SwitchCard
leading={<IconWorld stroke={1.75} />}
label="Public workspace profile"
description="Allow anyone with the link to view your workspace overview."
defaultChecked
trailingOn="Public"
trailingOff="Private"
/>
<SwitchCard
leading={<IconUsers stroke={1.75} />}
label="Member invitations"
description="Let admins invite teammates without owner approval."
defaultChecked
trailingOn="Enabled"
trailingOff="Disabled"
/>
</SwitchSettingsGroup>
<SwitchSettingsGroup
title="Security"
description="Policies that affect every member."
>
<SwitchCard
leading={<IconShieldLock stroke={1.75} />}
label="Require two-factor auth"
description="Block sign-in until a verification code is confirmed."
defaultChecked
trailingOn="Required"
trailingOff="Optional"
/>
</SwitchSettingsGroup>
</div>
);
}

Controlled

Controlled switch state for settings that reflect app state.

examples/switch-controlled.tsx
"use client";
import * as React from "react";
import { Switch } from "@/components/wensity/switch";
export function SwitchControlled() {
const [enabled, setEnabled] = React.useState(true);
return (
<Switch
variant="power"
checked={enabled}
onCheckedChange={setEnabled}
label="Personalized recommendations"
description="Use recent activity to improve suggestions."
/>
);
}

Sizes

Small, default, and large sizes for dense or spacious UI.

examples/switch-sizes.tsx
import { Switch } from "@/components/wensity/switch";
export function SwitchSizes() {
return (
<div className="flex items-start gap-4">
<Switch switchSize="sm" label="Small" defaultChecked />
<Switch switchSize="md" variant="elevated" label="Default" defaultChecked />
<Switch switchSize="lg" variant="segmented" label="Large" defaultChecked />
</div>
);
}

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>
);
}