Commit 98f4543
Fix sticky-left columns rendering vertically displaced
Root cause: .dsg-row is a plain block container. .dsg-cell children are
position: absolute (removed from normal flow) except cells that need to
stick, which use position: sticky and therefore stay in normal in-flow
layout. With only the gutter column sticky (pre-nick-keller#386 baseline) there was
exactly one in-flow child per row, which happened to land at the correct
spot by luck. PR nick-keller#386 added up to stickyLeftColumnNumber more
position:sticky cells per row; being in-flow, block layout stacked them
vertically -- one row-height per extra sticky cell -- which is exactly
the observed bug (pinned header cell displaced several rows down, empty/
misaligned pinned cells in the first rows). This is the same class of
issue the pre-existing .dsg-cell-sticky-right `transform:
translateY(-100%)` hack works around for exactly 2 in-flow cells
(gutter + sticky-right); it doesn't generalize to N sticky-left columns.
Fix: keep sticky-left cells position: absolute (out of flow, like
ordinary cells) instead of position: sticky, and compute their `left` in
JS as the column virtualizer's own `col.start` (its natural, unpinned
position) plus the container's current horizontal scrollLeft, tracked in
Grid.tsx via the container's onScroll handler. This keeps them visually
pinned without touching row flow layout at all, and leaves the existing
gutter/sticky-right mechanism untouched.
Using `col.start` (rather than the `columnRights` prop) as the offset
anchor also fixes a related bug found during verification: columnRights
can be transiently undefined before react-resize-detector reports a
real container width (it deliberately skips its on-mount measurement),
which made every sticky-left cell fall back to left: 0 and collapse onto
the gutter. col.start is always populated -- it falls back to the same
100px estimate ordinary cells use -- so sticky-left cells stay aligned
with their neighbors in that window too.
- src/style.css: drop `position: sticky` from .dsg-cell-sticky-left
(z-index kept for stacking above scrolled-under cells); add comment
explaining why, referencing the sticky-right translateY hack.
- src/components/Grid.tsx: track scrollLeft state via the container's
onScroll; add getStickyLeftOffset(colStart) = colStart + scrollLeft;
wire it into both the header-row and body-row sticky-left cells.
- dist/: rebuilt (npm run build) and verified npm test passes
(16 suites / 100 tests, including tests/stickyColumns.test.tsx).
- package.json: version -> 4.11.6-grid.2.
Verified live in the consumer app (base-de-datos-grid, packages/
payload-grid-view) against Directorio's 5391-row grid with
stickyLeftColumnNumber={2}: row 1 ('"El Chango" Cabral') and the header
render aligned; horizontal scroll keeps the gutter, open-record arrow,
and Nombre columns pinned with opaque backgrounds while other columns
slide underneath, at both small and large scroll offsets; alignment
holds during vertical scroll while horizontally scrolled; dark theme
(html[data-theme='dark'] .pgv-grid) stays legible with opaque cell
backgrounds.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>1 parent c412dcc commit 98f4543
7 files changed
Lines changed: 80 additions & 21 deletions
File tree
- dist
- components
- src
- components
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments