{ "name": "grip", "type": "registry:ui", "registryDependencies": [], "dependencies": [ "motion" ], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "grip.tsx", "content": "'use client';\n\nimport { AnimatePresence, motion, useAnimation } from 'motion/react';\nimport { useEffect, useState } from 'react';\n\nconst circles = [\n { cx: 19, cy: 5 }, // Top right\n { cx: 12, cy: 5 }, // Top middle\n { cx: 19, cy: 12 }, // Middle right\n { cx: 5, cy: 5 }, // Top left\n { cx: 12, cy: 12 }, // Center\n { cx: 19, cy: 19 }, // Bottom right\n { cx: 5, cy: 12 }, // Middle left\n { cx: 12, cy: 19 }, // Bottom middle\n { cx: 5, cy: 19 }, // Bottom left\n];\n\nconst GripIcon = () => {\n const [isHovered, setIsHovered] = useState(false);\n const controls = useAnimation();\n\n useEffect(() => {\n const animateCircles = async () => {\n if (isHovered) {\n await controls.start((i) => ({\n opacity: 0.3,\n transition: {\n delay: i * 0.1,\n duration: 0.2,\n },\n }));\n await controls.start((i) => ({\n opacity: 1,\n transition: {\n delay: i * 0.1,\n duration: 0.2,\n },\n }));\n }\n };\n\n animateCircles();\n }, [isHovered, controls]);\n\n return (\n setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n \n \n {circles.map((circle, index) => (\n \n ))}\n \n \n \n );\n};\n\nexport { GripIcon };\n", "type": "registry:ui" } ] }