{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "magnetic",
  "title": "Magnetic",
  "description": "Magnetic hover: elements lean toward the cursor and spring back.",
  "dependencies": [],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/magnetic.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { gsap, motionScale, useGSAP } from \"@/lib/motion\";\nimport { cn } from \"@/lib/utils\";\n\ntype MagneticProps = React.ComponentProps<\"span\"> & {\n  /** 0–1: how far the child follows the pointer. */\n  strength?: number;\n  /** Extra px around the child where the pull already starts. */\n  reach?: number;\n};\n\n/** Wraps a button or icon so it leans toward the pointer and springs back when released (GSAP, with an elastic release). */\nfunction Magnetic({ className, strength = 0.35, reach = 24, children, ...props }: MagneticProps) {\n  const ref = React.useRef<HTMLSpanElement>(null);\n\n  useGSAP(\n    () => {\n      const el = ref.current;\n      if (!el) return;\n      const area = el.parentElement ?? el;\n      const onMove = (e: PointerEvent) => {\n        const scale = motionScale(el);\n        if (!scale) return;\n        const rect = el.getBoundingClientRect();\n        const dx = e.clientX - (rect.left + rect.width / 2);\n        const dy = e.clientY - (rect.top + rect.height / 2);\n        const inside = Math.abs(dx) < rect.width / 2 + reach && Math.abs(dy) < rect.height / 2 + reach;\n        if (inside) {\n          gsap.to(el, { x: dx * strength * Math.min(scale, 1.5), y: dy * strength * Math.min(scale, 1.5), duration: 0.45, ease: \"cue\", overwrite: \"auto\" });\n        } else if (gsap.getProperty(el, \"x\") !== 0) release();\n      };\n      const release = () => gsap.to(el, { x: 0, y: 0, duration: 0.8, ease: \"elastic.out(1, 0.35)\", overwrite: true });\n      area.addEventListener(\"pointermove\", onMove);\n      area.addEventListener(\"pointerleave\", release);\n      return () => {\n        area.removeEventListener(\"pointermove\", onMove);\n        area.removeEventListener(\"pointerleave\", release);\n      };\n    },\n    { scope: ref, dependencies: [strength, reach] },\n  );\n\n  return (\n    <span ref={ref} data-slot=\"magnetic\" className={cn(\"inline-block will-change-transform\", className)} {...props}>\n      {children}\n    </span>\n  );\n}\n\nexport { Magnetic };\nexport type { MagneticProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/magnetic",
  "categories": [
    "motion"
  ],
  "type": "registry:ui"
}