puck / frontend /src /lib /useDrag.ts
vu1n's picture
Puck — desktop fairy familiar (HF Build Small)
3c124f3
Raw
History Blame Contribute Delete
1.22 kB
import * as React from "react";
export interface Pos {
x: number;
y: number;
}
/** Mouse-drag helper shared by windows and panels. Clamps to the viewport. */
export function useDrag(
pos: Pos,
onPos: (p: Pos) => void,
opts: { minX?: number; minY?: number; marginR?: number; marginB?: number } = {},
) {
const { minX = 4, minY = 30, marginR = 80, marginB = 60 } = opts;
// fresh pos for the closure without re-binding listeners mid-drag
const ref = React.useRef(pos);
ref.current = pos;
return React.useCallback(
(e: React.MouseEvent) => {
const sx = e.clientX;
const sy = e.clientY;
const { x: ox, y: oy } = ref.current;
const move = (ev: MouseEvent) => {
onPos({
x: Math.max(minX, Math.min(window.innerWidth - marginR, ox + ev.clientX - sx)),
y: Math.max(minY, Math.min(window.innerHeight - marginB, oy + ev.clientY - sy)),
});
};
const up = () => {
window.removeEventListener("mousemove", move);
window.removeEventListener("mouseup", up);
};
window.addEventListener("mousemove", move);
window.addEventListener("mouseup", up);
},
[onPos, minX, minY, marginR, marginB],
);
}