From 9fb25f4543c111c7e49a2fb592da143dad8858bc Mon Sep 17 00:00:00 2001 From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:29:59 +0800 Subject: [PATCH] fix(issues): prevent sticky mini bar oscillation with height placeholder When the agent live card collapses to sticky mode, its height drops from ~320px to ~40px. This layout shift caused content below to jump up, re-triggering IntersectionObserver and creating an infinite loop. Fix: capture the card's expanded height before collapsing, then set minHeight on a wrapper div to preserve the space. Content below stays put, sentinel stays out of view, no oscillation. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../features/issues/components/agent-live-card.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/web/features/issues/components/agent-live-card.tsx b/apps/web/features/issues/components/agent-live-card.tsx index 110eb1ff..c2676724 100644 --- a/apps/web/features/issues/components/agent-live-card.tsx +++ b/apps/web/features/issues/components/agent-live-card.tsx @@ -112,8 +112,10 @@ export function AgentLiveCard({ issueId, agentName, scrollContainerRef }: AgentL const [autoScroll, setAutoScroll] = useState(true); const [cancelling, setCancelling] = useState(false); const [isStuck, setIsStuck] = useState(false); + const [cardHeight, setCardHeight] = useState(0); const scrollRef = useRef(null); const sentinelRef = useRef(null); + const cardRef = useRef(null); const seenSeqs = useRef(new Set()); // Check for active task on mount @@ -237,7 +239,13 @@ export function AgentLiveCard({ issueId, agentName, scrollContainerRef }: AgentL const observer = new IntersectionObserver( (entries) => { - if (entries[0]) setIsStuck(!entries[0].isIntersecting); + if (!entries[0]) return; + const stuck = !entries[0].isIntersecting; + // Capture expanded height before collapsing to use as placeholder + if (stuck && cardRef.current) { + setCardHeight(cardRef.current.offsetHeight); + } + setIsStuck(stuck); }, { root, threshold: 0, rootMargin: "-40px 0px 0px 0px" }, ); @@ -284,7 +292,10 @@ export function AgentLiveCard({ issueId, agentName, scrollContainerRef }: AgentL {/* Sentinel — zero-height element that IntersectionObserver watches */}
+ {/* Placeholder preserves card height when stuck, preventing layout shift */} +
+
); }