import { useCallback, useEffect, useRef, useState, type CSSProperties, type ReactNode } from 'react' const STORAGE_KEY = 'trace.treeWidth' const DEFAULT_WIDTH = 380 const MIN_WIDTH = 280 const MAX_WIDTH = 560 function clampWidth(width: number): number { return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.round(width))) } function readStoredWidth(): number { try { const stored = window.localStorage.getItem(STORAGE_KEY) const parsed = stored === null ? Number.NaN : Number.parseInt(stored, 10) return Number.isFinite(parsed) ? clampWidth(parsed) : DEFAULT_WIDTH } catch { return DEFAULT_WIDTH } } function persistWidth(width: number) { try { window.localStorage.setItem(STORAGE_KEY, String(width)) } catch { // localStorage unavailable (private mode); keep the in-memory width. } } export function TraceSplitLayout({ tree, detail }: { tree: ReactNode; detail: ReactNode }) { const [width, setWidth] = useState(readStoredWidth) const dragRef = useRef<{ startX: number; startWidth: number } | null>(null) const widthRef = useRef(width) widthRef.current = width const onPointerMove = useCallback((event: MouseEvent) => { const drag = dragRef.current if (!drag) return setWidth(clampWidth(drag.startWidth + (event.clientX - drag.startX))) }, []) const onPointerUp = useCallback(() => { if (!dragRef.current) return dragRef.current = null persistWidth(widthRef.current) document.body.style.removeProperty('cursor') document.body.style.removeProperty('user-select') window.removeEventListener('mousemove', onPointerMove) window.removeEventListener('mouseup', onPointerUp) }, [onPointerMove]) const onDividerMouseDown = useCallback((event: React.MouseEvent) => { event.preventDefault() dragRef.current = { startX: event.clientX, startWidth: widthRef.current } document.body.style.cursor = 'col-resize' document.body.style.userSelect = 'none' window.addEventListener('mousemove', onPointerMove) window.addEventListener('mouseup', onPointerUp) }, [onPointerMove, onPointerUp]) const onDividerDoubleClick = useCallback(() => { setWidth(DEFAULT_WIDTH) persistWidth(DEFAULT_WIDTH) }, []) useEffect(() => () => { window.removeEventListener('mousemove', onPointerMove) window.removeEventListener('mouseup', onPointerUp) }, [onPointerMove, onPointerUp]) return (