refactor(table): add grouped and pinned column headers to table component#8392
Draft
LWS49 wants to merge 1 commit into
Draft
refactor(table): add grouped and pinned column headers to table component#8392LWS49 wants to merge 1 commit into
LWS49 wants to merge 1 commit into
Conversation
09a480d to
26e50f1
Compare
26e50f1 to
714bb53
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the shared TanStack/MUI table component to support multi-level grouped column headers and sticky pinned columns, including full support for combining pinned columns with row selectors and row indices.
Implementation
Builder (
buildHeaderRows)A new pure function converts a flat
ColumnTemplate[]into a row-majorHeaderRow[]grid for the renderer. Columns are partitioned intoleftPin | middle | rightPin; pinned columns always appear first and last in visual order regardless of declaration order. Pinned columns span all header rows viarowSpan = depth + 1and are placed only in row 0. Group cells are built by a run-length scan over middle columns, collapsing contiguous same-id segments into a singleGroupHeaderCellwith the appropriatecolSpan.Development-time validation catches constraints TypeScript cannot express: duplicate column IDs (corrupt React reconciliation), inconsistent
groupPathdepths across columns, and non-contiguous same-id group segments within the same parent. In development, depth errors throw; in test, they log only.CSS (
gridSxStyles)borderSpacing: 0+border-separateinstead ofborder-collapse: collapse. Collapsed borders are shared between cells — this breaks sticky columns, which need independent borders on their own stacking layer to stay visible over scrolled content.borderLeftnotborderRightfor cell separators. In sticky contexts,borderRighton cell N is painted over by cell N+1's background;borderLeftis owned by the cell's own layer.borderTopon non-first rows rather thanborderBottomon non-last rows. Blink composites sticky layers differently when activated —borderBottomgets covered by the next row's background;borderTopis always visible.grid-pin-rowspanclass.Sticky header offsets (
useStickyHeaderOffsets)A new hook measures each header row's rendered height with
ResizeObserver(falling back towindow.resize) and writes the cumulative top offset back onto rows 2+, correcting MUI'sstickyHeaderbehaviour which setstop: 0on every row.Pin + indexing support
Indexing columns (row selector, row indices) are now represented as synthetic left-pinned
ColumnTemplates prepended toallColumnsForHeaderbeforebuildHeaderRowsis called. Their indices align directly with TanStack's header array, removing thetsOffsetaddition from the leaf callback entirely. InforEachCell, cells atindex < tsOffsetreturnpin: 'left'with the correct fixed width soMuiTableRow's existing offset accumulation handles them without special cases.What it supports
Test plan
buildHeaderRowsunit tests cover flat, depth-1, depth-2, pin-only, and mixed layoutscomputePinOffsetsunit tests cover left/right accumulation for single, multi, and empty inputsTableintegration tests cover flat regression, grouped+pinned+scroll, pin+indexing (row selector), pin+indexing (indices), and sort UI placement