Forms
Switch
On/off toggle whose thumb springs across and stretches while pressed.
When three or more channels point at the same problem.
Prepare the change for review. Nothing runs without approval.
Tag Khaleeji, Najdi and Hijazi so replies match register.
pnpm dlx shadcn@latest add @paragon/switchBrings in@base-ui/reactcn
States
The thumb springs across, and stretches while you hold it. Try pressing and holding.
| Rest | Hover | Focus | Pressed | Invalid | Disabled | |
|---|---|---|---|---|---|---|
| off | ||||||
| on |
Sizes
registry/paragon/ui/switch.tsx
"use client"
import { Switch as SwitchPrimitive } from "@base-ui/react/switch"
import { cn } from "cn"
/**
* The thumb springs across and stretches while pressed. Geometry lives in
* custom properties (--track, --thumb, --thumb-w) so both sizes, both
* directions and the press stretch share one calculation.
*/
function Switch({
className,
size = "default",
...props
}: SwitchPrimitive.Root.Props & {
size?: "sm" | "default"
}) {
return (
<SwitchPrimitive.Root
data-slot="switch"
data-size={size}
className={cn(
"peer group/switch relative inline-flex shrink-0 items-center rounded-full p-(--pad) outline-none",
"[--pad:2px] [--thumb:1.125rem] [--track:2.375rem] data-[size=sm]:[--thumb:0.875rem] data-[size=sm]:[--track:1.875rem]",
"[--thumb-w:var(--thumb)] active:[--thumb-w:calc(var(--thumb)+0.3125rem)] motion-reduce:active:[--thumb-w:var(--thumb)]",
"h-[calc(var(--thumb)+var(--pad)*2)] w-(--track)",
"bg-input transition-colors duration-(--duration-base) ease-paragon hover:bg-foreground/30",
"data-checked:bg-primary data-checked:hover:bg-[color-mix(in_oklab,var(--primary),var(--background)_16%)]",
"after:absolute after:-inset-x-2 after:-inset-y-2.5",
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid",
"aria-invalid:ring-2 aria-invalid:ring-destructive/60",
"data-disabled:pointer-events-none data-disabled:opacity-50",
"group-has-[:focus-visible]/field-label:outline-none",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"pointer-events-none block h-(--thumb) w-(--thumb-w) rounded-full bg-card shadow-[0_1px_2px_rgb(0_0_0/0.2),0_0_0_0.5px_rgb(0_0_0/0.04)]",
"[transition:translate_var(--duration-slow)_var(--ease-spring),width_var(--duration-base)_var(--ease-paragon),background-color_var(--duration-base)_var(--ease-paragon)]",
"data-checked:translate-x-[calc(var(--track)-var(--thumb-w)-var(--pad)*2)] rtl:data-checked:-translate-x-[calc(var(--track)-var(--thumb-w)-var(--pad)*2)]",
"motion-reduce:transition-none",
"dark:bg-foreground dark:data-checked:bg-primary-foreground"
)}
/>
</SwitchPrimitive.Root>
)
}
export { Switch }