"use client"; import { motion } from "motion/react"; import { type MouseEvent, type ReactNode, useState } from "react"; interface MagneticButtonProps { children: ReactNode; className?: string; href?: string; onClick?: () => void; strength?: number; as?: "a" | "button" | "div" | "span" | "li"; target?: string; rel?: string; download?: boolean | string; type?: "button" | "submit" | "reset"; wrapperClassName?: string; "aria-label"?: string; } export default function MagneticButton({ children, className = "", href, onClick, strength = 0.3, as = "button", target, rel, download, type, wrapperClassName = "", "aria-label": ariaLabel, }: MagneticButtonProps) { const [position, setPosition] = useState({ x: 0, y: 0 }); const handleMouse = (e: MouseEvent) => { const rect = e.currentTarget.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; setPosition({ x: (e.clientX - centerX) * strength, y: (e.clientY - centerY) * strength, }); }; const handleMouseLeave = () => { setPosition({ x: 0, y: 0 }); }; const Tag = as === "a" ? motion.a : as === "button" ? motion.button : as === "div" ? motion.div : as === "span" ? motion.span : motion.li; const linkProps = as === "a" ? { href, target, rel, download } : {}; const buttonProps = as === "button" ? { type } : {}; const motionProps = { animate: { x: position.x, y: position.y, }, transition: { type: "spring" as const, stiffness: 350, damping: 15, mass: 0.5, }, }; if (as === "li") { return ( {children} ); } return (
{children}
); }