{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "native-magnetic-carbon", "type": "registry:component", "title": "Native Magnetic", "description": "Magnetic wrapper that applies a cursor-following effect to any content.", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-carbon/src/components/native/native-magnetic-carbon.tsx", "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n motion,\n Transition,\n useMotionValue,\n useSpring,\n useTransform,\n} from \"framer-motion\";\nimport { useRef, useState } from \"react\";\n\nexport interface NativeMagneticProps {\n /**\n * Content to apply the magnetic effect to.\n */\n children: React.ReactNode;\n /**\n * Strength of the magnetic pull (0-1 range recommended).\n * Default: 0.3\n */\n strength?: number;\n /**\n * Spring stiffness for the animation.\n * Default: 300\n */\n stiffness?: number;\n /**\n * Spring damping for the animation.\n * Default: 30\n */\n damping?: number;\n /**\n * Whether to scale up on hover.\n * Default: true\n */\n scaleOnHover?: boolean;\n /**\n * Wrapper element type.\n * Default: 'div'\n */\n as?: \"div\" | \"button\" | \"a\";\n /**\n * Link href (only applies when as=\"a\").\n */\n href?: string;\n /**\n * Click handler.\n */\n onClick?: () => void;\n className?: string;\n}\n\nconst springTransition: Transition = {\n type: \"spring\",\n stiffness: 400,\n damping: 25,\n};\n\nexport function NativeMagnetic({\n children,\n strength = 0.3,\n stiffness = 300,\n damping = 30,\n scaleOnHover = true,\n as = \"div\",\n href,\n onClick,\n className,\n}: NativeMagneticProps) {\n const ref = useRef(null);\n const [, setIsHovered] = useState(false);\n\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springConfig = { stiffness, damping };\n const springX = useSpring(x, springConfig);\n const springY = useSpring(y, springConfig);\n\n const translateX = useTransform(springX, (v) => v * strength);\n const translateY = useTransform(springY, (v) => v * strength);\n\n const handleMouseMove = (e: React.MouseEvent) => {\n if (!ref.current) return;\n\n const rect = ref.current.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n x.set(e.clientX - centerX);\n y.set(e.clientY - centerY);\n };\n\n const handleMouseLeave = () => {\n x.set(0);\n y.set(0);\n setIsHovered(false);\n };\n\n const commonProps = {\n onMouseMove: handleMouseMove,\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: handleMouseLeave,\n style: {\n x: translateX,\n y: translateY,\n },\n whileHover: scaleOnHover ? { scale: 1.05 } : undefined,\n whileTap: { scale: 0.95 },\n transition: springTransition,\n className: cn(\"inline-block cursor-pointer\", className),\n onClick,\n };\n\n if (as === \"a\" && href) {\n return (\n }\n href={href}\n {...commonProps}\n >\n {children}\n \n );\n }\n\n if (as === \"button\") {\n return (\n }\n type=\"button\"\n {...commonProps}\n >\n {children}\n \n );\n }\n\n return (\n } {...commonProps}>\n {children}\n \n );\n}\n", "type": "registry:component", "target": "components/uitripled/native-magnetic-carbon.tsx" } ] }