useMouse#

Reactive pointer position as one { x, y, sourceType } object. Browser composable — import from @sigx/use-web.

It returns a ReactiveView — read mouse.x / mouse.y by property access, each tracked per key, so an x-only consumer doesn't re-run on y changes. Listeners are passive and detach with the owning scope.

TSX
import { component, render } from 'sigx';
import { useMouse } from '@sigx/use-web';

const Pointer = component(() => {
    const mouse = useMouse();
    return () => (
        <p class="font-mono text-sm">
            x: {mouse.x} · y: {mouse.y} · {mouse.sourceType ?? 'none'}
        </p>
    );
});

render(<Pointer />, "#app");

By default it tracks both mouse and touch moves on window, in page coordinates. Switch coordinate systems with type, bind to a specific element with target, or seed the pre-move value with initialValue.

To pull the fields out without snapshotting them, use core's toSignals():

TypeScript
import { toSignals } from 'sigx';
const { x, y } = toSignals(useMouse()); // each a live signal

Every caller that mounts useMouse adds its own mousemove listener. To share one listener app-wide, wrap it: createSharedComposable(useMouse).

Signature#

TypeScript
function useMouse(options?: UseMouseOptions): ReactiveView<MouseState>;

interface MouseState {
    x: number;
    y: number;
    sourceType: 'mouse' | 'touch' | null;
}

Options#

OptionTypeDefaultDescription
type'page' | 'client' | 'screen''page'Coordinate system: page, client (viewport), or screen.
touchbooleantrueAlso track touch moves.
targetMaybeSignal<EventTarget | null | undefined>windowListen on a specific target instead of window.
initialValue{ x: number; y: number }Position before the first move.
windowWindowdefaultWindowOverride the window (SSR/testing).

SSR#

Frozen at initialValue, with sourceType: null — no listeners are attached until mount.

See also#