The MOCKED_SCROLLBAR_PROBE_SIZE comment still described the mock as
distinguishing the JS probe from the CSS gutter reservation, the same
probe-vs-gutter framing already retracted and corrected everywhere else in
this file and RCA.md. Reword it to match: the mock detects reintroduction of
the removed maxWidth - scrollBarSize subtraction, not a gutter/probe
mismatch.
Refs #21063
Some comments (useSticky.tsx, useSticky.test.tsx, RCA.md) still framed the
scrollbar-gutter/scrollBarStyles matching as the mechanism that prevents the
reported clipping, contradicting this branch's own hit-testing conclusion
that it's the unconditional width: maxWidth change that's load-bearing, with
gutter/style matching kept only as an unverified, secondary consistency
measure for combined horizontal+vertical scrolling. Rewrite those comments
and RCA sections to say so explicitly, and fix a getScrollBarSize.test.ts
comment that still described the removed maxWidth - scrollBarSize
subtraction as the header's "shrink amount".
Also remove the `as any` casts from the sticky regression test: type
`columns` as `Column<Row>[]` and pass `useSticky` directly, letting
`headerGroups`/`rows`/`cells` infer their existing react-table types (already
declared in `src/DataTable/types/react-table.d.ts`) instead of bypassing
type-checking of the exercised contract.
Refs #21063
The previous round's RCA claimed clipping based on comparing clientWidth to
scrollWidth on an overflow:hidden element, but scrollbar-gutter's reserved
space is phantom for overflow:hidden (never rendered as a real scrollbar),
so it doesn't move the actual clip boundary. Real-browser hit-testing
(document.elementFromPoint sweeps in headed Chromium) shows that comparison
doesn't demonstrate clipping. Retract that claim in RCA.md and replace it
with the structural reason the fix is correct regardless of any browser's
scrollbar-probe accuracy: the shared colgroup is always bounded by the
sizer's clientWidth, which is always bounded by maxWidth, so an unconditional
width: maxWidth on header/footer can never be narrower than the table it
must display.
Also add a /** @jsxImportSource @emotion/react */ pragma to useSticky.tsx so
its css prop is observable in this repo's Jest/Babel setup the same way
webpack/SWC already observes it in production, and use that to extend the
regression test to assert header/footer actually receive the
scrollBarStyles-generated class (previously only the inline width/
scrollbarGutter half was pinned, so the test passed with or without the
scrollBarStyles addition).
Refs #21063
scrollbar-gutter: stable's reserved width depends on whether custom
::-webkit-scrollbar styling is applied to that element (verified in both
headless and headed Chromium: 15px unstyled vs 8px styled, matching
CUSTOM_SCROLLBAR_SIZE). The previous fix reserved the gutter on the
header/footer wrappers without also giving them the same custom scrollbar
CSS the body/sizer carry, so they reserved a different (larger) amount and
could still clip the shared colgroup's rightmost column.
Also corrects the RCA: real, non-headless browser testing shows unmodified
master's original scrollBarSize-based computation does not diverge from
the body/sizer's reservation under any real condition reproduced in this
investigation (only headless Chromium's synthetic scrollbar probe showed a
difference, which turned out to be a headless-only rendering artifact, not
representative of a real user's browser). The fix still removes a real,
demonstrated defect class -- relying on two independently-measured
scrollbar-space numbers to agree -- rather than the exact historical
trigger, which remains unpinned.
The sticky header/footer wrapper width was narrowed by a separately
JS-measured scrollbar size, while the column widths shared via colgroup
were computed against the browser's own `scrollbar-gutter: stable`
reservation used by the body div. These two numbers aren't guaranteed to
agree, and when the probe overstates the real reservation the fixed-layout
table overflows its `overflow: hidden` wrapper, clipping the rightmost
column -- typically the totals row once a chart is resized enough to need
a vertical scrollbar.
Header and footer now reserve space via the same `scrollbar-gutter`
property the body already uses, so all three always agree.
Fixes#21063