{
  "title": "Spring Button",
  "description": "A button that shrinks on press and springs back with bounce.",
  "name": "motion-spring-button",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/motion/spring-button.tsx",
      "type": "registry:ui",
      "content": "import { type HTMLMotionProps, motion, useAnimation } from \"motion/react\";\n\ntype SpringButtonProps = {\n    scale?: number;\n    shaking?: boolean;\n} & HTMLMotionProps<\"button\">;\n\nexport const SpringButton = ({ scale = 0.85, shaking = true, ...props }: SpringButtonProps) => {\n    const controls = useAnimation();\n\n    const handlePress = () => {\n        controls.start({\n            scale: scale,\n            transition: { duration: 1, ease: \"easeOut\" },\n        });\n\n        if (shaking) {\n            controls.start({\n                x: [0, -1, 1, -0.5, 0.5, 0],\n                y: [0, 1, -1, -0.5, 0.5, 0],\n                transition: {\n                    duration: 0.4,\n                    repeat: Infinity,\n                    ease: \"linear\",\n                    times: [0, 0.2, 0.4, 0.6, 0.8, 1],\n                },\n            });\n        }\n    };\n\n    const handleRelease = () => {\n        controls.stop();\n        controls.start({\n            scale: 1,\n            x: 0,\n            y: 0,\n            transition: {\n                type: \"spring\",\n                stiffness: 400,\n                damping: 10,\n                mass: 1,\n            },\n        });\n    };\n\n    return (\n        <motion.button\n            {...props}\n            animate={controls}\n            onPointerDown={(e) => {\n                handlePress();\n                props.onPointerDown?.(e);\n            }}\n            onPointerUp={(e) => {\n                handleRelease();\n                props.onPointerUp?.(e);\n            }}\n            onPointerLeave={(e) => {\n                handleRelease();\n                props.onPointerLeave?.(e);\n            }}\n            onPointerCancel={(e) => {\n                handleRelease();\n                props.onPointerCancel?.(e);\n            }}\n        />\n    );\n};\n"
    }
  ],
  "mcp": {
    "description": "Provides refined UI interactions and accessible controls. A button that shrinks on press and springs back with bounce. Configurable props include: {; scale?: number;; shaking?: boolean;. Relies on motion. Optimal for building reusable interface elements and user input flows.",
    "tags": [
      "component",
      "motion",
      "animation"
    ]
  }
}