Replies: 1 comment
-
|
Here's our full |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Context
We're using
Virtualizerwith a customTableLayoutsubclass insideResizableTableContainerto build a virtualized, resizable table with both left-sticky and right-sticky columns (e.g., a frozen checkbox + name on the left, and an actions menu pinned to the right edge).We've got it working, but the solution required several workarounds that feel like they'd benefit from first-class support. Sharing our approach here in case it's useful to others or to discuss whether any of this could be built into the library.
What we needed
position: stickyon cells can reference the table scroll container, not an intermediate wrapperWhat we did
1. Custom
TableLayoutsubclassWe subclass
TableLayoutand override:isStickyColumn(node)— the base always returnsfalse. We check the node's key (or look up the column by index for body cells) against a set of sticky column keys passed vialayoutOptions.buildBody,buildRow,buildHeaderRow,buildTableHeader— we setlayoutInfo.allowOverflow = trueon each result. Without this, the VirtualizerItem wrappers getoverflow: hidden, which creates scroll containers that trapposition: stickyinside them. Sticky cells can't reach the table's scroll container.2. Right-sticky via CSS (
position: sticky; right: 0)This was the hardest part. The Virtualizer only supports left-based sticky positioning (
position: sticky; left: Xon VirtualizerItem wrappers). For left-sticky columns this works perfectly. But for right-sticky,left: Xwhere X =viewportWidth - columnWidthbreaks when content is wider than the viewport — the column appears in the middle of the content rather than at the far right.The fundamental problem: non-sticky VirtualizerItem wrappers use
position: absolute(out of flow), so the right-sticky wrapper's inline-flow position ends up immediately after the left-sticky columns, not at the far-right of the row.Our solution: Override
[role="row"]to usedisplay: flex. This makes all VirtualizerItem cell wrappers into flex items. Absolute-positioned (non-sticky) items are unaffected. Sticky items participate in flex layout. We then use CSS on the right-sticky wrapper:margin-left: autoin flex pushes the element to the row's far-right edge — beyond the viewport when there's horizontal scroll.position: sticky; right: 0then pins it to the viewport's right edge. This also fixes the inline-block baseline gap (4px) that otherwise requiresline-height: 0on rows.3.
isStickyColumnnode resolution for body cellsFor header cells,
node.keydirectly matches the column key. For body cells,node.keyis a generated composite key. We fall back to looking up the column bynode.colIndex ?? node.indexfrom the virtualizer's collection. This works but feels fragile — we've seen intermittent cases where the column index lookup fails for body cells, causing sticky columns to be virtualized away.What would help from React Aria
Right-sticky column support in
TableLayout— astickyColumndirection option (left/right) or astickyColumnSide(node)override that returns"left" | "right", so the Virtualizer can setright: 0instead ofleft: Xon the wrapper.allowOverflowdefault for table sections — or a layout option to control this. Currently everybuildBody/buildRow/buildHeaderRow/buildTableHeaderoverride exists solely to setallowOverflow = true. Without it, sticky columns are trapped inside their parent wrappers.Stable column identification in
isStickyColumn— the node passed for body cells doesn't directly expose the column key. Anode.columnKeyor similar property would make the sticky check reliable without index-based lookups.Content-aware column sizing —
ResizableTableContainerdistributes widths via a flex-like algorithm (static pixels +frunits) with no content measurement. In non-virtualized tables,table-layout: autogrows columns to fit content. Awidth: "auto"orwidth: "fit-content"option that measures the rendered column content and feeds it back as the column width would be very useful.Questions
display: flexon rows approach safe long-term, or could it break with future Virtualizer changes?Beta Was this translation helpful? Give feedback.
All reactions