"use client"; import { cn } from "@/lib/utils"; import { AnimatePresence, HTMLMotionProps, motion, useMotionValue, } from "motion/react"; import { useEffect, useRef, useState } from "react"; interface PointerProps extends Omit, "ref"> { children?: React.ReactNode; } /** * A custom pointer component that displays an animated cursor. * Add this as a child to any component to enable a custom pointer when hovering. * You can pass custom children to render as the pointer. * * @component * @param {PointerProps} props - The component props */ export function Pointer({ className, style, children, ...props }: PointerProps): JSX.Element { const x = useMotionValue(0); const y = useMotionValue(0); const [isActive, setIsActive] = useState(false); const containerRef = useRef(null); useEffect(() => { if (typeof window !== "undefined" && containerRef.current) { // Get the parent element directly from the ref const parentElement = containerRef.current.parentElement; if (parentElement) { // Add cursor-none to parent parentElement.style.cursor = "none"; // Add event listeners to parent const handleMouseMove = (e: MouseEvent) => { x.set(e.clientX); y.set(e.clientY); }; const handleMouseEnter = () => { setIsActive(true); }; const handleMouseLeave = () => { setIsActive(false); }; parentElement.addEventListener("mousemove", handleMouseMove); parentElement.addEventListener("mouseenter", handleMouseEnter); parentElement.addEventListener("mouseleave", handleMouseLeave); return () => { parentElement.style.cursor = ""; parentElement.removeEventListener("mousemove", handleMouseMove); parentElement.removeEventListener("mouseenter", handleMouseEnter); parentElement.removeEventListener("mouseleave", handleMouseLeave); }; } } }, [x, y]); return ( <>
{isActive && ( {children || ( )} )} ); }