{ "name": "cursor", "type": "registry:ui", "registryDependencies": [], "dependencies": [ "motion" ], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "cursor.tsx", "content": "'use client';\nimport React, { useEffect, useState, useRef } from 'react';\nimport {\n motion,\n SpringOptions,\n useMotionValue,\n useSpring,\n AnimatePresence,\n Transition,\n Variant,\n} from 'motion/react';\nimport { cn } from '@/lib/utils';\n\nexport type CursorProps = {\n children: React.ReactNode;\n className?: string;\n springConfig?: SpringOptions;\n attachToParent?: boolean;\n transition?: Transition;\n variants?: {\n initial: Variant;\n animate: Variant;\n exit: Variant;\n };\n onPositionChange?: (x: number, y: number) => void;\n};\n\nexport function Cursor({\n children,\n className,\n springConfig,\n attachToParent,\n variants,\n transition,\n onPositionChange,\n}: CursorProps) {\n const cursorX = useMotionValue(0);\n const cursorY = useMotionValue(0);\n const cursorRef = useRef(null);\n const [isVisible, setIsVisible] = useState(!attachToParent);\n\n useEffect(() => {\n if (typeof window !== 'undefined') {\n cursorX.set(window.innerWidth / 2);\n cursorY.set(window.innerHeight / 2);\n }\n }, []);\n\n useEffect(() => {\n if (!attachToParent) {\n document.body.style.cursor = 'none';\n } else {\n document.body.style.cursor = 'auto';\n }\n\n const updatePosition = (e: MouseEvent) => {\n cursorX.set(e.clientX);\n cursorY.set(e.clientY);\n onPositionChange?.(e.clientX, e.clientY);\n };\n\n document.addEventListener('mousemove', updatePosition);\n\n return () => {\n document.removeEventListener('mousemove', updatePosition);\n };\n }, [cursorX, cursorY, onPositionChange]);\n\n const cursorXSpring = useSpring(cursorX, springConfig || { duration: 0 });\n const cursorYSpring = useSpring(cursorY, springConfig || { duration: 0 });\n\n useEffect(() => {\n const handleVisibilityChange = (visible: boolean) => {\n setIsVisible(visible);\n };\n\n if (attachToParent && cursorRef.current) {\n const parent = cursorRef.current.parentElement;\n if (parent) {\n parent.addEventListener('mouseenter', () => {\n parent.style.cursor = 'none';\n handleVisibilityChange(true);\n });\n parent.addEventListener('mouseleave', () => {\n parent.style.cursor = 'auto';\n handleVisibilityChange(false);\n });\n }\n }\n\n return () => {\n if (attachToParent && cursorRef.current) {\n const parent = cursorRef.current.parentElement;\n if (parent) {\n parent.removeEventListener('mouseenter', () => {\n parent.style.cursor = 'none';\n handleVisibilityChange(true);\n });\n parent.removeEventListener('mouseleave', () => {\n parent.style.cursor = 'auto';\n handleVisibilityChange(false);\n });\n }\n }\n };\n }, [attachToParent]);\n\n return (\n \n \n {isVisible && (\n \n {children}\n \n )}\n \n \n );\n}\n", "type": "registry:ui" } ] }