From e8555625ff99e42370ff26c5d3e2d7fd4a133072 Mon Sep 17 00:00:00 2001 From: DexterFromLab Date: Thu, 12 Mar 2026 14:32:14 +0100 Subject: [PATCH] Fix horizontal grid jumping caused by scrollIntoView bubbling scrollIntoView() in AgentPane was scrolling all ancestor containers including ProjectGrid (overflow-x: auto), causing the entire project grid to jump horizontally every time any agent produced output. Replaced with direct scrollTop/scrollTo manipulation that only affects the intended scroll container. Also removed scroll-snap-type which caused additional snap recalculation on layout changes. Co-Authored-By: Claude Opus 4.6 --- v2/src/lib/components/Agent/AgentPane.svelte | 11 +++++++---- v2/src/lib/components/Workspace/ProjectBox.svelte | 2 +- .../lib/components/Workspace/ProjectGrid.svelte | 15 +++++++++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/v2/src/lib/components/Agent/AgentPane.svelte b/v2/src/lib/components/Agent/AgentPane.svelte index 277e1e8..05890dc 100644 --- a/v2/src/lib/components/Agent/AgentPane.svelte +++ b/v2/src/lib/components/Agent/AgentPane.svelte @@ -286,7 +286,10 @@ ); if (!msg) return; autoScroll = false; - scrollContainer.querySelector('#msg-' + CSS.escape(msg.id))?.scrollIntoView({ behavior: 'smooth', block: 'center' }); + const el = scrollContainer.querySelector('#msg-' + CSS.escape(msg.id)); + if (el instanceof HTMLElement) { + scrollContainer.scrollTop = el.offsetTop - scrollContainer.clientHeight / 2 + el.offsetHeight / 2; + } } // Scroll anchoring: two-phase pattern @@ -300,7 +303,7 @@ }); $effect(() => { if (session?.messages.length !== undefined && wasNearBottom && autoScroll) { - scrollContainer?.querySelector('#message-end')?.scrollIntoView({ behavior: 'instant' as ScrollBehavior }); + if (scrollContainer) scrollContainer.scrollTop = scrollContainer.scrollHeight; } }); @@ -585,7 +588,7 @@ ${burnRatePerHr.toFixed(2)}/hr {/if} {#if !autoScroll} - + {/if} @@ -607,7 +610,7 @@ {/if} {#if !autoScroll} - + {/if} {:else if session.status === 'error'} diff --git a/v2/src/lib/components/Workspace/ProjectBox.svelte b/v2/src/lib/components/Workspace/ProjectBox.svelte index c990edb..2afb602 100644 --- a/v2/src/lib/components/Workspace/ProjectBox.svelte +++ b/v2/src/lib/components/Workspace/ProjectBox.svelte @@ -390,7 +390,7 @@ display: grid; grid-template-rows: auto auto 1fr auto; min-width: 30rem; - scroll-snap-align: start; + /* scroll-snap-align removed: see ProjectGrid */ background: var(--ctp-base); border: 1px solid var(--ctp-surface0); border-radius: 0.375rem; diff --git a/v2/src/lib/components/Workspace/ProjectGrid.svelte b/v2/src/lib/components/Workspace/ProjectGrid.svelte index d07aa78..1efa4ac 100644 --- a/v2/src/lib/components/Workspace/ProjectGrid.svelte +++ b/v2/src/lib/components/Workspace/ProjectGrid.svelte @@ -16,14 +16,21 @@ let slotEls = $state>({}); // Auto-scroll to active project only when activeProjectId changes - // (untrack slotEls so agent re-renders don't trigger unwanted scrolls) + // Uses direct scrollLeft instead of scrollIntoView to avoid bubbling to parent containers $effect(() => { const id = activeProjectId; - if (!id) return; + if (!id || !containerEl) return; untrack(() => { const el = slotEls[id]; if (!el) return; - el.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' }); + // Only scroll if the slot is not already visible + const cRect = containerEl!.getBoundingClientRect(); + const eRect = el.getBoundingClientRect(); + if (eRect.left >= cRect.left && eRect.right <= cRect.right) return; + containerEl!.scrollTo({ + left: el.offsetLeft - containerEl!.offsetLeft, + behavior: 'smooth', + }); }); }); @@ -75,7 +82,7 @@ gap: 0.25rem; height: 100%; overflow-x: auto; - scroll-snap-type: x mandatory; + /* scroll-snap disabled: was causing horizontal jumps when agents auto-scroll */ padding: 0.25rem; }