{
  "name": "magnetic-basic",
  "type": "registry:ui",
  "componentName": "magnetic-basic",
  "description": "Basic implementation of the magnetic attraction effect.",
  "files": [
    {
      "path": "magnetic-basic.tsx",
      "content": "import { Magnetic } from '@/components/core/magnetic';\n\nexport function MagneticBasic() {\n  return (\n    <Magnetic>\n      <button\n        type='button'\n        className='inline-flex items-center rounded-md border border-zinc-100 bg-transparent px-4 py-2 text-sm text-zinc-950 transition-all duration-300 hover:bg-zinc-100 dark:border-zinc-900 dark:bg-transparent dark:text-zinc-50 dark:hover:bg-zinc-600'\n      >\n        <span>Submit</span>\n      </button>\n    </Magnetic>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/magnetic.tsx",
      "content": "'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport {\n  motion,\n  useMotionValue,\n  useSpring,\n  type SpringOptions,\n} from 'motion/react';\n\nconst SPRING_CONFIG = { stiffness: 26.7, damping: 4.1, mass: 0.2 };\n\nexport type MagneticProps = {\n  children: React.ReactNode;\n  intensity?: number;\n  range?: number;\n  actionArea?: 'self' | 'parent' | 'global';\n  springOptions?: SpringOptions;\n};\n\nexport function Magnetic({\n  children,\n  intensity = 0.6,\n  range = 100,\n  actionArea = 'self',\n  springOptions = SPRING_CONFIG,\n}: MagneticProps) {\n  const [isHovered, setIsHovered] = useState(false);\n  const ref = useRef<HTMLDivElement>(null);\n\n  const x = useMotionValue(0);\n  const y = useMotionValue(0);\n\n  const springX = useSpring(x, springOptions);\n  const springY = useSpring(y, springOptions);\n\n  useEffect(() => {\n    const calculateDistance = (e: MouseEvent) => {\n      if (ref.current) {\n        const rect = ref.current.getBoundingClientRect();\n        const centerX = rect.left + rect.width / 2;\n        const centerY = rect.top + rect.height / 2;\n        const distanceX = e.clientX - centerX;\n        const distanceY = e.clientY - centerY;\n\n        const absoluteDistance = Math.sqrt(distanceX ** 2 + distanceY ** 2);\n\n        if (isHovered && absoluteDistance <= range) {\n          const scale = 1 - absoluteDistance / range;\n          x.set(distanceX * intensity * scale);\n          y.set(distanceY * intensity * scale);\n        } else {\n          x.set(0);\n          y.set(0);\n        }\n      }\n    };\n\n    document.addEventListener('mousemove', calculateDistance);\n\n    return () => {\n      document.removeEventListener('mousemove', calculateDistance);\n    };\n  }, [isHovered, intensity, range, x, y]);\n\n  useEffect(() => {\n    if (actionArea === 'parent' && ref.current?.parentElement) {\n      const parent = ref.current.parentElement;\n\n      const handleParentEnter = () => setIsHovered(true);\n      const handleParentLeave = () => setIsHovered(false);\n\n      parent.addEventListener('mouseenter', handleParentEnter);\n      parent.addEventListener('mouseleave', handleParentLeave);\n\n      return () => {\n        parent.removeEventListener('mouseenter', handleParentEnter);\n        parent.removeEventListener('mouseleave', handleParentLeave);\n      };\n    } else if (actionArea === 'global') {\n      setIsHovered(true);\n    }\n  }, [actionArea]);\n\n  const handleMouseEnter = () => {\n    if (actionArea === 'self') {\n      setIsHovered(true);\n    }\n  };\n\n  const handleMouseLeave = () => {\n    if (actionArea === 'self') {\n      setIsHovered(false);\n      x.set(0);\n      y.set(0);\n    }\n  };\n\n  return (\n    <motion.div\n      ref={ref}\n      onMouseEnter={actionArea === 'self' ? handleMouseEnter : undefined}\n      onMouseLeave={actionArea === 'self' ? handleMouseLeave : undefined}\n      style={{\n        x: springX,\n        y: springY,\n      }}\n    >\n      {children}\n    </motion.div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}