@trackunit/react-table 2.1.71 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -1402,6 +1402,12 @@ const Table = ({ rowHeight = 50, loading = false, hideFooter = false, style, ...
1402
1402
  count: props.getRowModel().rows.length,
1403
1403
  estimateSize: () => rowHeight, // TODO: we should probably move from rowHeight -> estimateSize callback api to match Tanstack Virtual
1404
1404
  onTopItemChange: props.onTopItemChange,
1405
+ // Must agree with the `key={row.id}` used to render rows below, so the
1406
+ // virtualizer's `elementsCache` and React's reconciliation key rows the
1407
+ // same way. Without this, sorting/filtering/backward-pagination shifts
1408
+ // that keep a `<tr>` mounted while its window index changes cause
1409
+ // `directDomUpdates` to write transforms to the wrong cached element.
1410
+ getItemKey: index => props.getRowModel().rows[index]?.id ?? index,
1405
1411
  });
1406
1412
  const visibleColumns = react.useMemo(() => props.getAllColumns().filter(column => column.getIsVisible()), [props]);
1407
1413
  const visibleColumnsCount = visibleColumns.length;
@@ -1507,32 +1513,35 @@ const Table = ({ rowHeight = 50, loading = false, hideFooter = false, style, ...
1507
1513
  : null, jsxRuntime.jsx(ColumnActions, { getColumn: props.getColumn, header: header, setSorting: props.setSorting, visibleColumnsCount: visibleColumnsCount })] })] })),
1508
1514
  !header.column.columnDef.meta?.shouldGrow && header.column.getCanResize() ? (jsxRuntime.jsx(reactTableBaseComponents.ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null));
1509
1515
  }) }, headerGroup.id));
