material-react-table 2.1.0 → 2.3.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 +14 -4
- package/dist/index.esm.js +2360 -2324
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2350 -2311
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/src/body/MRT_TableBody.tsx +30 -125
- 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/menus/MRT_ShowHideColumnsMenu.tsx +4 -5
- package/src/menus/MRT_ShowHideColumnsMenuItems.tsx +2 -1
- package/src/table/MRT_Table.tsx +17 -107
- package/src/types.ts +1 -0
package/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "2.
|
2
|
+
"version": "2.3.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
|
-
}
|
73
|
+
const rows = useMRT_Rows(table);
|
147
74
|
|
148
|
-
|
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;
|
180
|
-
|
181
|
-
if (rowVirtualizerInstanceRef && rowVirtualizer) {
|
182
|
-
rowVirtualizerInstanceRef.current = rowVirtualizer;
|
183
|
-
}
|
75
|
+
const rowVirtualizer = useMRT_RowVirtualizer(table);
|
184
76
|
|
185
77
|
const virtualRows = rowVirtualizer
|
186
78
|
? rowVirtualizer.getVirtualItems()
|
@@ -195,6 +87,10 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
195
87
|
virtualPaddingRight,
|
196
88
|
};
|
197
89
|
|
90
|
+
const CreatingRow = creatingRow && createDisplayMode === 'row' && (
|
91
|
+
<MRT_TableBodyRow {...commonRowProps} row={creatingRow} rowIndex={-1} />
|
92
|
+
);
|
93
|
+
|
198
94
|
return (
|
199
95
|
<>
|
200
96
|
{!rowPinningDisplayMode?.includes('sticky') &&
|
@@ -223,23 +119,32 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
223
119
|
})}
|
224
120
|
</TableBody>
|
225
121
|
)}
|
122
|
+
{rowVirtualizer && CreatingRow && (
|
123
|
+
<TableBody
|
124
|
+
{...tableBodyProps}
|
125
|
+
sx={(theme) => ({
|
126
|
+
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
127
|
+
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
|
128
|
+
})}
|
129
|
+
>
|
130
|
+
{CreatingRow}
|
131
|
+
</TableBody>
|
132
|
+
)}
|
226
133
|
<TableBody
|
227
134
|
{...tableBodyProps}
|
228
135
|
sx={(theme) => ({
|
229
136
|
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
230
137
|
height: rowVirtualizer
|
231
138
|
? `${rowVirtualizer.getTotalSize()}px`
|
232
|
-
:
|
139
|
+
: undefined,
|
233
140
|
minHeight: !rows.length ? '100px' : undefined,
|
234
141
|
position: 'relative',
|
235
142
|
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
|
236
143
|
})}
|
237
144
|
>
|
238
|
-
{
|
239
|
-
<MRT_TableBodyRow row={creatingRow} rowIndex={-1} table={table} />
|
240
|
-
)}
|
145
|
+
{!rowVirtualizer && CreatingRow}
|
241
146
|
{tableBodyProps?.children ??
|
242
|
-
(!rows.length ? (
|
147
|
+
(!rows.length && !CreatingRow ? (
|
243
148
|
<tr
|
244
149
|
style={{
|
245
150
|
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
|
@@ -289,11 +194,11 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
|
|
289
194
|
};
|
290
195
|
return memoMode === 'rows' ? (
|
291
196
|
<Memo_MRT_TableBodyRow
|
292
|
-
key={`${row.id}
|
197
|
+
key={`${row.id}-${row.index}`}
|
293
198
|
{...props}
|
294
199
|
/>
|
295
200
|
) : (
|
296
|
-
<MRT_TableBodyRow key={`${row.id}
|
201
|
+
<MRT_TableBodyRow key={`${row.id}-${row.index}`} {...props} />
|
297
202
|
);
|
298
203
|
})}
|
299
204
|
</>
|
@@ -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
|
+
};
|