{
  "name": "cursor-2",
  "type": "registry:ui",
  "componentName": "cursor-2",
  "description": "Advanced cursor effect with interactive elements.",
  "files": [
    {
      "path": "cursor-2.tsx",
      "content": "import { SVGProps } from 'react';\nimport { Cursor } from '@/components/core/cursor';\n\nconst MouseIcon = (props: SVGProps<SVGSVGElement>) => {\n  return (\n    <svg\n      xmlns='http://www.w3.org/2000/svg'\n      width={26}\n      height={31}\n      fill='none'\n      {...props}\n    >\n      <g clipPath='url(#a)'>\n        <path\n          fill={'#22c55e'}\n          fillRule='evenodd'\n          stroke={'#fff'}\n          strokeLinecap='square'\n          strokeWidth={2}\n          d='M21.993 14.425 2.549 2.935l4.444 23.108 4.653-10.002z'\n          clipRule='evenodd'\n        />\n      </g>\n      <defs>\n        <clipPath id='a'>\n          <path fill={'#22c55e'} d='M0 0h26v31H0z' />\n        </clipPath>\n      </defs>\n    </svg>\n  );\n};\n\nexport function Cursor2() {\n  return (\n    <div className='py-12'>\n      <div className='overflow-hidden rounded-[12px] bg-white p-2 shadow-md dark:bg-black'>\n        <Cursor\n          attachToParent\n          variants={{\n            initial: { scale: 0.3, opacity: 0 },\n            animate: { scale: 1, opacity: 1 },\n            exit: { scale: 0.3, opacity: 0 },\n          }}\n          transition={{\n            ease: 'easeInOut',\n            duration: 0.15,\n          }}\n          className='left-12 top-4'\n        >\n          <div>\n            <MouseIcon className='h-6 w-6' />\n            <div className='ml-4 mt-1 rounded-[4px] bg-green-500 px-2 py-0.5 text-neutral-50'>\n              The city below\n            </div>\n          </div>\n        </Cursor>\n        <img\n          src='https://i.pinimg.com/564x/a0/6a/5f/a06a5f814569fcf4a67f3ad89ae1babf.jpg'\n          alt='Green herbs'\n          className='h-40 w-full max-w-32 rounded-[8px] object-cover'\n        />\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/cursor.tsx",
      "content": "'use client';\nimport React, { useEffect, useState, useRef } from 'react';\nimport {\n  motion,\n  SpringOptions,\n  useMotionValue,\n  useSpring,\n  AnimatePresence,\n  Transition,\n  Variant,\n} from 'motion/react';\nimport { cn } from '@/lib/utils';\n\nexport type CursorProps = {\n  children: React.ReactNode;\n  className?: string;\n  springConfig?: SpringOptions;\n  attachToParent?: boolean;\n  transition?: Transition;\n  variants?: {\n    initial: Variant;\n    animate: Variant;\n    exit: Variant;\n  };\n  onPositionChange?: (x: number, y: number) => void;\n};\n\nexport function Cursor({\n  children,\n  className,\n  springConfig,\n  attachToParent,\n  variants,\n  transition,\n  onPositionChange,\n}: CursorProps) {\n  const cursorX = useMotionValue(0);\n  const cursorY = useMotionValue(0);\n  const cursorRef = useRef<HTMLDivElement>(null);\n  const [isVisible, setIsVisible] = useState(!attachToParent);\n\n  useEffect(() => {\n    if (typeof window !== 'undefined') {\n      cursorX.set(window.innerWidth / 2);\n      cursorY.set(window.innerHeight / 2);\n    }\n  }, [cursorX, cursorY]);\n\n  useEffect(() => {\n    if (!attachToParent) {\n      document.body.style.cursor = 'none';\n    } else {\n      document.body.style.cursor = 'auto';\n    }\n\n    const updatePosition = (e: MouseEvent) => {\n      cursorX.set(e.clientX);\n      cursorY.set(e.clientY);\n      onPositionChange?.(e.clientX, e.clientY);\n    };\n\n    document.addEventListener('mousemove', updatePosition);\n\n    return () => {\n      document.removeEventListener('mousemove', updatePosition);\n      document.body.style.cursor = 'auto';\n    };\n  }, [attachToParent, cursorX, cursorY, onPositionChange]);\n\n  const cursorXSpring = useSpring(cursorX, springConfig || { duration: 0 });\n  const cursorYSpring = useSpring(cursorY, springConfig || { duration: 0 });\n\n  useEffect(() => {\n    const handleVisibilityChange = (visible: boolean) => {\n      setIsVisible(visible);\n    };\n\n    const parent = cursorRef.current?.parentElement;\n\n    if (attachToParent && parent) {\n      const handleMouseEnter = () => {\n        parent.style.cursor = 'none';\n        handleVisibilityChange(true);\n      };\n      const handleMouseLeave = () => {\n        parent.style.cursor = 'auto';\n        handleVisibilityChange(false);\n      };\n\n      parent.addEventListener('mouseenter', handleMouseEnter);\n      parent.addEventListener('mouseleave', handleMouseLeave);\n\n      return () => {\n        parent.removeEventListener('mouseenter', handleMouseEnter);\n        parent.removeEventListener('mouseleave', handleMouseLeave);\n        parent.style.cursor = 'auto';\n      };\n    }\n\n    return undefined;\n  }, [attachToParent]);\n\n  return (\n    <motion.div\n      ref={cursorRef}\n      className={cn('pointer-events-none fixed top-0 left-0 z-50', className)}\n      style={{\n        x: cursorXSpring,\n        y: cursorYSpring,\n        translateX: '-50%',\n        translateY: '-50%',\n      }}\n    >\n      <AnimatePresence>\n        {isVisible && (\n          <motion.div\n            initial='initial'\n            animate='animate'\n            exit='exit'\n            variants={variants}\n            transition={transition}\n          >\n            {children}\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </motion.div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}