From ad1f7ca7a92f9a797d0c4867f395ddb41646ec14 Mon Sep 17 00:00:00 2001 From: Huarch Date: Sun, 8 Nov 2026 04:16:42 +0800 Subject: [PATCH] fix(charts): move floating windows without per-event renders The earlier placement fix exposed chart headings but retained react-rnd state updates on every mousemove, so dragging still stalled with several charts open. Move the active window through pointer capture and a frame-scheduled DOM translation, then commit its bounds once on release. Cover cancellation, resize and restore controls, and eight-window dragging. The regression records 40 React transform writes on the old code and one on the fix while other windows and chart SVGs stay unchanged. --- src/shared/ui/floating-window.tsx | 10 +- src/shared/ui/use-floating-window-drag.ts | 84 +++++++++++ .../investigation-chart-windows.e2e.ts | 136 +++++++++++++++++- 3 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 src/shared/ui/use-floating-window-drag.ts diff --git a/src/shared/ui/floating-window.tsx b/src/shared/ui/floating-window.tsx index 5b1fc16..73b764b 100644 --- a/src/shared/ui/floating-window.tsx +++ b/src/shared/ui/floating-window.tsx @@ -4,6 +4,7 @@ import { Rnd } from "react-rnd"; import { Maximize2, Minimize2, X } from "lucide-react"; import { Button } from "./button"; import { floatingWindowHost, floatingWindowOrder, raiseFloatingWindow, removeFloatingWindow, subscribeFloatingWindows } from "./floating-window-layer"; +import { useFloatingWindowDrag } from "./use-floating-window-drag"; type Bounds = { x: number; y: number; width: number; height: number }; @@ -84,6 +85,9 @@ export function FloatingWindow({ title, triggerLabel, fillContent = false, openR const current = maximized ? { x: 8, y: 8, width: viewport.width - 16, height: viewport.height - 16 } : bounds; + const startDrag = useFloatingWindowDrag({ enabled: open && !maximized, position: current, + width: current.width, height: current.height, + onCommit: (position) => setBounds((previous) => fitWindow({ ...previous, ...position })) }); return <>