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], ); }