{ "name": "refresh-icon", "type": "registry:ui", "registryDependencies": [], "dependencies": [ "motion", "lucide-react" ], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "refresh-icon.tsx", "content": "'use client';\n\nimport { motion, useAnimation } from 'motion/react';\nimport { RefreshCcw } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { useEffect, useState } from 'react';\n\ninterface RefreshIconProps {\n className?: string;\n color?: string;\n size?: number;\n isRefreshing?: boolean;\n startOnHover?: boolean;\n animationType?: 'spin' | 'pulse';\n}\n\nexport function RefreshIcon({\n className,\n color = 'currentColor',\n size = 24,\n isRefreshing = false,\n startOnHover = true,\n animationType = 'spin',\n}: RefreshIconProps) {\n const controls = useAnimation();\n const [isHovered, setIsHovered] = useState(false);\n const shouldAnimate = isRefreshing || (startOnHover && isHovered);\n\n useEffect(() => {\n if (shouldAnimate) {\n if (animationType === 'spin') {\n controls.start({\n rotate: 360,\n transition: {\n duration: 1,\n repeat: Infinity,\n repeatType: 'loop',\n ease: 'linear',\n },\n });\n } else if (animationType === 'pulse') {\n controls.start({\n scale: [1, 1.1, 1],\n opacity: [1, 0.7, 1],\n transition: {\n duration: 1.5,\n repeat: Infinity,\n repeatType: 'loop',\n ease: 'easeInOut',\n },\n });\n }\n } else {\n controls.stop();\n if (animationType === 'spin') {\n controls.set({ rotate: 0 });\n } else {\n controls.set({ scale: 1, opacity: 1 });\n }\n }\n }, [shouldAnimate, animationType, controls]);\n\n return (\n setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n \n \n \n \n );\n}\n", "type": "registry:ui" } ] }