From f15b56f9eac990ff2b2f6767548c982ad7a7eb24 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 12 Mar 2026 01:23:42 +0000 Subject: [PATCH] Fix node height growing on remount with inline parameters The previous fix skipped the expand animation on initial mount but missed the ResizeObserver path. On remount, trackedSettingsHeightRef resets to 0, and the ResizeObserver sees the full panel height as a delta, adding it to the node height that already includes the panel. Add skipFirstObserveRef: when a node mounts with settings already expanded, the first ResizeObserver callback syncs the tracked height without calling setNodes, preventing the cumulative height growth. https://claude.ai/code/session_01MvD1n4QeXutgwUpKJuDGHa --- src/components/nodes/BaseNode.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/nodes/BaseNode.tsx b/src/components/nodes/BaseNode.tsx index e5f1cca1..4675e340 100644 --- a/src/components/nodes/BaseNode.tsx +++ b/src/components/nodes/BaseNode.tsx @@ -81,16 +81,20 @@ export function BaseNode({ const isAnimatingRef = useRef(false); const animationTimeoutRef = useRef | null>(null); const isInitialMountRef = useRef(true); + // When true, the ResizeObserver should sync trackedSettingsHeightRef without + // modifying node dimensions (the height is already accounted for from a + // previous mount before onlyRenderVisibleElements unmounted us). + const skipFirstObserveRef = useRef(false); // Adjust node height when settings expand or collapse useLayoutEffect(() => { // On initial mount with settings already expanded (e.g. remount after // onlyRenderVisibleElements), the node height already includes the panel. - // Just sync the tracked ref without adding height again. + // Tell the ResizeObserver to sync without adding height. if (isInitialMountRef.current) { isInitialMountRef.current = false; - if (settingsExpanded && settingsPanelRef.current) { - trackedSettingsHeightRef.current = settingsPanelRef.current.offsetHeight; + if (settingsExpanded && settingsPanel) { + skipFirstObserveRef.current = true; } return; } @@ -180,6 +184,15 @@ export function BaseNode({ for (const entry of entries) { const newPanelHeight = entry.contentRect.height; if (newPanelHeight === 0) continue; + + // On remount with settings already expanded, the node height already + // includes the panel. Just sync the ref without modifying dimensions. + if (skipFirstObserveRef.current) { + skipFirstObserveRef.current = false; + trackedSettingsHeightRef.current = newPanelHeight; + continue; + } + const delta = newPanelHeight - trackedSettingsHeightRef.current; if (Math.abs(delta) < 2) continue; // Ignore sub-pixel changes