{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "switch",
  "type": "registry:ui",
  "title": "Switch",
  "description": "On/off toggle for boolean settings, with size variants and accessible labeling.",
  "dependencies": [
    "@radix-ui/react-switch",
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/switch.tsx",
      "type": "registry:ui",
      "content": "// @toreview\n\"use client\"\n\n/**\n * @fileoverview Switch — animated toggle switch with spring physics and size variants.\n * @module packages/ui/components/ui/switch\n * @layer core\n *\n * @component\n * @example\n * import { Switch } from '@saasflare/ui';\n * <Switch checked={enabled} onCheckedChange={setEnabled} />\n * <Switch size=\"sm\" />\n */\n\nimport * as React from \"react\"\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/**\n * Props for {@link Switch}.\n *\n * Extends the Radix Switch root props with {@link SaasflareComponentProps},\n * so `animated` and the other axes can be supplied per-instance or inherited\n * from <SaasflareProvider>.\n */\ninterface SwitchProps\n  extends Omit<React.ComponentProps<typeof SwitchPrimitive.Root>, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {\n  /** Visual size of the toggle. `md` is the standard control; `sm` is a compact variant for dense rows. (`\"default\"` is a deprecated alias for `\"md\"`.) */\n  size?: \"sm\" | \"md\" | \"default\"\n}\n\n/**\n * Toggle switch for boolean settings, with a thumb that slides between\n * states (CSS transform — honors `animated` and reduced motion). Prefer it\n * over Checkbox when the change takes effect immediately rather than on\n * form submit.\n *\n * @component\n * @layer core\n *\n * @example\n * <Switch checked={enabled} onCheckedChange={setEnabled} />\n */\nfunction Switch({\n  className,\n  size = \"md\",\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: SwitchProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  const resolvedSize = size === \"default\" ? \"md\" : size\n\n  return (\n    <SwitchPrimitive.Root\n      {...props}\n      data-slot=\"switch\"\n      data-size={resolvedSize}\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      className={cn(\n        \"peer group/switch inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=md]:h-[1.15rem] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80\",\n        \"transition-colors duration-200\",\n        className\n      )}\n    >\n      {/* CSS transform, not Motion `layout`: layout projection lives in the\n        * domMax feature bundle, but SaasflareShell mounts LazyMotion with\n        * domAnimation — a `layout` prop here is silently inert and the thumb\n        * never moves. translate-x works everywhere; motion.css zeroes the\n        * duration under prefers-reduced-motion. */}\n      <SwitchPrimitive.Thumb\n        data-slot=\"switch-thumb\"\n        className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform duration-200 data-[state=unchecked]:translate-x-0 data-[state=checked]:translate-x-[calc(100%-2px)] group-data-[animated=false]/switch:transition-none group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground\"\n      />\n    </SwitchPrimitive.Root>\n  )\n}\n\nexport { Switch, type SwitchProps }\n",
      "target": "components/ui/switch.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/switch.json"
  }
}
