DOM

useMousePosition

Cursor coordinates within an element.

Demo

move your cursor over this panel

x
y

Coordinates are measured from the panel's top-left corner.

Usage

use-mouse-position.tsxtsx
import { useRef } from "react";
import { useMousePosition } from "hookli";

export function Demo() {
  const panelRef = useRef<HTMLDivElement>(null);
  const { x, y } = useMousePosition(panelRef);

  return (
    <div ref={panelRef} style={{ height: 160 }}>
      {x === null || y === null ? (
        <p>Move your cursor</p>
      ) : (
        <p>
          {Math.round(x)} × {Math.round(y)}
        </p>
      )}
    </div>
  );
}

API

useMousePosition.d.tsts
useMousePosition<T extends HTMLElement>(ref: RefObject<T>): { x: number | null; y: number | null }

Parameters

NameTypeDefaultDescription
refRefObject<T>Ref attached to the element the coordinates are measured against.

Returns

NameTypeDescription
xnumber | nullCursor X relative to the element's left edge; null until the first mousemove. Updates on every window mousemove, so it can go negative or exceed the element's width.
ynumber | nullCursor Y relative to the element's top edge; null until the first mousemove.

Hook

The implementation, straight from hookli. Copy it, or install the package.

src/hooks/useMousePosition.hook.tstsx
import { Ref, useEffect, useState } from "react";

interface MousePosition {
  x: number | null;
  y: number | null;
}

export const useMousePosition = <T extends HTMLElement>(
  ref: Ref<T>,
): MousePosition => {
  const [mousePosition, setMousePosition] = useState<MousePosition>({
    x: null,
    y: null,
  });

  useEffect(() => {
    const updateMousePosition = (event: MouseEvent) => {
      const { clientX, clientY } = event;
      if (ref && "current" in ref && ref.current) {
        const { left, top } = ref.current.getBoundingClientRect();
        setMousePosition({ x: clientX - left, y: clientY - top });
      }
    };

    window.addEventListener("mousemove", updateMousePosition);
    return () => {
      window.removeEventListener("mousemove", updateMousePosition);
    };
  }, [ref]);

  return mousePosition;
};

View source on GitHub

Related hooks