{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"motion-toggle","type":"registry:component","title":"Toggle (Motion)","description":"Toggle with motion: it presses in, its background pops in from the middle and its icon bounces as it turns on.","dependencies":["motion","radix-ui"],"registryDependencies":["https://dashral.com/r/utils.json","https://dashral.com/r/motion-reduced.json","https://dashral.com/r/motion-tokens.json","https://dashral.com/r/toggle.json"],"files":[{"path":"registry/dashral/motion/toggle.tsx","type":"registry:file","target":"components/dashral/motion/toggle.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport { AnimatePresence, motion } from \"motion/react\"\nimport { toggleOnFill, toggleVariants, type ToggleProps } from \"../toggle\"\nimport { cn } from \"../lib/utils\"\n\nimport { useReducedMotion } from \"../lib/motion-reduced\"\nimport { duration, ease, spring } from \"../lib/motion-tokens\"\n\nexport type { ToggleProps } from \"../toggle\"\n\n/**\n * The kit's Toggle with motion: the same variants, sizes and props. It presses in on a spring; turned on, its\n * background pops in from the middle and what's inside gives a small bounce; turned off, the background shrinks away.\n * With reduced motion the background only fades.\n */\nexport function Toggle({ variant, size, color = \"primary\", className, pressed: pressedProp, defaultPressed, onPressedChange, children, ...props }: ToggleProps) {\n  const reduced = useReducedMotion()\n  const [own, setOwn] = React.useState(defaultPressed ?? false)\n  const pressed = pressedProp ?? own\n  const [flips, setFlips] = React.useState(0)\n\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      pressed={pressed}\n      onPressedChange={(next) => {\n        if (pressedProp === undefined) setOwn(next)\n        setFlips((n) => n + 1)\n        onPressedChange?.(next)\n      }}\n      asChild\n      {...props}\n    >\n      <motion.button\n        whileTap={reduced || props.disabled ? undefined : { scale: 0.9 }}\n        transition={spring.press}\n        // The background is the motion layer's; CSS keeps the colors.\n        className={toggleVariants({ variant, size, color, className: cn(\"relative isolate data-[state=on]:bg-transparent data-[state=on]:hover:bg-transparent\", className) })}\n      >\n        <AnimatePresence initial={false}>\n          {pressed && color !== \"none\" && (\n            <motion.span\n              key=\"on\"\n              aria-hidden\n              className={cn(\"absolute inset-0 -z-10 rounded-[inherit]\", toggleOnFill[color])}\n              initial={reduced ? { opacity: 0 } : { opacity: 0, scale: 0.6 }}\n              animate={{ opacity: 1, scale: 1 }}\n              exit={reduced ? { opacity: 0 } : { opacity: 0, scale: 0.6, transition: { duration: duration.fast, ease: ease.exit } }}\n              transition={reduced ? { duration: duration.fast } : { ...spring.pop, opacity: { duration: duration.fast } }}\n            />\n          )}\n        </AnimatePresence>\n        <motion.span\n          key={flips}\n          className=\"inline-flex items-center gap-[inherit]\"\n          initial={false}\n          animate={flips && !reduced ? { scale: [1, pressed ? 1.18 : 0.88, 1] } : undefined}\n          transition={{ duration: duration.standard, ease: ease.standard }}\n        >\n          {children}\n        </motion.span>\n      </motion.button>\n    </TogglePrimitive.Root>\n  )\n}\n"}]}