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