{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-mouse",
  "title": "UseMouse",
  "description": "Tracks the mouse position in the element and document.",
  "files": [
    {
      "path": "registry/hooks/use-mouse.tsx",
      "content": "'use client';\n\nimport { RefObject, useCallback, useEffect, useState } from 'react';\n\nexport type UseMouseOptions = {\n  ref: RefObject<HTMLElement>;\n  trackOutside?: boolean;\n  clampToZero?: boolean;\n};\n\n/**\n * Data returned by the useMouse hook\n *\n * @property docX - Mouse X position in the document (pageX)\n * @property docY - Mouse Y position in the document (pageY)\n * @property posX - Element X position on the page (relative to document)\n * @property posY - Element Y position on the page (relative to document)\n * @property elX - Mouse X position relative to the element\n * @property elY - Mouse Y position relative to the element\n * @property elH - Element height\n * @property elW - Element width\n */\ntype MouseData = {\n  docX: number;\n  docY: number;\n  posX: number;\n  posY: number;\n  elX: number;\n  elY: number;\n  elH: number;\n  elW: number;\n};\n\nexport function useMouse({\n  ref,\n  trackOutside = false,\n  clampToZero = false,\n}: UseMouseOptions): MouseData {\n  if (process.env.NODE_ENV === 'development') {\n    if (!ref?.current) {\n      console.error(\n        'useMouse: ref is required and must point to an HTMLElement!',\n      );\n    }\n  }\n\n  const [state, setState] = useState<MouseData>({\n    docX: 0,\n    docY: 0,\n    posX: 0,\n    posY: 0,\n    elX: 0,\n    elY: 0,\n    elH: 0,\n    elW: 0,\n  });\n\n  const moveHandler = useCallback(\n    (event: MouseEvent) => {\n      if (ref && ref.current) {\n        const {\n          left,\n          top,\n          width: elW,\n          height: elH,\n        } = ref.current.getBoundingClientRect();\n        const posX = left + window.pageXOffset;\n        const posY = top + window.pageYOffset;\n        let elX = event.pageX - posX;\n        let elY = event.pageY - posY;\n\n        // Clamps elX/elY to >= 0 if clampToZero\n        if (clampToZero) {\n          elX = Math.max(0, elX);\n          elY = Math.max(0, elY);\n        }\n\n        // If not tracking outside the element, only update if the mouse is inside\n        const isInside =\n          event.pageX >= posX &&\n          event.pageX <= posX + elW &&\n          event.pageY >= posY &&\n          event.pageY <= posY + elH;\n\n        if (trackOutside || isInside) {\n          const nextState: MouseData = {\n            docX: event.pageX,\n            docY: event.pageY,\n            posX,\n            posY,\n            elX,\n            elY,\n            elH,\n            elW,\n          };\n\n          // Updates only if some value has changed\n          setState((prev) => {\n            for (const key in nextState) {\n              if (\n                nextState[key as keyof MouseData] !==\n                prev[key as keyof MouseData]\n              ) {\n                return nextState;\n              }\n            }\n            return prev;\n          });\n        }\n      }\n    },\n    [ref, trackOutside, clampToZero],\n  );\n\n  useEffect(() => {\n    document.addEventListener('mousemove', moveHandler);\n    return () => {\n      document.removeEventListener('mousemove', moveHandler);\n    };\n  }, [moveHandler]);\n\n  return state;\n}\n",
      "type": "registry:hook",
      "target": "hooks/guarahooks/use-mouse.tsx"
    }
  ],
  "categories": [
    "ui-and-dom"
  ],
  "type": "registry:hook"
}