Context
Found while fixing #12906 (overdrag scroll term): the redesigned overdrag path routes scrolling through the dedicated horizontal scrollbar element (the scroll SSOT), which surfaced that the scrollbar's own range is short in locked-column grids. This is a pre-existing, drag-independent bug: plain user scrolling cannot reach the last center columns.
Release classification: ON the board — #12906 (sub of #12883, the v13 locked-column DnD gate) routes overdrag through this element; with the short range, overdrag-right would stop ~5 columns early in devindex.
The Problem
Live measurement (devindex @ 1680×1000, locked-start 370px [3 columns], locked-end 120px [1 column], center content 3036px, center clip 1156px):
neo-grid-horizontal-scrollbar-1: clientWidth: 1646 (FULL grid width), scrollWidth: 3036 (center content) → max scrollLeft = 1390
neo-grid-header-toolbar-1 (center): clientWidth: 1156, scrollWidth: 3036 → needs max 1880
- At scrollbar max, the toolbar (synced verbatim by
GridHorizontalScrollSync) sits at 1390: the last center column renders at viewport x 1953..2033 — 410px past the center region's right edge (1543) and unreachable. The shortfall is exactly the locked widths: 1880 − 1390 = 490 = 370 + 120.
The Architectural Reality
grid.HorizontalScrollbar renders a 1px-high spacer sized via centerWidth_ (fed from the center grid.Body#afterSetAvailableWidth, src/grid/Body.mjs:411), but the scrollbar's own element spans the full grid width — its scrollport includes the locked regions, while its content models only the center.
Neo.main.addon.GridHorizontalScrollSync#onScroll copies scrollerNode.scrollLeft verbatim to the center header toolbar and to the bodies' --grid-scroll-left CSS var — a 1:1 mapping that is only correct when the scrollbar's scrollport equals the center clip width.
- Single-region grids are unaffected (clip == grid width; the mapping is exact).
The Fix
Scope the scrollbar's scrollport to the center region: add startWidth_ / endWidth_ configs to grid.HorizontalScrollbar that apply margin-left / margin-right on its root, fed from the locked bodies' availableWidth exactly like the existing centerWidth feed (extend the src/grid/Body.mjs:411 block to route per region). Result: scrollport = center clip width; max scrollLeft = center content − center clip; the addon's verbatim copy becomes exact for every region split.
UX note (flagging explicitly for the operator): the visible scrollbar track then spans only the center region — locked columns no longer have dead track under them. This matches the freeze-pane convention (Excel, AG Grid pinned columns).
Acceptance Criteria
Out of Scope
- The overdrag routing itself (that is #12906's deliverable; this ticket is the range substrate it stands on).
- Vertical scrollbar architecture (the
#9486 family).
Related
- Consumer: #12906 (overdrag pipeline routing) · Parent gate: #12883 · Addon:
src/main/addon/GridHorizontalScrollSync.mjs
Live latest-open sweep: checked latest 20 open issues at 2026-06-11T15:50Z; no equivalent found (the #9486 family covers vertical-scrollbar architecture). A2A in-flight claim sweep: no overlapping lane claims in the last hour.
Origin Session ID: e605ce21-3668-445c-bc00-45896aa9a092
Retrieval Hint: "horizontal scrollbar scrollport locked widths 1390 1880 unreachable center columns"
Context
Found while fixing #12906 (overdrag scroll term): the redesigned overdrag path routes scrolling through the dedicated horizontal scrollbar element (the scroll SSOT), which surfaced that the scrollbar's own range is short in locked-column grids. This is a pre-existing, drag-independent bug: plain user scrolling cannot reach the last center columns.
Release classification:ON the board — #12906 (sub of #12883, the v13 locked-column DnD gate) routes overdrag through this element; with the short range, overdrag-right would stop ~5 columns early in devindex.The Problem
Live measurement (devindex @ 1680×1000, locked-start 370px [3 columns], locked-end 120px [1 column], center content 3036px, center clip 1156px):
neo-grid-horizontal-scrollbar-1:clientWidth: 1646(FULL grid width),scrollWidth: 3036(center content) → maxscrollLeft= 1390neo-grid-header-toolbar-1(center):clientWidth: 1156,scrollWidth: 3036→ needs max 1880GridHorizontalScrollSync) sits at 1390: the last center column renders at viewport x 1953..2033 — 410px past the center region's right edge (1543) and unreachable. The shortfall is exactly the locked widths: 1880 − 1390 = 490 = 370 + 120.The Architectural Reality
grid.HorizontalScrollbarrenders a 1px-high spacer sized viacenterWidth_(fed from the centergrid.Body#afterSetAvailableWidth,src/grid/Body.mjs:411), but the scrollbar's own element spans the full grid width — its scrollport includes the locked regions, while its content models only the center.Neo.main.addon.GridHorizontalScrollSync#onScrollcopiesscrollerNode.scrollLeftverbatim to the center header toolbar and to the bodies'--grid-scroll-leftCSS var — a 1:1 mapping that is only correct when the scrollbar's scrollport equals the center clip width.The Fix
Scope the scrollbar's scrollport to the center region: add
startWidth_/endWidth_configs togrid.HorizontalScrollbarthat applymargin-left/margin-righton its root, fed from the locked bodies'availableWidthexactly like the existingcenterWidthfeed (extend thesrc/grid/Body.mjs:411block to route per region). Result: scrollport = center clip width; max scrollLeft = center content − center clip; the addon's verbatim copy becomes exact for every region split.UX note (flagging explicitly for the operator): the visible scrollbar track then spans only the center region — locked columns no longer have dead track under them. This matches the freeze-pane convention (Excel, AG Grid pinned columns).
Acceptance Criteria
Out of Scope
#9486family).Related
src/main/addon/GridHorizontalScrollSync.mjsLive latest-open sweep: checked latest 20 open issues at 2026-06-11T15:50Z; no equivalent found (the
#9486family covers vertical-scrollbar architecture). A2A in-flight claim sweep: no overlapping lane claims in the last hour.Origin Session ID: e605ce21-3668-445c-bc00-45896aa9a092
Retrieval Hint: "horizontal scrollbar scrollport locked widths 1390 1880 unreachable center columns"