Switch
Client leafAn instant on/off toggle for a single setting.
Live preview
Rendered from the installed VEXA source — the same files you receive.
Installation
Adds the component source to your project. Registry dependencies are pulled in automatically.
npx shadcn@latest add https://vexa.valfiguer.com/r/switch.jsonInstalls to components/vexa/switch.tsx
npm dependencies
- @radix-ui/react-switch
Registry dependencies
- @vexa/utils
Other VEXA items this component needs. Install them first — they are resolved automatically by the CLI.
Source
Copy this into its target path, or install it with the command above.
components/vexa/switch.tsx
"use client";
import type * as React from "react";
import * as SwitchPrimitive from "@radix-ui/react-switch";
import { cn } from "@/lib/utils";
/**
* Switch — an instant on/off toggle for a single setting.
*
* Client leaf. Radix supplies `role="switch"`, `aria-checked`, and the keyboard
* model (Space/Enter toggles). Use a Switch for settings that apply immediately;
* prefer a Checkbox inside forms that are submitted. State is conveyed by the
* thumb position, not color alone. Provide an accessible name via `<Label>` or
* `aria-label`. The thumb transition respects reduced-motion.
*/
export function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent",
"transition-colors duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)]",
"outline-none focus-visible:ring-2 focus-visible:ring-vexa-ring focus-visible:ring-offset-2 focus-visible:ring-offset-vexa-background",
"disabled:cursor-not-allowed disabled:opacity-50",
"data-[state=unchecked]:bg-vexa-input data-[state=checked]:bg-vexa-primary",
className,
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"pointer-events-none block size-5 rounded-full bg-vexa-surface-raised shadow-vexa-sm ring-0",
"transition-transform duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)] motion-reduce:transition-none",
"translate-x-0.5 data-[state=checked]:translate-x-[1.375rem]",
)}
/>
</SwitchPrimitive.Root>
);
}
Details
Example
tsx
<div className="flex items-center gap-2"><Switch id="wifi" /><Label htmlFor="wifi">Wi-Fi</Label></div>Accessibility
role=switch with aria-checked; Space/Enter toggles. State is shown by the thumb position, not color alone. The thumb transition respects reduced motion.