1510
- }) }), hasResults ? (jsxRuntime.jsx(reactTableBaseComponents.Tbody, { className: "text-sm font-normal", style: {
1511
- height: `${virtualizer.getTotalSize()}px`,
1512
- flexGrow: 1,
1513
- }, children: virtualizer.getVirtualItems().map((virtualRow, index) => {
1516
+ }) }), hasResults ? (jsxRuntime.jsx(reactTableBaseComponents.Tbody, { className: "relative text-sm font-normal contain-layout", ref: virtualizer.containerRef, children: virtualizer.getVirtualItems().map(virtualRow => {
1514
1517
  const row = props.getRowModel().rows[virtualRow.index];
1515
1518
  if (!row) {
1516
1519
  return null;
1517
1520
  }
1518
1521
  else {
1519
- return (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: tailwindMerge.twMerge("row-focus group", reactComponents.cvaInteractableItem({
1522
+ return (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: tailwindMerge.twMerge(
1523
+ // `absolute left-0 top-0 w-full` anchors the row so the
1524
+ // virtualizer can position it via a transform (directDomUpdates).
1525
+ "row-focus group absolute left-0 top-0 w-full", reactComponents.cvaInteractableItem({
1520
1526
  cursor: (!!props.onRowClick || row.getCanSelect()) &&
1521
1527
  (props.isRowClickable ? props.isRowClickable(row.original) : true)
1522
1528
  ? "pointer"
1523
1529
  : "default",
1524
1530
  selection: row.getIsSelected() ? "selected" : "auto",
1525
1531
  focus: "unfocused",
1526
- })), "data-testid": `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
1532
+ })), "data-index": virtualRow.index, "data-testid": `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
1527
1533
  if (props.onRowClick) {
1528
1534
  props.onRowClick(row);
1529
1535
  }
1530
1536
  else if (row.getCanSelect()) {
1531
1537
  row.toggleSelected();
1532
1538
  }
1533
- }, style: {
1534
- height: `${virtualRow.size}px`,
1535
- transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
1539
+ },
1540
+ // The virtualizer writes the row transform (directDomUpdates); the ref
1541
+ // registers the row for positioning and dynamic height measurement.
1542
+ // Only the main-axis size (height) is set here, never the position.
1543
+ ref: virtualizer.measureElement, style: {
1544
+ height: `${rowHeight}px`,
1536
1545
  }, children: row.getVisibleCells().map(cell => {
1537
1546
  // Processing the cell identifier:
1538
1547
  // 1. Remove the segment enclosed by "___" (e.g., "___Asset___").
package/index.esm.js CHANGED
@@ -1401,6 +1401,12 @@ const Table = ({ rowHeight = 50, loading = false, hideFooter = false, style, ...
1401
1401
  count: props.getRowModel().rows.length,
1402
1402
  estimateSize: () => rowHeight, // TODO: we should probably move from rowHeight -> estimateSize callback api to match Tanstack Virtual
1403
1403
  onTopItemChange: props.onTopItemChange,
1404
+ // Must agree with the `key={row.id}` used to render rows below, so the
1405
+ // virtualizer's `elementsCache` and React's reconciliation key rows the
1406
+ // same way. Without this, sorting/filtering/backward-pagination shifts
1407
+ // that keep a `<tr>` mounted while its window index changes cause
1408
+ // `directDomUpdates` to write transforms to the wrong cached element.
1409
+ getItemKey: index => props.getRowModel().rows[index]?.id ?? index,
1404
1410
  });
1405
1411
  const visibleColumns = useMemo(() => props.getAllColumns().filter(column => column.getIsVisible()), [props]);
1406
1412
  const visibleColumnsCount = visibleColumns.length;
@@ -1506,32 +1512,35 @@ const Table = ({ rowHeight = 50, loading = false, hideFooter = false, style, ...
1506
1512
  : null, jsx(ColumnActions, { getColumn: props.getColumn, header: header, setSorting: props.setSorting, visibleColumnsCount: visibleColumnsCount })] })] })),
1507
1513
  !header.column.columnDef.meta?.shouldGrow && header.column.getCanResize() ? (jsx(ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null));
1508
1514
  }) }, headerGroup.id));
1509
- }) }), hasResults ? (jsx(Tbody, { className: "text-sm font-normal", style: {
1510
- height: `${virtualizer.getTotalSize()}px`,
1511
- flexGrow: 1,
1512
- }, children: virtualizer.getVirtualItems().map((virtualRow, index) => {
1515
+ }) }), hasResults ? (jsx(Tbody, { className: "relative text-sm font-normal contain-layout", ref: virtualizer.containerRef, children: virtualizer.getVirtualItems().map(virtualRow => {
1513
1516
  const row = props.getRowModel().rows[virtualRow.index];
1514
1517
  if (!row) {
1515
1518
  return null;
1516
1519
  }
1517
1520
  else {
1518
- return (jsx(Tr, { className: twMerge("row-focus group", cvaInteractableItem({
1521
+ return (jsx(Tr, { className: twMerge(
1522
+ // `absolute left-0 top-0 w-full` anchors the row so the
1523
+ // virtualizer can position it via a transform (directDomUpdates).
1524
+ "row-focus group absolute left-0 top-0 w-full", cvaInteractableItem({
1519
1525
  cursor: (!!props.onRowClick || row.getCanSelect()) &&
1520
1526
  (props.isRowClickable ? props.isRowClickable(row.original) : true)
1521
1527
  ? "pointer"
1522
1528
  : "default",
1523
1529
  selection: row.getIsSelected() ? "selected" : "auto",
1524
1530
  focus: "unfocused",
1525
- })), "data-testid": `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
1531
+ })), "data-index": virtualRow.index, "data-testid": `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
1526
1532
  if (props.onRowClick) {
1527
1533
  props.onRowClick(row);
1528
1534
  }
1529
1535
  else if (row.getCanSelect()) {
1530
1536
  row.toggleSelected();
1531
1537
  }
1532
- }, style: {
1533
- height: `${virtualRow.size}px`,
1534
- transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
1538
+ },
1539
+ // The virtualizer writes the row transform (directDomUpdates); the ref
1540
+ // registers the row for positioning and dynamic height measurement.
1541
+ // Only the main-axis size (height) is set here, never the position.
1542
+ ref: virtualizer.measureElement, style: {
1543
+ height: `${rowHeight}px`,
1535
1544
  }, children: row.getVisibleCells().map(cell => {
1536
1545
  // Processing the cell identifier:
1537
1546
  // 1. Remove the segment enclosed by "___" (e.g., "___Asset___").
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-table",
3
- "version": "2.1.71",
3
+ "version": "2.2.0",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -11,15 +11,15 @@
11
11
  "react-dnd": "16.0.1",
12
12
  "react-dnd-html5-backend": "16.0.1",
13
13
  "tailwind-merge": "^2.0.0",
14
- "@trackunit/react-components": "2.1.65",
15
- "@trackunit/react-core-hooks": "1.17.74",
16
- "@trackunit/shared-utils": "1.15.61",
17
- "@trackunit/css-class-variance-utilities": "1.13.58",
18
- "@trackunit/ui-icons": "1.13.59",
19
- "@trackunit/react-table-base-components": "2.1.69",
20
- "@trackunit/react-form-components": "2.1.68",
21
- "@trackunit/i18n-library-translation": "2.0.63",
22
- "@trackunit/iris-app-runtime-core-api": "1.16.67",
14
+ "@trackunit/react-components": "2.2.0",
15
+ "@trackunit/react-core-hooks": "1.18.0",
16
+ "@trackunit/shared-utils": "1.15.62",
17
+ "@trackunit/css-class-variance-utilities": "1.13.59",
18
+ "@trackunit/ui-icons": "1.13.60",
19
+ "@trackunit/react-table-base-components": "2.2.0",
20
+ "@trackunit/react-form-components": "2.2.0",
21
+ "@trackunit/i18n-library-translation": "2.1.0",
22
+ "@trackunit/iris-app-runtime-core-api": "1.16.68",
23
23
  "zod": "^3.25.76"
24
24
  },
25
25
  "peerDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/table/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}