Add frozen: 'start' | 'end' for end-edge column pinning#4034
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4034 +/- ##
==========================================
+ Coverage 97.48% 97.54% +0.06%
==========================================
Files 38 39 +1
Lines 1549 1588 +39
Branches 497 515 +18
==========================================
+ Hits 1510 1549 +39
Misses 39 39
🚀 New features to boost your workflow:
|
amanmahajan7
left a comment
There was a problem hiding this comment.
Thank you for the PR. A few quick comments. I can do a detailed review in 2 weeks (on a vacation)
| } | ||
|
|
||
| const frozen = rawColumn.frozen ?? false; | ||
| const frozen: boolean | 'start' | 'end' = rawColumn.frozen ?? false; |
There was a problem hiding this comment.
Let's add a type and reuse it
| border-inline-start: var(--rdg-selection-width) solid var(--rdg-selection-color); | ||
| } | ||
|
|
||
| & > .${cellFrozenEnd}:last-child::after { |
There was a problem hiding this comment.
same here, let's dedupe
& > .${cellFrozen}:first-child::before,
& > .${cellFrozenEnd}:last-child::after { }
& > .${cellFrozen}:first-child::before { }
& > .${cellFrozenEnd}:last-child::after { }
5943b18 to
5016075
Compare
|
@amanmahajan7 pushed a revision addressing all 5 comments. On comment 4: intentional divergence from the literal suggestion. Comment 2's dedup removed the separate Two open questions, both breaking — your call:
Both currently kept as-is (non-breaking). No rush — enjoy the vacation. |
c51325e to
d88ce9d
Compare
|
Hi @amanmahajan7 — gentle nudge, no rush. Hope the vacation was good. Branch is up-to-date with
Both are breaking, so I held off. Happy to address whenever you have a window. |
amanmahajan7
left a comment
There was a problem hiding this comment.
A few more cleanup comments. I will do a detailed review soon.
| } | ||
|
|
||
| & > .${cellFrozen}:first-child::before { | ||
| & > .rdg-cell-frozen:first-child::before, |
There was a problem hiding this comment.
lets rename this variable also
| & > .rdg-cell-frozen:first-child::before, | |
| & > .rdg-cell-frozen-start:first-child::before, |
8c52472 to
e9b24ff
Compare
|
@amanmahajan7 thanks — applied all 5 inline comments plus extended the rename principle consistently across the codebase. Your 5 comments:
Same principle applied to similar names (where ambiguous "Frozen" meant "start-frozen"):
All 351 tests pass on chromium + firefox. |
e9b24ff to
f1e732e
Compare
|
I haven't had a chance to review this PR. I will review is as soon as I can. Thanks for your patience. |
|
Hi guys, Could you please consider releasing this pull request to production? I’m currently waiting for this functionality on my side and would greatly appreciate your help. Thanks in advance! |
|
Thanks for your work on this @PaloSP, we are looking forward to have this functionality. @amanmahajan7 I know you are busy, so how can we help to speed this release up? |
ca48030 to
fb064a4
Compare
|
I am planing on reviewing this PR next week. Hopefully we can merge and release a new version early next week. |
amanmahajan7
left a comment
There was a problem hiding this comment.
Looks great overall. A few comments and I think we can add 2 more tests
- calling
scrollToCellon end frozen column https://github.com/grafana/react-data-grid/blob/main/test/browser/scrollToCell.test.tsx#L64 - https://github.com/grafana/react-data-grid/blob/main/test/browser/virtualization.test.ts#L140. We can add a similar test for
frozen: 'end'
| scrollToCell({ idx, rowIdx }) { | ||
| const scrollToIdx = | ||
| idx != null && idx > lastFrozenColumnIndex && idx < columns.length ? idx : undefined; | ||
| idx != null && idx > lastStartFrozenColumnIndex && idx < columns.length ? idx : undefined; |
There was a problem hiding this comment.
| idx != null && idx > lastStartFrozenColumnIndex && idx < columns.length ? idx : undefined; | |
| idx != null && | |
| idx > lastStartFrozenColumnIndex && | |
| (firstEndFrozenColumnIndex === -1 || idx < firstEndFrozenColumnIndex) && | |
| idx < columns.length |
We can skip scrolling for end frozen columns
| // Single shared sticky/z-index rule reused by both edge-frozen variants. | ||
| // Selectors that need to distinguish start vs end use the marker classes | ||
| // (`.rdg-cell-frozen-start` / `.rdg-cell-frozen-end`) directly rather than this ecij identifier. | ||
| export const cellFrozenStart = css` |
There was a problem hiding this comment.
| export const cellFrozenStart = css` | |
| export const cellFrozen = css` |
nit
or
| export const cellFrozenStart = css` | |
| export const cellFrozenBase = css` |
| await expect.element(cell3).toHaveClass(cellClassname, cellFrozenEndClassname, { exact: true }); | ||
| }); | ||
|
|
||
| test('end-frozen cells expose insetInlineEnd and --rdg-frozen-end CSS var', async () => { |
There was a problem hiding this comment.
seems like we are testing implementation details? Can we replicate what we did for start?
There was a problem hiding this comment.
Can rename this file to startFrozen
fb064a4 to
24478ed
Compare
|
@amanmahajan7 all applied, thanks for the review.
New tests: Also rebased on latest |
amanmahajan7
left a comment
There was a problem hiding this comment.
A few more comments. I will do one final review and local testing after this change
|
@amanmahajan7 done, all four:
While at it, swept the whole diff for leftovers of the same patterns and found one: CI green, 351 tests passing. Ready for your final review. |
amanmahajan7
left a comment
There was a problem hiding this comment.
One last comment otherwise ready.
| insetInlineStart: isStartFrozen(column.frozen) | ||
| ? `var(--rdg-frozen-start-${column.idx})` | ||
| : undefined, | ||
| insetInlineEnd: column.frozen === 'end' ? `var(--rdg-frozen-end-${column.idx})` : undefined |
There was a problem hiding this comment.
| insetInlineEnd: column.frozen === 'end' ? `var(--rdg-frozen-end-${column.idx})` : undefined | |
| insetInlineEnd: column.frozen === 'end' ? `var(--rdg-frozen-end-${column.idx + colSpan - 1})` : undefined |
I think we need this. Can you double check
|
@amanmahajan7 good catch, confirmed it's a real bug. |
amanmahajan7
left a comment
There was a problem hiding this comment.
This is great! Thank you for adding this highly requested feature.
Adds right-edge column pinning — long-standing ask (#2873, #3671).
Column.frozenwidens toboolean | 'start' | 'end'.truestays an alias for'start'(backwards compatible).'end'pins to the inline-end edge; symmetric infra:--rdg-frozen-end-${idx}CSS var,rdg-cell-frozen-endclass, end-shadow + top/bottom-summary variants, logical properties throughout.Credit to @robert-luoqing for #3671 which informed the approach. API per @amanmahajan7 and @nstepien's
'start' | 'end'refinement.One check: "we want to prevent the shadow logic" (#3671 2026-04-21) — I interpreted as "preserve" and mirrored the start-shadow symmetrically. If the intent was otherwise, happy to drop it.
Tests: new
test/browser/column/frozenEnd.test.ts+ additions tovirtualization.test.tsanddirection.test.ts. Demo updated inCommonFeatures.