material-react-table 2.1.0 → 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/dist/index.d.ts +13 -4
- package/dist/index.esm.js +2360 -2325
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2393 -2355
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/src/body/MRT_TableBody.tsx +16 -123
- package/src/body/MRT_TableBodyCell.tsx +3 -3
- package/src/body/MRT_TableBodyRow.tsx +9 -5
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useMRT_ColumnVirtualizer.ts +125 -0
- package/src/hooks/useMRT_DisplayColumns.tsx +2 -0
- package/src/hooks/useMRT_RowVirtualizer.ts +64 -0
- package/src/hooks/useMRT_Rows.ts +94 -0
- package/src/table/MRT_Table.tsx +17 -107
package/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "2.
|
2
|
+
"version": "2.2.0",
|
3
3
|
"license": "MIT",
|
4
4
|
"name": "material-react-table",
|
5
5
|
"description": "A fully featured Material UI V5 implementation of TanStack React Table V8, written from the ground up in TypeScript.",
|
@@ -61,30 +61,30 @@
|
|
61
61
|
"storybook:dev": "storybook dev -p 6006"
|
62
62
|
},
|
63
63
|
"devDependencies": {
|
64
|
-
"@babel/core": "^7.23.
|
64
|
+
"@babel/core": "^7.23.7",
|
65
65
|
"@babel/preset-react": "^7.23.3",
|
66
|
-
"@emotion/react": "^11.11.
|
66
|
+
"@emotion/react": "^11.11.3",
|
67
67
|
"@emotion/styled": "^11.11.0",
|
68
68
|
"@faker-js/faker": "^8.3.1",
|
69
|
-
"@mui/icons-material": "^5.15.
|
70
|
-
"@mui/material": "^5.15.
|
71
|
-
"@mui/x-date-pickers": "^6.18.
|
69
|
+
"@mui/icons-material": "^5.15.2",
|
70
|
+
"@mui/material": "^5.15.2",
|
71
|
+
"@mui/x-date-pickers": "^6.18.6",
|
72
72
|
"@rollup/plugin-typescript": "^11.1.5",
|
73
73
|
"@size-limit/preset-small-lib": "^11.0.1",
|
74
|
-
"@storybook/addon-a11y": "^7.6.
|
75
|
-
"@storybook/addon-essentials": "^7.6.
|
76
|
-
"@storybook/addon-interactions": "^7.6.
|
77
|
-
"@storybook/addon-links": "^7.6.
|
78
|
-
"@storybook/addon-storysource": "^7.6.
|
79
|
-
"@storybook/blocks": "^7.6.
|
80
|
-
"@storybook/react": "^7.6.
|
81
|
-
"@storybook/react-vite": "^7.6.
|
74
|
+
"@storybook/addon-a11y": "^7.6.7",
|
75
|
+
"@storybook/addon-essentials": "^7.6.7",
|
76
|
+
"@storybook/addon-interactions": "^7.6.7",
|
77
|
+
"@storybook/addon-links": "^7.6.7",
|
78
|
+
"@storybook/addon-storysource": "^7.6.7",
|
79
|
+
"@storybook/blocks": "^7.6.7",
|
80
|
+
"@storybook/react": "^7.6.7",
|
81
|
+
"@storybook/react-vite": "^7.6.7",
|
82
82
|
"@storybook/testing-library": "^0.2.2",
|
83
|
-
"@types/node": "^20.10.
|
84
|
-
"@types/react": "^18.2.
|
83
|
+
"@types/node": "^20.10.6",
|
84
|
+
"@types/react": "^18.2.46",
|
85
85
|
"@types/react-dom": "^18.2.18",
|
86
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
87
|
-
"@typescript-eslint/parser": "^6.
|
86
|
+
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
87
|
+
"@typescript-eslint/parser": "^6.17.0",
|
88
88
|
"@vitejs/plugin-react": "^4.2.1",
|
89
89
|
"eslint": "^8.56.0",
|
90
90
|
"eslint-plugin-mui-path-imports": "^0.0.15",
|
@@ -97,7 +97,7 @@
|
|
97
97
|
"rollup-plugin-dts": "^6.1.0",
|
98
98
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
99
99
|
"size-limit": "^11.0.1",
|
100
|
-
"storybook": "^7.6.
|
100
|
+
"storybook": "^7.6.7",
|
101
101
|
"storybook-dark-mode": "^3.0.3",
|
102
102
|
"tslib": "^2.6.2",
|
103
103
|
"typescript": "^5.3.3",
|
@@ -1,19 +1,11 @@
|
|
1
|
-
import { memo,
|
2
|
-
import {
|
3
|
-
type Range,
|
4
|
-
type VirtualItem,
|
5
|
-
type Virtualizer,
|
6
|
-
useVirtualizer,
|
7
|
-
} from '@tanstack/react-virtual';
|
1
|
+
import { memo, useMemo } from 'react';
|
2
|
+
import { type VirtualItem, type Virtualizer } from '@tanstack/react-virtual';
|
8
3
|
import TableBody, { type TableBodyProps } from '@mui/material/TableBody';
|
9
4
|
import Typography from '@mui/material/Typography';
|
10
5
|
import { MRT_TableBodyRow, Memo_MRT_TableBodyRow } from './MRT_TableBodyRow';
|
11
|
-
import {
|
12
|
-
|
13
|
-
|
14
|
-
parseFromValuesOrFunc,
|
15
|
-
} from '../column.utils';
|
16
|
-
import { rankGlobalFuzzy } from '../sortingFns';
|
6
|
+
import { parseFromValuesOrFunc } from '../column.utils';
|
7
|
+
import { useMRT_RowVirtualizer } from '../hooks';
|
8
|
+
import { useMRT_Rows } from '../hooks/useMRT_Rows';
|
17
9
|
import {
|
18
10
|
type MRT_Row,
|
19
11
|
type MRT_RowData,
|
@@ -38,56 +30,30 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
38
30
|
}: Props<TData>) => {
|
39
31
|
const {
|
40
32
|
getBottomRows,
|
41
|
-
getCenterRows,
|
42
33
|
getIsSomeRowsPinned,
|
43
|
-
getPrePaginationRowModel,
|
44
34
|
getRowModel,
|
45
35
|
getState,
|
46
36
|
getTopRows,
|
47
37
|
options: {
|
48
38
|
createDisplayMode,
|
49
|
-
enableGlobalFilterRankedResults,
|
50
|
-
enablePagination,
|
51
|
-
enableRowPinning,
|
52
|
-
enableRowVirtualization,
|
53
39
|
enableStickyFooter,
|
54
40
|
enableStickyHeader,
|
55
41
|
layoutMode,
|
56
42
|
localization,
|
57
|
-
manualExpanding,
|
58
|
-
manualFiltering,
|
59
|
-
manualGrouping,
|
60
|
-
manualPagination,
|
61
|
-
manualSorting,
|
62
43
|
memoMode,
|
63
44
|
muiTableBodyProps,
|
64
45
|
renderEmptyRowsFallback,
|
65
46
|
rowPinningDisplayMode,
|
66
|
-
rowVirtualizerInstanceRef,
|
67
|
-
rowVirtualizerOptions,
|
68
47
|
},
|
69
|
-
refs: {
|
48
|
+
refs: { tableFooterRef, tableHeadRef, tablePaperRef },
|
70
49
|
} = table;
|
71
|
-
const {
|
72
|
-
|
73
|
-
creatingRow,
|
74
|
-
density,
|
75
|
-
draggingRow,
|
76
|
-
expanded,
|
77
|
-
globalFilter,
|
78
|
-
isFullScreen,
|
79
|
-
pagination,
|
80
|
-
rowPinning,
|
81
|
-
sorting,
|
82
|
-
} = getState();
|
50
|
+
const { columnFilters, creatingRow, globalFilter, isFullScreen, rowPinning } =
|
51
|
+
getState();
|
83
52
|
|
84
53
|
const tableBodyProps = {
|
85
54
|
...parseFromValuesOrFunc(muiTableBodyProps, { table }),
|
86
55
|
...rest,
|
87
56
|
};
|
88
|
-
const rowVirtualizerProps = parseFromValuesOrFunc(rowVirtualizerOptions, {
|
89
|
-
table,
|
90
|
-
});
|
91
57
|
|
92
58
|
const tableHeadHeight =
|
93
59
|
((enableStickyHeader || isFullScreen) &&
|
@@ -96,23 +62,6 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
96
62
|
const tableFooterHeight =
|
97
63
|
(enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
|
98
64
|
|
99
|
-
const shouldRankRows = useMemo(
|
100
|
-
() =>
|
101
|
-
getCanRankRows(table) &&
|
102
|
-
!Object.values(sorting).some(Boolean) &&
|
103
|
-
globalFilter,
|
104
|
-
[
|
105
|
-
enableGlobalFilterRankedResults,
|
106
|
-
expanded,
|
107
|
-
globalFilter,
|
108
|
-
manualExpanding,
|
109
|
-
manualFiltering,
|
110
|
-
manualGrouping,
|
111
|
-
manualSorting,
|
112
|
-
sorting,
|
113
|
-
],
|
114
|
-
);
|
115
|
-
|
116
65
|
const pinnedRowIds = useMemo(
|
117
66
|
() =>
|
118
67
|
getRowModel()
|
@@ -121,66 +70,9 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
121
70
|
[rowPinning, table.getRowModel().rows],
|
122
71
|
);
|
123
72
|
|
124
|
-
const rows =
|
125
|
-
let rows: MRT_Row<TData>[] = [];
|
126
|
-
if (!shouldRankRows) {
|
127
|
-
rows =
|
128
|
-
!enableRowPinning || rowPinningDisplayMode?.includes('sticky')
|
129
|
-
? getRowModel().rows
|
130
|
-
: getCenterRows();
|
131
|
-
} else {
|
132
|
-
rows = getPrePaginationRowModel().rows.sort((a, b) =>
|
133
|
-
rankGlobalFuzzy(a, b),
|
134
|
-
);
|
135
|
-
if (enablePagination && !manualPagination) {
|
136
|
-
const start = pagination.pageIndex * pagination.pageSize;
|
137
|
-
rows = rows.slice(start, start + pagination.pageSize);
|
138
|
-
}
|
139
|
-
}
|
140
|
-
if (enableRowPinning && rowPinningDisplayMode?.includes('sticky')) {
|
141
|
-
rows = [
|
142
|
-
...getTopRows().filter((row) => !pinnedRowIds.includes(row.id)),
|
143
|
-
...rows,
|
144
|
-
...getBottomRows().filter((row) => !pinnedRowIds.includes(row.id)),
|
145
|
-
];
|
146
|
-
}
|
147
|
-
|
148
|
-
return rows;
|
149
|
-
}, [
|
150
|
-
shouldRankRows,
|
151
|
-
shouldRankRows ? getPrePaginationRowModel().rows : getRowModel().rows,
|
152
|
-
pagination.pageIndex,
|
153
|
-
pagination.pageSize,
|
154
|
-
rowPinning,
|
155
|
-
]);
|
156
|
-
|
157
|
-
const rowVirtualizer:
|
158
|
-
| Virtualizer<HTMLDivElement, HTMLTableRowElement>
|
159
|
-
| undefined = enableRowVirtualization
|
160
|
-
? useVirtualizer({
|
161
|
-
count: rows.length,
|
162
|
-
estimateSize: () =>
|
163
|
-
density === 'compact' ? 37 : density === 'comfortable' ? 58 : 73,
|
164
|
-
getScrollElement: () => tableContainerRef.current,
|
165
|
-
measureElement:
|
166
|
-
typeof window !== 'undefined' &&
|
167
|
-
navigator.userAgent.indexOf('Firefox') === -1
|
168
|
-
? (element) => element?.getBoundingClientRect().height
|
169
|
-
: undefined,
|
170
|
-
overscan: 4,
|
171
|
-
rangeExtractor: useCallback(
|
172
|
-
(range: Range) => {
|
173
|
-
return extraIndexRangeExtractor(range, draggingRow?.index ?? 0);
|
174
|
-
},
|
175
|
-
[draggingRow],
|
176
|
-
),
|
177
|
-
...rowVirtualizerProps,
|
178
|
-
})
|
179
|
-
: undefined;
|
73
|
+
const rows = useMRT_Rows(table);
|
180
74
|
|
181
|
-
|
182
|
-
rowVirtualizerInstanceRef.current = rowVirtualizer;
|
183
|
-
}
|
75
|
+
const rowVirtualizer = useMRT_RowVirtualizer(table);
|
184
76
|
|
185
77
|
const virtualRows = rowVirtualizer
|
186
78
|
? rowVirtualizer.getVirtualItems()
|
@@ -227,9 +119,10 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
227
119
|
{...tableBodyProps}
|
228
120
|
sx={(theme) => ({
|
229
121
|
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
230
|
-
height:
|
231
|
-
|
232
|
-
|
122
|
+
height:
|
123
|
+
rowVirtualizer
|
124
|
+
? `${rowVirtualizer.getTotalSize()}px`
|
125
|
+
: undefined,
|
233
126
|
minHeight: !rows.length ? '100px' : undefined,
|
234
127
|
position: 'relative',
|
235
128
|
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
|
@@ -289,11 +182,11 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
289
182
|
};
|
290
183
|
return memoMode === 'rows' ? (
|
291
184
|
<Memo_MRT_TableBodyRow
|
292
|
-
key={`${row.id}
|
185
|
+
key={`${row.id}-${row.index}`}
|
293
186
|
{...props}
|
294
187
|
/>
|
295
188
|
) : (
|
296
|
-
<MRT_TableBodyRow key={`${row.id}
|
189
|
+
<MRT_TableBodyRow key={`${row.id}-${row.index}`} {...props} />
|
297
190
|
);
|
298
191
|
})}
|
299
192
|
</>
|
@@ -33,7 +33,7 @@ interface Props<TData extends MRT_RowData> extends TableCellProps {
|
|
33
33
|
rowIndex: number;
|
34
34
|
rowRef: RefObject<HTMLTableRowElement>;
|
35
35
|
table: MRT_TableInstance<TData>;
|
36
|
-
|
36
|
+
virtualColumnIndex?: number;
|
37
37
|
}
|
38
38
|
|
39
39
|
export const MRT_TableBodyCell = <TData extends MRT_RowData>({
|
@@ -43,7 +43,7 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
|
|
43
43
|
rowIndex,
|
44
44
|
rowRef,
|
45
45
|
table,
|
46
|
-
|
46
|
+
virtualColumnIndex,
|
47
47
|
...rest
|
48
48
|
}: Props<TData>) => {
|
49
49
|
const theme = useTheme();
|
@@ -212,7 +212,7 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
|
|
212
212
|
|
213
213
|
return (
|
214
214
|
<TableCell
|
215
|
-
data-index={
|
215
|
+
data-index={virtualColumnIndex}
|
216
216
|
ref={(node: HTMLTableCellElement) => {
|
217
217
|
if (node) {
|
218
218
|
measureElement?.(node);
|
@@ -106,10 +106,14 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
|
|
106
106
|
|
107
107
|
const sx = parseFromValuesOrFunc(tableRowProps?.sx, theme as any);
|
108
108
|
|
109
|
-
const
|
109
|
+
const defaultRowHeight =
|
110
|
+
density === 'compact' ? 37 : density === 'comfortable' ? 53 : 69;
|
111
|
+
|
112
|
+
const customRowHeight =
|
110
113
|
// @ts-ignore
|
111
|
-
parseInt(tableRowProps?.style?.height ?? sx?.height, 10) ||
|
112
|
-
|
114
|
+
parseInt(tableRowProps?.style?.height ?? sx?.height, 10) || undefined;
|
115
|
+
|
116
|
+
const rowHeight = customRowHeight || defaultRowHeight;
|
113
117
|
|
114
118
|
const handleDragEnter = (_e: DragEvent) => {
|
115
119
|
if (enableRowOrdering && draggingRow) {
|
@@ -128,7 +132,7 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
|
|
128
132
|
return (
|
129
133
|
<>
|
130
134
|
<TableRow
|
131
|
-
data-index={
|
135
|
+
data-index={rowIndex}
|
132
136
|
data-pinned={!!isPinned || undefined}
|
133
137
|
data-selected={row.getIsSelected() || undefined}
|
134
138
|
onDragEnter={handleDragEnter}
|
@@ -142,7 +146,7 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
|
|
142
146
|
{...tableRowProps}
|
143
147
|
style={{
|
144
148
|
transform: virtualRow
|
145
|
-
? `translateY(${virtualRow
|
149
|
+
? `translateY(${virtualRow.start}px)`
|
146
150
|
: undefined,
|
147
151
|
...tableRowProps?.style,
|
148
152
|
}}
|
package/src/hooks/index.ts
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
export * from './useMRT_ColumnVirtualizer';
|
1
2
|
export * from './useMRT_DisplayColumns';
|
2
3
|
export * from './useMRT_Effects';
|
4
|
+
export * from './useMRT_RowVirtualizer';
|
5
|
+
export * from './useMRT_Rows';
|
3
6
|
export * from './useMRT_TableInstance';
|
4
7
|
export * from './useMRT_TableOptions';
|
@@ -0,0 +1,125 @@
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
2
|
+
import {
|
3
|
+
type Range,
|
4
|
+
type Virtualizer,
|
5
|
+
useVirtualizer,
|
6
|
+
} from '@tanstack/react-virtual';
|
7
|
+
import {
|
8
|
+
extraIndexRangeExtractor,
|
9
|
+
parseFromValuesOrFunc,
|
10
|
+
} from '../column.utils';
|
11
|
+
import { type MRT_RowData, type MRT_TableInstance } from '../types';
|
12
|
+
|
13
|
+
export const useMRT_ColumnVirtualizer = <
|
14
|
+
TData extends MRT_RowData,
|
15
|
+
TScrollElement extends Element | Window = HTMLDivElement,
|
16
|
+
TItemElement extends Element = HTMLTableCellElement,
|
17
|
+
>(
|
18
|
+
table: MRT_TableInstance<TData>,
|
19
|
+
):
|
20
|
+
| (Virtualizer<TScrollElement, TItemElement> & {
|
21
|
+
virtualPaddingLeft?: number;
|
22
|
+
virtualPaddingRight?: number;
|
23
|
+
})
|
24
|
+
| undefined => {
|
25
|
+
const {
|
26
|
+
getState,
|
27
|
+
options: {
|
28
|
+
columnVirtualizerInstanceRef,
|
29
|
+
columnVirtualizerOptions,
|
30
|
+
enableColumnPinning,
|
31
|
+
enableColumnVirtualization,
|
32
|
+
},
|
33
|
+
refs: { tableContainerRef },
|
34
|
+
} = table;
|
35
|
+
const { columnPinning, columnVisibility, draggingColumn } = getState();
|
36
|
+
|
37
|
+
const columnVirtualizerProps = parseFromValuesOrFunc(
|
38
|
+
columnVirtualizerOptions,
|
39
|
+
{
|
40
|
+
table,
|
41
|
+
},
|
42
|
+
);
|
43
|
+
|
44
|
+
const [leftPinnedIndexes, rightPinnedIndexes] = useMemo(
|
45
|
+
() =>
|
46
|
+
enableColumnVirtualization && enableColumnPinning
|
47
|
+
? [
|
48
|
+
table.getLeftLeafColumns().map((c) => c.getPinnedIndex()),
|
49
|
+
table
|
50
|
+
.getRightLeafColumns()
|
51
|
+
.map(
|
52
|
+
(c) =>
|
53
|
+
table.getVisibleLeafColumns().length - c.getPinnedIndex() - 1,
|
54
|
+
),
|
55
|
+
]
|
56
|
+
: [[], []],
|
57
|
+
[columnPinning, enableColumnVirtualization, enableColumnPinning],
|
58
|
+
);
|
59
|
+
|
60
|
+
//get first 16 column widths and average them if calc is needed
|
61
|
+
const averageColumnWidth = useMemo(() => {
|
62
|
+
if (!enableColumnVirtualization || columnVirtualizerProps?.estimateSize)
|
63
|
+
return 0;
|
64
|
+
const columnsWidths =
|
65
|
+
table
|
66
|
+
.getRowModel()
|
67
|
+
.rows[0]?.getCenterVisibleCells()
|
68
|
+
?.slice(0, 16)
|
69
|
+
?.map((cell) => cell.column.getSize() * 1.2) ?? [];
|
70
|
+
return columnsWidths.reduce((a, b) => a + b, 0) / columnsWidths.length;
|
71
|
+
}, [table.getRowModel().rows, columnPinning, columnVisibility]);
|
72
|
+
|
73
|
+
const draggingColumnIndex = table
|
74
|
+
.getVisibleLeafColumns()
|
75
|
+
.findIndex((c) => c.id === draggingColumn?.id);
|
76
|
+
|
77
|
+
const columnVirtualizer = enableColumnVirtualization
|
78
|
+
? (useVirtualizer({
|
79
|
+
count: table.getVisibleLeafColumns().length,
|
80
|
+
estimateSize: () => averageColumnWidth,
|
81
|
+
getScrollElement: () => tableContainerRef.current,
|
82
|
+
horizontal: true,
|
83
|
+
overscan: 3,
|
84
|
+
rangeExtractor: useCallback(
|
85
|
+
(range: Range) => {
|
86
|
+
const newIndexes = extraIndexRangeExtractor(
|
87
|
+
range,
|
88
|
+
draggingColumnIndex,
|
89
|
+
);
|
90
|
+
return [
|
91
|
+
...new Set([
|
92
|
+
...leftPinnedIndexes,
|
93
|
+
...newIndexes,
|
94
|
+
...rightPinnedIndexes,
|
95
|
+
]),
|
96
|
+
];
|
97
|
+
},
|
98
|
+
[leftPinnedIndexes, rightPinnedIndexes, draggingColumnIndex],
|
99
|
+
),
|
100
|
+
...columnVirtualizerProps,
|
101
|
+
}) as unknown as Virtualizer<TScrollElement, TItemElement>)
|
102
|
+
: undefined;
|
103
|
+
|
104
|
+
if (columnVirtualizerInstanceRef && columnVirtualizer) {
|
105
|
+
//@ts-ignore
|
106
|
+
columnVirtualizerInstanceRef.current = columnVirtualizer;
|
107
|
+
}
|
108
|
+
|
109
|
+
const virtualColumns = columnVirtualizer
|
110
|
+
? columnVirtualizer.getVirtualItems()
|
111
|
+
: undefined;
|
112
|
+
|
113
|
+
if (columnVirtualizer && virtualColumns?.length) {
|
114
|
+
// @ts-ignore
|
115
|
+
columnVirtualizer.virtualPaddingLeft =
|
116
|
+
virtualColumns[leftPinnedIndexes!.length]?.start ?? 0;
|
117
|
+
// @ts-ignore
|
118
|
+
columnVirtualizer.virtualPaddingRight =
|
119
|
+
columnVirtualizer.getTotalSize() -
|
120
|
+
(virtualColumns[virtualColumns.length - 1 - rightPinnedIndexes!.length]
|
121
|
+
?.end ?? 0);
|
122
|
+
}
|
123
|
+
|
124
|
+
return columnVirtualizer as any;
|
125
|
+
};
|
@@ -16,6 +16,7 @@ import {
|
|
16
16
|
type MRT_Row,
|
17
17
|
type MRT_RowData,
|
18
18
|
} from '../types';
|
19
|
+
import { MRT_DefaultDisplayColumn } from '.';
|
19
20
|
|
20
21
|
interface Params<TData extends MRT_RowData> {
|
21
22
|
columnOrder: MRT_ColumnOrderState;
|
@@ -217,6 +218,7 @@ function makeSpacerColumn<TData extends MRT_RowData>(
|
|
217
218
|
if (order.includes(id)) {
|
218
219
|
return {
|
219
220
|
...defaultDisplayColumnProps(tableOptions, id, undefined, 0),
|
221
|
+
...MRT_DefaultDisplayColumn,
|
220
222
|
muiTableBodyCellProps: blankColProps,
|
221
223
|
muiTableFooterCellProps: blankColProps,
|
222
224
|
muiTableHeadCellProps: blankColProps,
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import { useCallback } from 'react';
|
2
|
+
import {
|
3
|
+
type Range,
|
4
|
+
type Virtualizer,
|
5
|
+
useVirtualizer,
|
6
|
+
} from '@tanstack/react-virtual';
|
7
|
+
import {
|
8
|
+
extraIndexRangeExtractor,
|
9
|
+
parseFromValuesOrFunc,
|
10
|
+
} from '../column.utils';
|
11
|
+
import { type MRT_RowData, type MRT_TableInstance } from '../types';
|
12
|
+
|
13
|
+
export const useMRT_RowVirtualizer = <
|
14
|
+
TData extends MRT_RowData,
|
15
|
+
TScrollElement extends Element | Window = HTMLDivElement,
|
16
|
+
TItemElement extends Element = HTMLTableRowElement,
|
17
|
+
>(
|
18
|
+
table: MRT_TableInstance<TData>,
|
19
|
+
): Virtualizer<TScrollElement, TItemElement> | undefined => {
|
20
|
+
const {
|
21
|
+
getRowModel,
|
22
|
+
getState,
|
23
|
+
options: {
|
24
|
+
enableRowVirtualization,
|
25
|
+
rowVirtualizerInstanceRef,
|
26
|
+
rowVirtualizerOptions,
|
27
|
+
},
|
28
|
+
refs: { tableContainerRef },
|
29
|
+
} = table;
|
30
|
+
const { density, draggingRow } = getState();
|
31
|
+
|
32
|
+
const rowVirtualizerProps = parseFromValuesOrFunc(rowVirtualizerOptions, {
|
33
|
+
table,
|
34
|
+
});
|
35
|
+
|
36
|
+
const rowVirtualizer = enableRowVirtualization
|
37
|
+
? (useVirtualizer({
|
38
|
+
count: getRowModel().rows.length,
|
39
|
+
estimateSize: () =>
|
40
|
+
density === 'compact' ? 37 : density === 'comfortable' ? 58 : 73,
|
41
|
+
getScrollElement: () => tableContainerRef.current,
|
42
|
+
measureElement:
|
43
|
+
typeof window !== 'undefined' &&
|
44
|
+
navigator.userAgent.indexOf('Firefox') === -1
|
45
|
+
? (element) => element?.getBoundingClientRect().height
|
46
|
+
: undefined,
|
47
|
+
overscan: 4,
|
48
|
+
rangeExtractor: useCallback(
|
49
|
+
(range: Range) => {
|
50
|
+
return extraIndexRangeExtractor(range, draggingRow?.index ?? 0);
|
51
|
+
},
|
52
|
+
[draggingRow],
|
53
|
+
),
|
54
|
+
...rowVirtualizerProps,
|
55
|
+
}) as unknown as Virtualizer<TScrollElement, TItemElement>)
|
56
|
+
: undefined;
|
57
|
+
|
58
|
+
if (rowVirtualizerInstanceRef && rowVirtualizer) {
|
59
|
+
//@ts-ignore
|
60
|
+
rowVirtualizerInstanceRef.current = rowVirtualizer;
|
61
|
+
}
|
62
|
+
|
63
|
+
return rowVirtualizer;
|
64
|
+
};
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import { useMemo } from 'react';
|
2
|
+
import { getCanRankRows } from '../column.utils';
|
3
|
+
import { rankGlobalFuzzy } from '../sortingFns';
|
4
|
+
import {
|
5
|
+
type MRT_Row,
|
6
|
+
type MRT_RowData,
|
7
|
+
type MRT_TableInstance,
|
8
|
+
} from '../types';
|
9
|
+
|
10
|
+
export const useMRT_Rows = <TData extends MRT_RowData>(
|
11
|
+
table: MRT_TableInstance<TData>,
|
12
|
+
): MRT_Row<TData>[] => {
|
13
|
+
const {
|
14
|
+
getBottomRows,
|
15
|
+
getCenterRows,
|
16
|
+
getPrePaginationRowModel,
|
17
|
+
getRowModel,
|
18
|
+
getState,
|
19
|
+
getTopRows,
|
20
|
+
options: {
|
21
|
+
enableGlobalFilterRankedResults,
|
22
|
+
enablePagination,
|
23
|
+
enableRowPinning,
|
24
|
+
manualExpanding,
|
25
|
+
manualFiltering,
|
26
|
+
manualGrouping,
|
27
|
+
manualPagination,
|
28
|
+
manualSorting,
|
29
|
+
rowPinningDisplayMode,
|
30
|
+
},
|
31
|
+
} = table;
|
32
|
+
const { expanded, globalFilter, pagination, rowPinning, sorting } =
|
33
|
+
getState();
|
34
|
+
|
35
|
+
const shouldRankRows = useMemo(
|
36
|
+
() =>
|
37
|
+
getCanRankRows(table) &&
|
38
|
+
!Object.values(sorting).some(Boolean) &&
|
39
|
+
globalFilter,
|
40
|
+
[
|
41
|
+
enableGlobalFilterRankedResults,
|
42
|
+
expanded,
|
43
|
+
globalFilter,
|
44
|
+
manualExpanding,
|
45
|
+
manualFiltering,
|
46
|
+
manualGrouping,
|
47
|
+
manualSorting,
|
48
|
+
sorting,
|
49
|
+
],
|
50
|
+
);
|
51
|
+
|
52
|
+
const pinnedRowIds = useMemo(
|
53
|
+
() =>
|
54
|
+
getRowModel()
|
55
|
+
.rows.filter((row) => row.getIsPinned())
|
56
|
+
.map((r) => r.id),
|
57
|
+
[rowPinning, table.getRowModel().rows],
|
58
|
+
);
|
59
|
+
|
60
|
+
const rows = useMemo(() => {
|
61
|
+
let rows: MRT_Row<TData>[] = [];
|
62
|
+
if (!shouldRankRows) {
|
63
|
+
rows =
|
64
|
+
!enableRowPinning || rowPinningDisplayMode?.includes('sticky')
|
65
|
+
? getRowModel().rows
|
66
|
+
: getCenterRows();
|
67
|
+
} else {
|
68
|
+
rows = getPrePaginationRowModel().rows.sort((a, b) =>
|
69
|
+
rankGlobalFuzzy(a, b),
|
70
|
+
);
|
71
|
+
if (enablePagination && !manualPagination) {
|
72
|
+
const start = pagination.pageIndex * pagination.pageSize;
|
73
|
+
rows = rows.slice(start, start + pagination.pageSize);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
if (enableRowPinning && rowPinningDisplayMode?.includes('sticky')) {
|
77
|
+
rows = [
|
78
|
+
...getTopRows().filter((row) => !pinnedRowIds.includes(row.id)),
|
79
|
+
...rows,
|
80
|
+
...getBottomRows().filter((row) => !pinnedRowIds.includes(row.id)),
|
81
|
+
];
|
82
|
+
}
|
83
|
+
|
84
|
+
return rows;
|
85
|
+
}, [
|
86
|
+
shouldRankRows,
|
87
|
+
shouldRankRows ? getPrePaginationRowModel().rows : getRowModel().rows,
|
88
|
+
pagination.pageIndex,
|
89
|
+
pagination.pageSize,
|
90
|
+
rowPinning,
|
91
|
+
]);
|
92
|
+
|
93
|
+
return rows;
|
94
|
+
};
|