feat: upgrade TanStack Table to v9 with faster rendering and multi-range cell selection - #1920
feat: upgrade TanStack Table to v9 with faster rendering and multi-range cell selection#1920paustint wants to merge 1 commit into
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Upgrades Jetstream’s internal grid implementation from TanStack Table v8 to v9, introducing a feature-registry based setup, store/atom-driven fine-grained rendering, and new spreadsheet-style multi-range cell selection while keeping the external DataTable/DataTree APIs largely stable.
Changes:
- Upgrade
@tanstack/react-tableto v9 and introduce a centralizedjetstreamTableFeaturesregistry to control bundled features. - Refactor grid state management to leverage TanStack v9 store/atoms for finer-grained re-renders (selection/expanded/cellSelection, resize handle “islands”, memoized header).
- Add multi-range (Ctrl/Cmd) cell selection + updated copy/paste/clear behavior and migrate row shift-range selection to v9’s built-in handler.
Reviewed changes
Copilot reviewed 49 out of 50 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Locks TanStack v9 packages and new store dependencies. |
| package.json | Upgrades @tanstack/react-table to ^9.0.0 and adds @tanstack/react-store. |
| libs/ui/src/lib/data-table/PreviewChangesModal.tsx | Fixes copy/export behavior for status/error fields and empty display values; adds context menu copy. |
| libs/ui/src/lib/data-table/gridExport.ts | Tightens generics (T extends object) for v9 type compatibility. |
| libs/ui/src/lib/data-table/grid/selection/grid-selection.ts | Adds a facade around v9 cellSelectionFeature (bounds, spans, edges, active range). |
| libs/ui/src/lib/data-table/grid/renderers/CellRenderers.tsx | Ensures error column copy returns status; routes row shift-range selection through v9 handler. |
| libs/ui/src/lib/data-table/grid/rdg-compat.ts | Updates rdg-compat types to v9 generics and extends object constraints. |
| libs/ui/src/lib/data-table/grid/keyboard/useGridKeyboardNavigation.ts | Implements multi-range cell selection, range copy behavior, and Escape collapse semantics. |
| libs/ui/src/lib/data-table/grid/grid-types.ts | Introduces TanStack v9 type aliases + GridRowHandle variance-safe escape hatch and module augmentation updates. |
| libs/ui/src/lib/data-table/grid/grid-row-utils.ts | Removes hand-rolled row range selection helper; updates types for v9. |
| libs/ui/src/lib/data-table/grid/grid-paste.ts | Updates paste target computation types for v9 table/row/column aliases. |
| libs/ui/src/lib/data-table/grid/grid-filters.ts | Extends SET filter value computation to traverse tree rows via getSubRows. |
| libs/ui/src/lib/data-table/grid/grid-features.ts | Central v9 feature registration + row model factories + sortFns registry. |
| libs/ui/src/lib/data-table/grid/grid-context.tsx | Updates runtime context to v9 table alias and adds row-model input selector utility. |
| libs/ui/src/lib/data-table/grid/grid-column-utils.tsx | Tightens generic constraints for v9 row typing (T extends object). |
| libs/ui/src/lib/data-table/grid/filterFns.ts | Ports filter functions to v9 aliases (TanstackFilterFn, TanstackRow). |
| libs/ui/src/lib/data-table/grid/editors/EditorHost.tsx | Updates table typing for v9 (TanstackTable) and extends object generics. |
| libs/ui/src/lib/data-table/grid/editors/CellEditors.tsx | Tightens editor generics (TRow extends object) and minor formatting. |
| libs/ui/src/lib/data-table/grid/DataTableV2.tsx | Adds enableCellSelection prop plumbed into the v9 grid core. |
| libs/ui/src/lib/data-table/grid/data-table-grid.css | Adds multi-range selection borders and adjusts frozen divider/resize handle focus clipping. |
| libs/ui/src/lib/data-table/grid/core/useJetstreamTable.ts | Migrates to useTable + feature registry; moves selection/expanded/cellSelection into atoms; stable proxy facade. |
| libs/ui/src/lib/data-table/grid/components/HeaderCell.tsx | Adds fine-grained subscriptions for sort state, select-all checkbox, and resize-handle drag island. |
| libs/ui/src/lib/data-table/grid/components/GridSummaryRow.tsx | Updates to v9 column typing alias. |
| libs/ui/src/lib/data-table/grid/components/GridRow.tsx | Subscribes per-row selection via atom; switches range highlighting to span/edge model. |
| libs/ui/src/lib/data-table/grid/components/GridHeader.tsx | Memoizes header block and narrows active cell to sticky region to avoid re-renders on body navigation. |
| libs/ui/src/lib/data-table/grid/components/GridGroupRow.tsx | Subscribes group rows to rowSelection atom for correct descendant selection visuals. |
| libs/ui/src/lib/data-table/grid/components/GridContainer.tsx | Adds cell selection bounds plumbing, multi-range copy/paste/clear targeting, and row-model subscriptions. |
| libs/ui/src/lib/data-table/grid/components/GridCell.tsx | Uses edge-bitmask range highlighting and forwards ctrl/meta state for multi-range selection. |
| libs/ui/src/lib/data-table/grid/components/GridBody.tsx | Subscribes to row-model inputs for atom-driven expanded changes; computes per-row selection spans. |
| libs/ui/src/lib/data-table/grid/components/grid-layout.ts | Updates frozen/layout helpers to v9 column alias. |
| libs/ui/src/lib/data-table/grid/buildColumnDefs.ts | Ports to v9 column def alias and enables cell selection on data columns only. |
| libs/ui/src/lib/data-table/grid/tests/selection-expansion-atoms.spec.tsx | Adds tests for atom-backed selection/expanded dual controlled/internal behavior (StrictMode-safe). |
| libs/ui/src/lib/data-table/grid/tests/row-range-selection.spec.ts | Adds tests for v9 shift-range row selection via getToggleSelectedHandler. |
| libs/ui/src/lib/data-table/grid/tests/grid-selection.spec.tsx | Adds tests for multi-range cell selection facade and span/edge helpers. |
| libs/ui/src/lib/data-table/grid/tests/grid-row-utils.spec.ts | Removes tests for deleted hand-rolled selectRowRange. |
| libs/ui/src/lib/data-table/grid/tests/grid-filters.spec.ts | Adds test coverage for getSubRows traversal in SET filter value computation. |
| libs/ui/src/lib/data-table/DataTree.tsx | Tightens generics to extends object to match v9 constraints. |
| libs/ui/src/lib/data-table/DataTable.tsx | Adds enableCellSelection to the public DataTable surface and tightens generic constraints. |
| libs/ui/src/lib/data-table/tests/PreviewChangesModal.spec.ts | Updates tests for blank-vs-em-dash behavior and error column copy value plumbing. |
| libs/shared/ui-core/src/app/GridDownloadButton.tsx | Tightens export button generics to extends object. |
| libs/features/manage-permissions/src/utils/permission-manager-table-utils.tsx | Marks checkbox columns editable for paste/clear and adds paste application helper for permissions tables. |
| libs/features/manage-permissions/src/utils/tests/permission-manager-table-label-column.spec.ts | Updates helper generics to extends object and aligns with SET filter changes. |
| libs/features/manage-permissions/src/ManagePermissionsEditorTabVisibilityTable.tsx | Wires grid paste into permission checkbox updates. |
| libs/features/manage-permissions/src/ManagePermissionsEditorSystemPermissionTable.tsx | Wires grid paste into permission checkbox updates. |
| libs/features/manage-permissions/src/ManagePermissionsEditorObjectTable.tsx | Wires grid paste into permission checkbox updates. |
| libs/features/manage-permissions/src/ManagePermissionsEditorFieldTable.tsx | Wires grid paste into permission checkbox updates. |
| libs/features/deploy/src/utils/deploy-metadata.utils.tsx | Fixes group counts to exclude placeholder “No metadata found” rows. |
| libs/features/automation-control/src/useAutomationControlData.ts | Fixes Reset to restore activeVersionNumber for flow/process builder rows. |
| libs/features/automation-control/src/AutomationControlEditorTable.tsx | Adds paste support for Active checkbox column and marks paste-eligible rows via editable. |
| libs/features/automation-control/src/automation-control-table-renderers.tsx | Centers Active checkbox and hides label for better grid rendering/interaction. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
53520a4 to
597769c
Compare
…nge cell selection Upgrade @tanstack/react-table 8.21.3 → 9.x (pinned ^9.0.0; 9.1.x blocked by the 3-day minimumReleaseAge gate until ~Aug 10). All TanStack usage is confined to the libs/ui grid, so feature code is untouched except where noted. ## Core port - useReactTable → useTable with an explicit tableFeatures registry (grid-features.ts); unused features (pagination, pinning, faceting) are now tree-shaken out of the bundle - Central Tanstack* type aliases bake in the new TFeatures generic; module augmentation updated; RowData constraint contained via `extends object` - table.getState() → table.store.state; columnSizingInfo → columnResizing - Stable table facade: v9 returns a new wrapper per state change, so useJetstreamTable exposes a stable Proxy to preserve the "one table identity" contract for context memos and effects - GridRowHandle: variance-safe subset type for the tanstackRow escape hatch (v9 rows are invariant in their data generic) - Adopted v9 built-in shift-click row range selection (replaces hand-rolled selectRowRange); bare-checkbox tables gain shift-click; select-all indeterminate updated for v9's changed getIsSomeRowsSelected semantics ## Fine-grained rendering (v9 store/atoms) - Column-resize drag re-renders only the dragged header's handle island - rowSelection/expanded moved to external atoms (dual controlled/internal mode preserved; consumer callbacks fire exactly once under StrictMode) - A selection toggle re-renders only the affected row + select-all island; GridHeader is memoized and skips re-renders during typing/navigation ## Cell range selection (new) - Spreadsheet-style multi-range selection via v9 cellSelectionFeature: Ctrl/Cmd+click adds/subtracts rectangles, ranges survive sort/filter/reorder, Escape collapses, multi-range copy, Delete/revert across all ranges - All v9 selection API access confined to a grid-selection facade ## Fixes found while testing - Preview Changes: Warnings/Error column copied blank (value lived on row.status); added copy context menu; empty cells copy blank (em-dash is now render-only); Status column copies its compact state - Error popovers restored to the strong red header (SLDS 2 Cosmos restyled the error variant to a pink container) - Frozen-column divider and header resize handle no longer clip focus/selection ring edges - Automation Control: SET filter popover was empty for tree tables (computeFilterSetValues now traverses getSubRows); Reset left flows marked dirty (activeVersionNumber is now restored); checkbox centered and toggles only on the checkbox itself - Deploy: group counts no longer include the "No metadata found" placeholder - Paste (and Delete-to-clear) implemented for boolean checkbox tables: permission manager (all four editors) and Automation Control's Active column, routed through the same handlers as checkbox clicks
597769c to
44bf10f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 49 out of 50 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (3)
libs/ui/src/lib/data-table/grid/selection/grid-selection.ts:155
- The docstring for
getCellRangeEdgessays the bitmask is only top/right/bottom/left (1/2/4/8), but the implementation also sets bit 16 to represent the selected fill. This mismatch can cause misuse when adding new range-related UI logic.
libs/ui/src/lib/data-table/grid/renderers/CellRenderers.tsx:422 SelectFormatterfabricates an event object forgetToggleSelectedHandler(), but it does not includenativeEvent.shiftKeyeven though the comment notes TanStack may read it. If TanStack checksevent.nativeEvent.shiftKey(common in their handlers), Shift-range selection will silently stop working for the SLDS label-driven checkbox path.
libs/features/automation-control/src/AutomationControlEditorTable.tsx:128handlePastetraverses the tree viagetSubRows(row, 0)for every node. SincegetSubRowsis explicitly typed as(row, index), hard-coding0can break consumers that depend on the index (and it’s inconsistent with other tree traversals in this PR that propagate the real index).
const visit = (row: TableRowOrItemOrChild) => {
rowByKey.set(row.key, row);
getSubRows(row, 0)?.forEach(visit);
};
rows.forEach(visit);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 49 out of 50 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (1)
libs/features/manage-permissions/src/utils/permission-manager-table-utils.tsx:1695
columnKey.lastIndexOf('-')can return -1 (or point at the first/last char). In that caseslice(0, -1)/slice(0)mis-parses the key and can apply a paste to the wrong permission id/action (or accidentally treat almost the whole string as a permission id). Add a guard to skip malformed keys before slicing.
const separatorIndex = columnKey.lastIndexOf('-');
const permissionId = columnKey.slice(0, separatorIndex);
const actionKey = columnKey.slice(separatorIndex + 1);
const row = updatedRows[rowIndex];
Upgrade @tanstack/react-table 8.21.3 → 9.x (pinned ^9.0.0; 9.1.x blocked by the 3-day minimumReleaseAge gate until ~Aug 10). All TanStack usage is confined to the libs/ui grid, so feature code is untouched except where noted.
Core port
extends objectFine-grained rendering (v9 store/atoms)
Cell range selection (new)
Fixes found while testing