MCPcopy
hub / github.com/opentrace/opentrace / useResizablePanel

Function useResizablePanel

ui/src/hooks/useResizablePanel.ts:56–202  ·  view source on GitHub ↗
({
  storageKey,
  defaultWidth,
  minWidth,
  maxWidth,
  side,
  panelRef,
}: UseResizablePanelOptions)

Source from the content-addressed store, hash-verified

54 * and makes it into localStorage.
55 */
56export function useResizablePanel({
57 storageKey,
58 defaultWidth,
59 minWidth,
60 maxWidth,
61 side,
62 panelRef,
63}: UseResizablePanelOptions): {
64 width: number;
65 handleMouseDown: PanelResizeMouseDown;
66} {
67 const [width, setWidth] = useState(() => {
68 const stored = localStorage.getItem(storageKey);
69 if (stored) {
70 const parsed = parseInt(stored, 10);
71 if (!isNaN(parsed) && parsed >= minWidth && parsed <= maxWidth)
72 return parsed;
73 }
74 return defaultWidth;
75 });
76
77 const isDragging = useRef(false);
78 const startX = useRef(0);
79 const startWidth = useRef(0);
80
81 const handleMouseDown = useCallback<PanelResizeMouseDown>(
82 (e, cursorOverride) => {
83 e.preventDefault();
84 isDragging.current = true;
85 startX.current = e.clientX;
86 // Anchor the drag to whatever width the panel is ACTUALLY rendering —
87 // if a `max-width` CSS clamp has pinned the panel smaller than the
88 // stored React state (e.g. the viewport shrank since last drag), this
89 // keeps the drag feeling continuous with what's on screen.
90 const rendered = panelRef.current?.getBoundingClientRect().width;
91 startWidth.current = rendered ? Math.round(rendered) : width;
92 document.body.style.cursor = cursorOverride ?? 'col-resize';
93 document.body.style.userSelect = 'none';
94 },
95 [width, panelRef],
96 );
97
98 useEffect(() => {
99 let pending: number | null = null;
100 let rafId: number | null = null;
101
102 const flush = () => {
103 rafId = null;
104 const panel = panelRef.current;
105 if (pending == null || !panel) return;
106 // Clamp pending to whatever the parent currently allows so the
107 // drag stops cleanly at the available limit (and doesn't fight the
108 // ResizeObserver's clamp on every frame).
109 const parent = panel.parentElement;
110 if (parent) {
111 const panelRect = panel.getBoundingClientRect();
112 const parentRect = parent.getBoundingClientRect();
113 const available = parentRect.right - panelRect.left - 4;

Callers 5

PhysicsPanelFunction · 0.90
SettingsDrawerFunction · 0.90
HelpDrawerFunction · 0.90
SidePanelFunction · 0.90
ChatPanel.tsxFile · 0.90

Calls 2

observeMethod · 0.95
disconnectMethod · 0.95

Tested by

no test coverage detected