import { useState, useEffect, useCallback } from 'react'; import styles from './CustomCursor.module.css'; export function CustomCursor() { const [position, setPosition] = useState({ x: 0, y: 0 }); const [isPointer, setIsPointer] = useState(false); const [isHidden, setIsHidden] = useState(true); const [isClicking, setIsClicking] = useState(false); const handleMouseMove = useCallback((e: MouseEvent) => { setPosition({ x: e.clientX, y: e.clientY }); setIsHidden(false); const target = e.target as HTMLElement; const isClickable = target.tagName === 'A' || target.tagName === 'BUTTON' || !!target.closest('a') || !!target.closest('button') || window.getComputedStyle(target).cursor === 'pointer'; setIsPointer(isClickable); }, []); const handleMouseDown = useCallback(() => setIsClicking(true), []); const handleMouseUp = useCallback(() => setIsClicking(false), []); const handleMouseLeave = useCallback(() => setIsHidden(true), []); const handleMouseEnter = useCallback(() => setIsHidden(false), []); useEffect(() => { // Don't show custom cursor on touch devices if (window.matchMedia('(hover: none)').matches) { return; } document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mousedown', handleMouseDown); document.addEventListener('mouseup', handleMouseUp); document.addEventListener('mouseleave', handleMouseLeave); document.addEventListener('mouseenter', handleMouseEnter); return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mousedown', handleMouseDown); document.removeEventListener('mouseup', handleMouseUp); document.removeEventListener('mouseleave', handleMouseLeave); document.removeEventListener('mouseenter', handleMouseEnter); }; }, [handleMouseMove, handleMouseDown, handleMouseUp, handleMouseLeave, handleMouseEnter]); // Don't render on touch devices if (typeof window !== 'undefined' && window.matchMedia('(hover: none)').matches) { return null; } return ( <>
> ); }