From 9dc28f4fdefe07518e793793f495ca4e200fde43 Mon Sep 17 00:00:00 2001 From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com> Date: Fri, 12 Jun 2026 18:32:05 +0800 Subject: [PATCH] fix(agents): single scroll container for the list (trial before rollout) Both scroll axes move to the outer wrapper; the grid drops h-full and the rows wrapper drops its own overflow. Kills the percentage-height bridge between the two scroll elements that fed the flickering double scrollbars and clipped the last row under the horizontal scrollbar. Sticky header pins inside the scroller; vertical scrollbar now spans the full pane (Linear's structure). Skills/autopilots follow after visual confirmation. Co-Authored-By: Claude Fable 5 --- .../views/agents/components/agents-page.tsx | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/views/agents/components/agents-page.tsx b/packages/views/agents/components/agents-page.tsx index 2d86dbb53..3f3b06f3b 100644 --- a/packages/views/agents/components/agents-page.tsx +++ b/packages/views/agents/components/agents-page.tsx @@ -934,12 +934,18 @@ export function AgentsPage(_props: AgentsPageProps = {}) { return filtered; }, [scopeRows, filters, sortField, sortDirection]); - // Row virtualization — headless math, offsets as padding on the body, - // fixed-height rows. - const listBodyRef = useRef(null); + // Row virtualization — headless math, offsets as padding on the rows + // wrapper, fixed-height rows. The scroll element is the SINGLE outer + // scroller (both axes): splitting horizontal scrolling (wrapper) from + // vertical scrolling (an inner element) connected by an h-full + // percentage bridge caused a non-converging layout loop (flickering + // double scrollbars) and clipped the last row under the horizontal + // scrollbar. The sticky header pins inside this scroller; the vertical + // scrollbar spans the full pane height (Linear's structure). + const listScrollRef = useRef(null); const rowVirtualizer = useVirtualizer({ count: rows.length, - getScrollElement: () => listBodyRef.current, + getScrollElement: () => listScrollRef.current, estimateSize: () => ROW_HEIGHT, overscan: 10, }); @@ -1031,9 +1037,12 @@ export function AgentsPage(_props: AgentsPageProps = {}) { allRows={scopeRows} visibleCount={rows.length} /> -
+
+ {/* Plain subgrid passthrough (NOT ListGridBody): scrolling + lives on the outer wrapper, this div only groups the rows + and carries the virtualization padding. */}