Skip to content

refactor: single scrollbar add and named slack in getHeadersWidth - #1274

Merged
6pac merged 1 commit into
masterfrom
refactor/headers-width-slack
Aug 10, 2026
Merged

refactor: single scrollbar add and named slack in getHeadersWidth#1274
6pac merged 1 commit into
masterfrom
refactor/headers-width-slack

Conversation

@6pac-ai

@6pac-ai 6pac-ai commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Resolves the Q16 investigation item from the quirks triage (discussion #1247): getHeadersWidth() added the vertical-scrollbar width to the active band twice — once in the conditional gutter-attribution block (from #1260, gated on !autoHeight), and once more, unconditionally, in the band-finalization block. Two generations of code expressing the same intent.

Why the duplicate add contributes nothing

The band widths already carry the classic +1000 fixed slack (applied to the left band and again to the return value), which is what actually guarantees the two invariants the header width serves:

  1. the header band's scroll range covers the body viewport's scroll range (header width is the header/body scroll-sync floor), and
  2. column drag-reorder has room past the last column.

A second ≤17px scrollbar term riding on a 1000px slack cannot be load-bearing. It was also wrong-shaped: the conditional add correctly skips autoHeight grids (which have no vertical scrollbar), while the unconditional one gave them a gutter for a scrollbar that doesn't exist.

The change

  • Exactly one scrollbar add remains — the documented, conditional gutter attribution.
  • The two unconditional duplicate adds are deleted.
  • The 1000 literals are promoted to a named module constant, HEADER_WIDTH_SLACK, with a comment stating what the slack is for — the intent is now explicit rather than folklore.

Net effect on computed widths: the header container gets ≤17px narrower (and autoHeight grids lose the phantom gutter). The container is clipped, and both scroll-range floors retain the full 1000px slack, so nothing is user-visible.

This also simplifies the #1238 rework: the ViewportMgr's computeHeaderWidths currently mirrors the double-add bit-for-bit; after this lands it mirrors one sane formula.

Test

cypress/e2e/headers-width-scroll-sync.cy.ts — a regression pin, not a bug repro (there is no fail-on-unfixed leg, and per that, no temporary example page). Self-hosting harness with three grids — plain, frozenColumn: 1 (right band scrolls), and autoHeight — asserting for each: header scroll range ≥ body scroll range, header scroller reaches the body's scrollLeft at full right scroll (no clamping), and the last column's header stays pixel-aligned with its body cells there. Verified to pass on the pre-change build (baseline) and on the refactored build, so any future width-formula change that breaks scroll sync fails this spec.

Full cypress suite: all specs passed — 652 tests, 650 passing, 2 pre-existing skips (4m51s).

(Quirks-triage follow-up: with this, every actionable item from discussion #1247 is resolved on master — remaining entries are the documented keep-as-is decisions and the Q32 product call.)

🤖 Generated with Claude Code

The vertical-scrollbar width was added to the active header band twice:
once in the conditional gutter-attribution block and once more,
unconditionally, in the band finalization - two generations of code
expressing the same intent, with the second add also giving autoHeight
grids a gutter for a scrollbar that does not exist. The band widths
already carry the 1000px slack that guarantees the scroll-range floor,
so the duplicate term contributed nothing. Exactly one conditional add
remains, and the slack literal is promoted to HEADER_WIDTH_SLACK.

The new headers-width-scroll-sync spec pins the observable contract
(range floor, sync at full right scroll, last-column alignment) across
plain, frozen-column and autoHeight grids; it passes on both the
pre-change and refactored builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants