Browse Source

Revert "Fix inline parameter panel causing node height growth on remount"

This reverts commit fe9741708c.
handoff-20260429-1057
Claude 4 months ago
parent
commit
c0bde7671e
Failed to extract signature
  1. 24
      src/components/nodes/BaseNode.tsx
  2. 9
      src/components/nodes/InlineParameterPanel.tsx

24
src/components/nodes/BaseNode.tsx

@ -81,26 +81,20 @@ export function BaseNode({
const isAnimatingRef = useRef(false); const isAnimatingRef = useRef(false);
const animationTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null); const animationTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const isInitialMountRef = useRef(true); const isInitialMountRef = useRef(true);
// When true, the ResizeObserver syncs trackedSettingsHeightRef without // When true, the ResizeObserver should sync trackedSettingsHeightRef without
// modifying node dimensions (height already includes the panel from a // modifying node dimensions (the height is already accounted for from a
// previous mount before onlyRenderVisibleElements unmounted us). // previous mount before onlyRenderVisibleElements unmounted us).
const suppressObserverRef = useRef(false); const skipFirstObserveRef = useRef(false);
const suppressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
// Adjust node height when settings expand or collapse // Adjust node height when settings expand or collapse
useLayoutEffect(() => { useLayoutEffect(() => {
// On initial mount with settings already expanded (e.g. remount after // On initial mount with settings already expanded (e.g. remount after
// onlyRenderVisibleElements), the node height already includes the panel. // onlyRenderVisibleElements), the node height already includes the panel.
// Suppress ResizeObserver dimension changes while the panel settles. // Tell the ResizeObserver to sync without adding height.
if (isInitialMountRef.current) { if (isInitialMountRef.current) {
isInitialMountRef.current = false; isInitialMountRef.current = false;
if (settingsExpanded && settingsPanel) { if (settingsExpanded && settingsPanel) {
suppressObserverRef.current = true; skipFirstObserveRef.current = true;
// Allow suppression for long enough that the panel fully renders
suppressTimerRef.current = setTimeout(() => {
suppressObserverRef.current = false;
suppressTimerRef.current = null;
}, 300);
} }
return; return;
} }
@ -193,7 +187,8 @@ export function BaseNode({
// On remount with settings already expanded, the node height already // On remount with settings already expanded, the node height already
// includes the panel. Just sync the ref without modifying dimensions. // includes the panel. Just sync the ref without modifying dimensions.
if (suppressObserverRef.current) { if (skipFirstObserveRef.current) {
skipFirstObserveRef.current = false;
trackedSettingsHeightRef.current = newPanelHeight; trackedSettingsHeightRef.current = newPanelHeight;
continue; continue;
} }
@ -236,15 +231,12 @@ export function BaseNode({
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [settingsExpanded, settingsPanel]); }, [settingsExpanded, settingsPanel]);
// Cleanup timeouts on unmount // Cleanup animation timeout on unmount
useLayoutEffect(() => { useLayoutEffect(() => {
return () => { return () => {
if (animationTimeoutRef.current) { if (animationTimeoutRef.current) {
clearTimeout(animationTimeoutRef.current); clearTimeout(animationTimeoutRef.current);
} }
if (suppressTimerRef.current) {
clearTimeout(suppressTimerRef.current);
}
}; };
}, []); }, []);

9
src/components/nodes/InlineParameterPanel.tsx

@ -21,15 +21,10 @@ function InlineParameterPanelInner({
}: InlineParameterPanelProps) { }: InlineParameterPanelProps) {
const contentRef = useRef<HTMLDivElement>(null); const contentRef = useRef<HTMLDivElement>(null);
const [contentHeight, setContentHeight] = useState(0); const [contentHeight, setContentHeight] = useState(0);
// When mounted with expanded=true (e.g. remount after scrolling back into
// view), render at full height immediately instead of animating from 0.
const mountedExpandedRef = useRef(expanded);
useEffect(() => { useEffect(() => {
if (expanded && contentRef.current) { if (expanded && contentRef.current) {
setContentHeight(contentRef.current.scrollHeight); setContentHeight(contentRef.current.scrollHeight);
// After first measurement, future changes should animate normally
mountedExpandedRef.current = false;
} }
}, [expanded, children]); }, [expanded, children]);
@ -62,8 +57,8 @@ function InlineParameterPanelInner({
{/* Content area — smooth height animation */} {/* Content area — smooth height animation */}
<div <div
id={`params-${nodeId}`} id={`params-${nodeId}`}
className={`nodrag nopan nowheel bg-[#2a2a2a] overflow-hidden rounded-b-lg ${mountedExpandedRef.current ? "" : "transition-[max-height] duration-150 ease-out"}`} className="nodrag nopan nowheel bg-[#2a2a2a] overflow-hidden transition-[max-height] duration-150 ease-out rounded-b-lg"
style={{ maxHeight: expanded ? (mountedExpandedRef.current ? "none" : contentHeight) : 0 }} style={{ maxHeight: expanded ? contentHeight : 0 }}
> >
<div ref={contentRef} className="px-3 pt-2 pb-3 rounded-b-lg"> <div ref={contentRef} className="px-3 pt-2 pb-3 rounded-b-lg">
{children} {children}

Loading…
Cancel
Save