{
  "title": "Switch",
  "description": "A control that allows the user to toggle between checked and not checked with jelly squash-and-stretch active physics and bouncy spring animations.",
  "name": "motion-switch",
  "dependencies": [
    "motion",
    "@base-ui/react"
  ],
  "registryDependencies": [],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/motion/switch.tsx",
      "type": "registry:ui",
      "content": "import * as React from \"react\";\n\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\";\nimport { type Transition, motion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface SwitchProps extends SwitchPrimitive.Root.Props {\n    size?: \"sm\" | \"default\";\n    transition?: Transition;\n}\n\nfunction Switch({\n    className,\n    size = \"default\",\n    transition = { type: \"spring\", stiffness: 500, damping: 22, mass: 0.8 },\n    disabled,\n    ...props\n}: SwitchProps) {\n    const [isPressed, setIsPressed] = React.useState(false);\n\n    const travelDistance = size === \"sm\" ? 10 : 14;\n\n    return (\n        <SwitchPrimitive.Root\n            data-slot=\"switch\"\n            data-size={size}\n            disabled={disabled}\n            className={cn(\n                \"data-checked:bg-primary data-unchecked:bg-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 dark:data-unchecked:bg-input/80 peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-[3px] aria-invalid:ring-[3px] data-disabled:cursor-not-allowed data-disabled:opacity-50 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px]\",\n                className,\n            )}\n            onPointerDown={(e) => {\n                if (!disabled) setIsPressed(true);\n                props.onPointerDown?.(e);\n            }}\n            onPointerUp={(e) => {\n                setIsPressed(false);\n                props.onPointerUp?.(e);\n            }}\n            onPointerLeave={(e) => {\n                setIsPressed(false);\n                props.onPointerLeave?.(e);\n            }}\n            onKeyDown={(e) => {\n                if (!disabled && (e.key === \" \" || e.key === \"Enter\")) {\n                    setIsPressed(true);\n                }\n                props.onKeyDown?.(e);\n            }}\n            onKeyUp={(e) => {\n                setIsPressed(false);\n                props.onKeyUp?.(e);\n            }}\n            {...props}>\n            <SwitchPrimitive.Thumb\n                data-slot=\"switch-thumb\"\n                className=\"bg-background dark:data-unchecked:bg-foreground dark:data-checked:bg-primary-foreground pointer-events-none block rounded-full ring-0 group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3\"\n                render={(thumbProps, state) => (\n                    <motion.span\n                        {...thumbProps}\n                        initial={false}\n                        animate={{\n                            x: state.checked ? travelDistance : 0,\n                            scaleX: isPressed ? 1.15 : 1,\n                            scaleY: isPressed ? 0.92 : 1,\n                            originX: state.checked ? 0.8 : 0.2,\n                            originY: 0.5,\n                        }}\n                        transition={transition}\n                        className=\"bg-background dark:data-unchecked:bg-foreground dark:data-checked:bg-primary-foreground pointer-events-none block rounded-full ring-0 group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3\"\n                    />\n                )}\n            />\n        </SwitchPrimitive.Root>\n    );\n}\n\nexport { Switch };\n"
    }
  ],
  "mcp": {
    "description": "A control that allows the user to toggle between checked and unchecked states. Provides jelly active squash-and-stretch and spring bounce motion.",
    "tags": [
      "component",
      "switch",
      "paceui",
      "animation",
      "toggle"
    ]
  }
}