@cutting/material-react-table 5.0.0-beta.2 → 5.1.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/README.md +1 -4
- package/dist/index.d.ts +189 -524
- package/dist/index.js +329 -345
- package/dist/index.js.map +1 -1
- package/locales/ar/index.mjs +1 -2
- package/locales/az/index.mjs +1 -2
- package/locales/bg/index.mjs +1 -2
- package/locales/cs/index.mjs +1 -2
- package/locales/da/index.mjs +1 -2
- package/locales/de/index.mjs +1 -2
- package/locales/el/index.mjs +1 -2
- package/locales/en/index.mjs +1 -2
- package/locales/es/index.mjs +1 -2
- package/locales/et/index.mjs +1 -2
- package/locales/fa/index.mjs +1 -2
- package/locales/fi/index.mjs +1 -2
- package/locales/fr/index.mjs +1 -2
- package/locales/he/index.mjs +1 -2
- package/locales/hr/index.mjs +1 -2
- package/locales/hu/index.mjs +1 -2
- package/locales/hy/index.mjs +1 -2
- package/locales/id/index.mjs +1 -2
- package/locales/it/index.mjs +1 -2
- package/locales/ja/index.mjs +1 -2
- package/locales/ko/index.mjs +1 -2
- package/locales/nl/index.mjs +1 -2
- package/locales/no/index.mjs +1 -2
- package/locales/np/index.mjs +1 -2
- package/locales/pl/index.mjs +1 -2
- package/locales/pt/index.mjs +1 -2
- package/locales/pt-BR/index.mjs +1 -2
- package/locales/ro/index.mjs +1 -2
- package/locales/ru/index.mjs +1 -2
- package/locales/sk/index.mjs +1 -2
- package/locales/sr-Cyrl-RS/index.mjs +1 -2
- package/locales/sr-Latn-RS/index.mjs +1 -2
- package/locales/sv/index.mjs +1 -2
- package/locales/tr/index.mjs +1 -2
- package/locales/uk/index.mjs +1 -2
- package/locales/vi/index.mjs +1 -2
- package/locales/zh-Hans/index.mjs +1 -2
- package/locales/zh-Hant/index.mjs +1 -2
- package/package.json +32 -40
- package/src/MaterialReactTable.smoke.test.tsx +3 -9
- package/src/components/MaterialReactTable.tsx +13 -21
- package/src/components/body/MRT_TableBody.tsx +67 -82
- package/src/components/body/MRT_TableBodyCell.tsx +38 -80
- package/src/components/body/MRT_TableBodyCellValue.tsx +5 -14
- package/src/components/body/MRT_TableBodyRow.tsx +55 -102
- package/src/components/body/MRT_TableBodyRowGrabHandle.test.tsx +2 -6
- package/src/components/body/MRT_TableBodyRowGrabHandle.tsx +4 -9
- package/src/components/body/MRT_TableBodyRowPinButton.tsx +8 -14
- package/src/components/body/MRT_TableDetailPanel.test.tsx +3 -9
- package/src/components/body/MRT_TableDetailPanel.tsx +8 -14
- package/src/components/buttons/MRT_ColumnPinningButtons.test.tsx +6 -16
- package/src/components/buttons/MRT_ColumnPinningButtons.tsx +6 -12
- package/src/components/buttons/MRT_CopyButton.tsx +7 -15
- package/src/components/buttons/MRT_EditActionButtons.test.tsx +2 -6
- package/src/components/buttons/MRT_EditActionButtons.tsx +15 -37
- package/src/components/buttons/MRT_ExpandAllButton.tsx +8 -16
- package/src/components/buttons/MRT_ExpandButton.tsx +9 -21
- package/src/components/buttons/MRT_GrabHandleButton.tsx +6 -10
- package/src/components/buttons/MRT_RowPinButton.tsx +8 -23
- package/src/components/buttons/MRT_ShowHideColumnsButton.tsx +5 -18
- package/src/components/buttons/MRT_ToggleDensePaddingButton.test.tsx +4 -12
- package/src/components/buttons/MRT_ToggleDensePaddingButton.tsx +4 -11
- package/src/components/buttons/MRT_ToggleFiltersButton.test.tsx +4 -13
- package/src/components/buttons/MRT_ToggleFiltersButton.tsx +3 -5
- package/src/components/buttons/MRT_ToggleFullScreenButton.test.tsx +3 -11
- package/src/components/buttons/MRT_ToggleFullScreenButton.tsx +4 -9
- package/src/components/buttons/MRT_ToggleGlobalFilterButton.tsx +3 -5
- package/src/components/buttons/MRT_ToggleRowActionMenuButton.tsx +7 -15
- package/src/components/footer/MRT_TableFooter.tsx +9 -16
- package/src/components/footer/MRT_TableFooterCell.tsx +9 -32
- package/src/components/footer/MRT_TableFooterRow.tsx +18 -32
- package/src/components/head/MRT_TableHead.tsx +8 -18
- package/src/components/head/MRT_TableHeadCell.tsx +46 -100
- package/src/components/head/MRT_TableHeadCellColumnActionsButton.tsx +10 -30
- package/src/components/head/MRT_TableHeadCellFilterContainer.tsx +4 -15
- package/src/components/head/MRT_TableHeadCellFilterLabel.tsx +20 -54
- package/src/components/head/MRT_TableHeadCellGrabHandle.test.tsx +5 -19
- package/src/components/head/MRT_TableHeadCellGrabHandle.tsx +9 -38
- package/src/components/head/MRT_TableHeadCellResizeHandle.test.tsx +3 -13
- package/src/components/head/MRT_TableHeadCellResizeHandle.tsx +10 -24
- package/src/components/head/MRT_TableHeadCellSortLabel.tsx +10 -26
- package/src/components/head/MRT_TableHeadRow.tsx +24 -36
- package/src/components/inputs/MRT_EditCellTextField.test.tsx +2 -9
- package/src/components/inputs/MRT_EditCellTextField.tsx +9 -28
- package/src/components/inputs/MRT_FilterCheckbox.tsx +9 -23
- package/src/components/inputs/MRT_FilterRangeFields.tsx +6 -15
- package/src/components/inputs/MRT_FilterRangeSlider.tsx +24 -32
- package/src/components/inputs/MRT_FilterTextField.test.tsx +72 -14
- package/src/components/inputs/MRT_FilterTextField.tsx +77 -138
- package/src/components/inputs/MRT_GlobalFilterTextField.tsx +10 -32
- package/src/components/inputs/MRT_SelectCheckbox.test.tsx +4 -11
- package/src/components/inputs/MRT_SelectCheckbox.tsx +17 -36
- package/src/components/menus/MRT_ActionMenuItem.tsx +6 -15
- package/src/components/menus/MRT_CellActionMenu.tsx +6 -9
- package/src/components/menus/MRT_ColumnActionMenu.tsx +22 -57
- package/src/components/menus/MRT_FilterOptionMenu.tsx +38 -65
- package/src/components/menus/MRT_RowActionMenu.tsx +33 -22
- package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +29 -65
- package/src/components/menus/MRT_ShowHideColumnsMenuItems.test.tsx +43 -0
- package/src/components/menus/MRT_ShowHideColumnsMenuItems.tsx +14 -50
- package/src/components/modals/MRT_EditRowModal.test.tsx +5 -21
- package/src/components/modals/MRT_EditRowModal.tsx +8 -26
- package/src/components/table/MRT_Table.tsx +12 -20
- package/src/components/table/MRT_TableContainer.test.tsx +147 -0
- package/src/components/table/MRT_TableContainer.tsx +33 -37
- package/src/components/table/MRT_TableLoadingOverlay.tsx +3 -5
- package/src/components/table/MRT_TablePaper.tsx +7 -14
- package/src/components/toolbar/MRT_BottomToolbar.tsx +11 -23
- package/src/components/toolbar/MRT_LinearProgressBar.tsx +4 -11
- package/src/components/toolbar/MRT_TablePagination.tsx +33 -40
- package/src/components/toolbar/MRT_ToolbarAlertBanner.tsx +21 -50
- package/src/components/toolbar/MRT_ToolbarDropZone.test.tsx +26 -10
- package/src/components/toolbar/MRT_ToolbarDropZone.tsx +23 -21
- package/src/components/toolbar/MRT_ToolbarInternalButtons.tsx +11 -21
- package/src/components/toolbar/MRT_TopToolbar.tsx +12 -28
- package/src/fns/aggregationFns.test.tsx +1 -3
- package/src/fns/filterFns.test.tsx +9 -37
- package/src/fns/filterFns.ts +73 -96
- package/src/fns/sortingFns.test.tsx +39 -0
- package/src/fns/sortingFns.ts +15 -15
- package/src/fns/tableFeatures.test.tsx +6 -29
- package/src/fns/tableFeatures.ts +5 -4
- package/src/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +2 -11
- package/src/hooks/display-columns/getMRT_RowDragColumnDef.tsx +2 -10
- package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +8 -17
- package/src/hooks/display-columns/getMRT_RowNumbersColumnDef.tsx +3 -8
- package/src/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +2 -8
- package/src/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +3 -13
- package/src/hooks/display-columns/getMRT_RowSpacerColumnDef.tsx +1 -5
- package/src/hooks/useMRT_ColumnVirtualizer.ts +28 -49
- package/src/hooks/useMRT_Effects.test.tsx +114 -0
- package/src/hooks/useMRT_Effects.ts +26 -27
- package/src/hooks/useMRT_RowVirtualizer.ts +18 -33
- package/src/hooks/useMRT_Rows.ts +3 -42
- package/src/hooks/useMRT_TableInstance.ts +63 -129
- package/src/hooks/useMRT_TableOptions.ts +15 -29
- package/src/hooks/useMaterialReactTable.ts +2 -7
- package/src/icons.ts +38 -1
- package/src/index.ts +0 -4
- package/src/locales/ar.ts +1 -2
- package/src/locales/az.ts +1 -2
- package/src/locales/bg.ts +1 -2
- package/src/locales/cs.ts +2 -4
- package/src/locales/da.ts +1 -2
- package/src/locales/de.ts +1 -2
- package/src/locales/el.ts +1 -2
- package/src/locales/en.ts +1 -2
- package/src/locales/es.ts +1 -2
- package/src/locales/et.ts +2 -4
- package/src/locales/fa.ts +1 -2
- package/src/locales/fi.ts +2 -4
- package/src/locales/fr.ts +1 -2
- package/src/locales/he.ts +1 -2
- package/src/locales/hr.ts +1 -2
- package/src/locales/hu.ts +1 -2
- package/src/locales/hy.ts +1 -2
- package/src/locales/id.ts +2 -4
- package/src/locales/it.ts +1 -2
- package/src/locales/ja.ts +1 -2
- package/src/locales/ko.ts +1 -2
- package/src/locales/nl.ts +1 -2
- package/src/locales/no.ts +2 -4
- package/src/locales/np.ts +2 -4
- package/src/locales/pl.ts +1 -2
- package/src/locales/pt-BR.ts +1 -2
- package/src/locales/pt.ts +1 -2
- package/src/locales/ro.ts +1 -2
- package/src/locales/ru.ts +1 -2
- package/src/locales/sk.ts +2 -4
- package/src/locales/sr-Cyrl-RS.ts +1 -2
- package/src/locales/sr-Latn-RS.ts +1 -2
- package/src/locales/sv.ts +1 -2
- package/src/locales/tr.ts +1 -2
- package/src/locales/uk.ts +1 -2
- package/src/locales/vi.ts +1 -2
- package/src/types.ts +156 -349
- package/src/utils/cell.utils.ts +30 -68
- package/src/utils/column.utils.ts +61 -49
- package/src/utils/displayColumn.utils.ts +16 -38
- package/src/utils/highlight.utils.ts +7 -11
- package/src/utils/row.utils.ts +40 -65
- package/src/utils/slotProps.utils.ts +1 -4
- package/src/utils/style.utils.ts +18 -46
- package/src/utils/tanstack.helpers.ts +10 -17
- package/src/utils/utils.ts +6 -10
- package/src/utils/virtualization.utils.ts +5 -9
package/src/fns/sortingFns.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
import { compareItems, type RankingInfo } from '@tanstack/match-sorter-utils';
|
|
2
2
|
import {
|
|
3
|
+
type Row,
|
|
3
4
|
sortFn_alphanumeric,
|
|
5
|
+
sortFn_alphanumericCaseSensitive,
|
|
4
6
|
sortFn_basic,
|
|
5
7
|
sortFn_datetime,
|
|
6
8
|
sortFn_text,
|
|
9
|
+
sortFn_textCaseSensitive,
|
|
7
10
|
} from '@tanstack/react-table';
|
|
8
|
-
import { type Row } from '@tanstack/react-table';
|
|
9
11
|
|
|
10
12
|
import { type MRT_Row, type MRT_RowData } from '../types';
|
|
13
|
+
import { type MRT_TableFeatures } from './tableFeatures';
|
|
11
14
|
|
|
12
|
-
const fuzzy = <TData extends MRT_RowData>(
|
|
13
|
-
rowA: Row<
|
|
14
|
-
rowB: Row<
|
|
15
|
+
const fuzzy = <TFeatures extends MRT_TableFeatures, TData extends MRT_RowData>(
|
|
16
|
+
rowA: Row<TFeatures, TData>,
|
|
17
|
+
rowB: Row<TFeatures, TData>,
|
|
15
18
|
columnId: string,
|
|
16
|
-
) => {
|
|
19
|
+
): number => {
|
|
17
20
|
let dir = 0;
|
|
18
|
-
if (rowA.columnFiltersMeta[columnId]) {
|
|
21
|
+
if ('columnFiltersMeta' in rowA && 'columnFiltersMeta' in rowB && rowA.columnFiltersMeta[columnId]) {
|
|
19
22
|
dir = compareItems(
|
|
20
23
|
rowA.columnFiltersMeta[columnId] as RankingInfo,
|
|
21
24
|
rowB.columnFiltersMeta[columnId] as RankingInfo,
|
|
22
25
|
);
|
|
23
26
|
}
|
|
24
27
|
// Provide a fallback for when the item ranks are equal
|
|
25
|
-
return dir === 0
|
|
26
|
-
? sortFn_alphanumeric(rowA, rowB, columnId)
|
|
27
|
-
: dir;
|
|
28
|
+
return dir === 0 ? sortFn_alphanumeric(rowA, rowB, columnId) : dir;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
export const MRT_SortingFns = {
|
|
31
32
|
alphanumeric: sortFn_alphanumeric,
|
|
33
|
+
alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive,
|
|
32
34
|
basic: sortFn_basic,
|
|
33
35
|
datetime: sortFn_datetime,
|
|
34
36
|
fuzzy,
|
|
35
37
|
text: sortFn_text,
|
|
38
|
+
textCaseSensitive: sortFn_textCaseSensitive,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
export const rankGlobalFuzzy = <TData extends MRT_RowData>(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
) =>
|
|
42
|
-
Math.max(...Object.values(rowB.columnFiltersMeta).map((v: any) => v.rank)) -
|
|
43
|
-
Math.max(...Object.values(rowA.columnFiltersMeta).map((v: any) => v.rank));
|
|
41
|
+
export const rankGlobalFuzzy = <TData extends MRT_RowData>(rowA: MRT_Row<TData>, rowB: MRT_Row<TData>): number =>
|
|
42
|
+
Math.max(...Object.values(rowB.columnFiltersMeta).map((meta) => (meta as RankingInfo).rank)) -
|
|
43
|
+
Math.max(...Object.values(rowA.columnFiltersMeta).map((meta) => (meta as RankingInfo).rank));
|
|
@@ -8,20 +8,12 @@ interface Person {
|
|
|
8
8
|
name: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const data: Person[] = [
|
|
12
|
-
{ name: 'Jonathan' },
|
|
13
|
-
{ name: 'Aaron' },
|
|
14
|
-
{ name: 'Sara' },
|
|
15
|
-
];
|
|
11
|
+
const data: Person[] = [{ name: 'Jonathan' }, { name: 'Aaron' }, { name: 'Sara' }];
|
|
16
12
|
|
|
17
|
-
const columns: MRT_ColumnDef<Person>[] = [
|
|
18
|
-
{ accessorKey: 'name', header: 'Name' },
|
|
19
|
-
];
|
|
13
|
+
const columns: MRT_ColumnDef<Person>[] = [{ accessorKey: 'name', header: 'Name' }];
|
|
20
14
|
|
|
21
15
|
const renderedNames = (container: HTMLElement) =>
|
|
22
|
-
Array.from(container.querySelectorAll('tbody tr')).map(
|
|
23
|
-
(row) => row.textContent,
|
|
24
|
-
);
|
|
16
|
+
Array.from(container.querySelectorAll('tbody tr')).map((row) => row.textContent);
|
|
25
17
|
|
|
26
18
|
describe('server-side options suppress client-side row models', () => {
|
|
27
19
|
test('manualPagination renders the whole server page, ignoring pageSize', () => {
|
|
@@ -40,12 +32,7 @@ describe('server-side options suppress client-side row models', () => {
|
|
|
40
32
|
|
|
41
33
|
test('manualFiltering keeps every row when a global filter is set', () => {
|
|
42
34
|
const { container } = render(
|
|
43
|
-
<MaterialReactTable
|
|
44
|
-
columns={columns}
|
|
45
|
-
data={data}
|
|
46
|
-
manualFiltering
|
|
47
|
-
state={{ globalFilter: 'zzz' }}
|
|
48
|
-
/>,
|
|
35
|
+
<MaterialReactTable columns={columns} data={data} manualFiltering state={{ globalFilter: 'zzz' }} />,
|
|
49
36
|
);
|
|
50
37
|
|
|
51
38
|
expect(renderedNames(container)).toEqual(['Jonathan', 'Aaron', 'Sara']);
|
|
@@ -69,24 +56,14 @@ describe('server-side options suppress client-side row models', () => {
|
|
|
69
56
|
describe('client-side row models stay active by default', () => {
|
|
70
57
|
test('pagination slices to pageSize', () => {
|
|
71
58
|
const { container } = render(
|
|
72
|
-
<MaterialReactTable
|
|
73
|
-
columns={columns}
|
|
74
|
-
data={data}
|
|
75
|
-
state={{ pagination: { pageIndex: 0, pageSize: 2 } }}
|
|
76
|
-
/>,
|
|
59
|
+
<MaterialReactTable columns={columns} data={data} state={{ pagination: { pageIndex: 0, pageSize: 2 } }} />,
|
|
77
60
|
);
|
|
78
61
|
|
|
79
62
|
expect(renderedNames(container)).toEqual(['Jonathan', 'Aaron']);
|
|
80
63
|
});
|
|
81
64
|
|
|
82
65
|
test('global filter drops non-matching rows', () => {
|
|
83
|
-
const { container } = render(
|
|
84
|
-
<MaterialReactTable
|
|
85
|
-
columns={columns}
|
|
86
|
-
data={data}
|
|
87
|
-
state={{ globalFilter: 'zzz' }}
|
|
88
|
-
/>,
|
|
89
|
-
);
|
|
66
|
+
const { container } = render(<MaterialReactTable columns={columns} data={data} state={{ globalFilter: 'zzz' }} />);
|
|
90
67
|
|
|
91
68
|
expect(renderedNames(container)).toEqual(['No results found']);
|
|
92
69
|
});
|
package/src/fns/tableFeatures.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type AggregationFnDef,
|
|
3
2
|
cellSelectionFeature,
|
|
4
3
|
cellSpanningFeature,
|
|
5
4
|
columnFacetingFeature,
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
createGroupedRowModel,
|
|
19
18
|
createPaginatedRowModel,
|
|
20
19
|
createSortedRowModel,
|
|
20
|
+
type CustomAggregationFns,
|
|
21
21
|
type FilterFn,
|
|
22
22
|
globalFilteringFeature,
|
|
23
23
|
rowAggregationFeature,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
tableFeatures,
|
|
33
33
|
} from '@tanstack/react-table';
|
|
34
34
|
|
|
35
|
+
import { type MRT_RowData } from '../types';
|
|
35
36
|
import { MRT_AggregationFns } from './aggregationFns';
|
|
36
37
|
import { MRT_FilterFns } from './filterFns';
|
|
37
38
|
import { MRT_SortingFns } from './sortingFns';
|
|
@@ -96,8 +97,8 @@ export const MRT_DefaultTableFeatures = tableFeatures({
|
|
|
96
97
|
});
|
|
97
98
|
|
|
98
99
|
export interface MRT_TableFeatures extends StockFeatures {
|
|
99
|
-
aggregationFns:
|
|
100
|
-
filterFns: Record<string, FilterFn<
|
|
100
|
+
aggregationFns: CustomAggregationFns<MRT_TableFeatures, MRT_RowData>;
|
|
101
|
+
filterFns: Record<string, FilterFn<MRT_TableFeatures, MRT_RowData>>;
|
|
101
102
|
mrtFeature: TableFeature;
|
|
102
|
-
sortFns: Record<string, SortFn<
|
|
103
|
+
sortFns: Record<string, SortFn<MRT_TableFeatures, MRT_RowData>>;
|
|
103
104
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { MRT_ToggleRowActionMenuButton } from '../../components/buttons/MRT_ToggleRowActionMenuButton';
|
|
2
|
-
import {
|
|
3
|
-
type MRT_ColumnDef,
|
|
4
|
-
type MRT_RowData,
|
|
5
|
-
type MRT_StatefulTableOptions,
|
|
6
|
-
} from '../../types';
|
|
2
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
7
3
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
8
4
|
|
|
9
5
|
export const getMRT_RowActionsColumnDef = <TData extends MRT_RowData>(
|
|
@@ -11,12 +7,7 @@ export const getMRT_RowActionsColumnDef = <TData extends MRT_RowData>(
|
|
|
11
7
|
): MRT_ColumnDef<TData> => {
|
|
12
8
|
return {
|
|
13
9
|
Cell: ({ cell, row, staticRowIndex, table }) => (
|
|
14
|
-
<MRT_ToggleRowActionMenuButton
|
|
15
|
-
cell={cell}
|
|
16
|
-
row={row}
|
|
17
|
-
staticRowIndex={staticRowIndex}
|
|
18
|
-
table={table}
|
|
19
|
-
/>
|
|
10
|
+
<MRT_ToggleRowActionMenuButton cell={cell} row={row} staticRowIndex={staticRowIndex} table={table} />
|
|
20
11
|
),
|
|
21
12
|
...defaultDisplayColumnProps({
|
|
22
13
|
header: 'actions',
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
|
|
3
3
|
import { MRT_TableBodyRowGrabHandle } from '../../components/body/MRT_TableBodyRowGrabHandle';
|
|
4
|
-
import {
|
|
5
|
-
type MRT_ColumnDef,
|
|
6
|
-
type MRT_RowData,
|
|
7
|
-
type MRT_StatefulTableOptions,
|
|
8
|
-
} from '../../types';
|
|
4
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
9
5
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
10
6
|
|
|
11
7
|
export const getMRT_RowDragColumnDef = <TData extends MRT_RowData>(
|
|
@@ -13,11 +9,7 @@ export const getMRT_RowDragColumnDef = <TData extends MRT_RowData>(
|
|
|
13
9
|
): MRT_ColumnDef<TData> => {
|
|
14
10
|
return {
|
|
15
11
|
Cell: ({ row, rowRef, table }) => (
|
|
16
|
-
<MRT_TableBodyRowGrabHandle
|
|
17
|
-
row={row}
|
|
18
|
-
rowRef={rowRef as RefObject<HTMLTableRowElement | null>}
|
|
19
|
-
table={table}
|
|
20
|
-
/>
|
|
12
|
+
<MRT_TableBodyRowGrabHandle row={row} rowRef={rowRef as RefObject<HTMLTableRowElement | null>} table={table} />
|
|
21
13
|
),
|
|
22
14
|
grow: false,
|
|
23
15
|
...defaultDisplayColumnProps({
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { Stack } from '@mui/material';
|
|
2
|
-
import { Tooltip } from '@mui/material';
|
|
1
|
+
import { Stack, Tooltip } from '@mui/material';
|
|
3
2
|
import { type ReactNode } from 'react';
|
|
4
3
|
|
|
5
4
|
import { MRT_ExpandAllButton } from '../../components/buttons/MRT_ExpandAllButton';
|
|
6
5
|
import { MRT_ExpandButton } from '../../components/buttons/MRT_ExpandButton';
|
|
7
|
-
import {
|
|
8
|
-
type MRT_ColumnDef,
|
|
9
|
-
type MRT_RowData,
|
|
10
|
-
type MRT_StatefulTableOptions,
|
|
11
|
-
} from '../../types';
|
|
6
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
12
7
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
13
8
|
import { getCommonTooltipProps } from '../../utils/style.utils';
|
|
14
9
|
|
|
@@ -39,10 +34,11 @@ export const getMRT_RowExpandColumnDef = <TData extends MRT_RowData>(
|
|
|
39
34
|
return (
|
|
40
35
|
<Stack
|
|
41
36
|
sx={{
|
|
42
|
-
alignItems:
|
|
43
|
-
flexDirection:
|
|
44
|
-
gap:
|
|
45
|
-
}}
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
flexDirection: 'row',
|
|
39
|
+
gap: '0.25rem',
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
46
42
|
<MRT_ExpandButton {...expandButtonProps} />
|
|
47
43
|
<Tooltip
|
|
48
44
|
{...getCommonTooltipProps('right')}
|
|
@@ -68,12 +64,7 @@ export const getMRT_RowExpandColumnDef = <TData extends MRT_RowData>(
|
|
|
68
64
|
<>
|
|
69
65
|
<MRT_ExpandAllButton table={table} />
|
|
70
66
|
{groupedColumnMode === 'remove' &&
|
|
71
|
-
grouping
|
|
72
|
-
?.map(
|
|
73
|
-
(groupedColumnId) =>
|
|
74
|
-
table.getColumn(groupedColumnId)?.columnDef.header,
|
|
75
|
-
)
|
|
76
|
-
?.join(', ')}
|
|
67
|
+
grouping?.map((groupedColumnId) => table.getColumn(groupedColumnId)?.columnDef.header)?.join(', ')}
|
|
77
68
|
</>
|
|
78
69
|
);
|
|
79
70
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type MRT_ColumnDef,
|
|
3
|
-
type MRT_RowData,
|
|
4
|
-
type MRT_StatefulTableOptions,
|
|
5
|
-
} from '../../types';
|
|
1
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
6
2
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
7
3
|
|
|
8
4
|
export const getMRT_RowNumbersColumnDef = <TData extends MRT_RowData>(
|
|
@@ -15,9 +11,8 @@ export const getMRT_RowNumbersColumnDef = <TData extends MRT_RowData>(
|
|
|
15
11
|
|
|
16
12
|
return {
|
|
17
13
|
Cell: ({ row, staticRowIndex }) =>
|
|
18
|
-
((rowNumberDisplayMode === 'static'
|
|
19
|
-
|
|
20
|
-
: row.index) ?? 0) + 1,
|
|
14
|
+
((rowNumberDisplayMode === 'static' ? (staticRowIndex || 0) + (pageSize || 0) * (pageIndex || 0) : row.index) ??
|
|
15
|
+
0) + 1,
|
|
21
16
|
grow: false,
|
|
22
17
|
Header: () => localization.rowNumber,
|
|
23
18
|
...defaultDisplayColumnProps({
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { MRT_TableBodyRowPinButton } from '../../components/body/MRT_TableBodyRowPinButton';
|
|
2
|
-
import {
|
|
3
|
-
type MRT_ColumnDef,
|
|
4
|
-
type MRT_RowData,
|
|
5
|
-
type MRT_StatefulTableOptions,
|
|
6
|
-
} from '../../types';
|
|
2
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
7
3
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
8
4
|
|
|
9
5
|
export const getMRT_RowPinningColumnDef = <TData extends MRT_RowData>(
|
|
10
6
|
tableOptions: MRT_StatefulTableOptions<TData>,
|
|
11
7
|
): MRT_ColumnDef<TData> => {
|
|
12
8
|
return {
|
|
13
|
-
Cell: ({ row, table }) =>
|
|
14
|
-
<MRT_TableBodyRowPinButton row={row} table={table} />
|
|
15
|
-
),
|
|
9
|
+
Cell: ({ row, table }) => <MRT_TableBodyRowPinButton row={row} table={table} />,
|
|
16
10
|
grow: false,
|
|
17
11
|
...defaultDisplayColumnProps({
|
|
18
12
|
header: 'pin',
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { MRT_SelectCheckbox } from '../../components/inputs/MRT_SelectCheckbox';
|
|
2
|
-
import {
|
|
3
|
-
type MRT_ColumnDef,
|
|
4
|
-
type MRT_RowData,
|
|
5
|
-
type MRT_StatefulTableOptions,
|
|
6
|
-
} from '../../types';
|
|
2
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
7
3
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
8
4
|
|
|
9
5
|
export const getMRT_RowSelectColumnDef = <TData extends MRT_RowData>(
|
|
@@ -13,17 +9,11 @@ export const getMRT_RowSelectColumnDef = <TData extends MRT_RowData>(
|
|
|
13
9
|
|
|
14
10
|
return {
|
|
15
11
|
Cell: ({ row, staticRowIndex, table }) => (
|
|
16
|
-
<MRT_SelectCheckbox
|
|
17
|
-
row={row}
|
|
18
|
-
staticRowIndex={staticRowIndex}
|
|
19
|
-
table={table}
|
|
20
|
-
/>
|
|
12
|
+
<MRT_SelectCheckbox row={row} staticRowIndex={staticRowIndex} table={table} />
|
|
21
13
|
),
|
|
22
14
|
grow: false,
|
|
23
15
|
Header:
|
|
24
|
-
enableSelectAll && enableMultiRowSelection
|
|
25
|
-
? ({ table }) => <MRT_SelectCheckbox table={table} />
|
|
26
|
-
: undefined,
|
|
16
|
+
enableSelectAll && enableMultiRowSelection ? ({ table }) => <MRT_SelectCheckbox table={table} /> : undefined,
|
|
27
17
|
...defaultDisplayColumnProps({
|
|
28
18
|
header: 'select',
|
|
29
19
|
id: 'mrt-row-select',
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type MRT_ColumnDef,
|
|
3
|
-
type MRT_RowData,
|
|
4
|
-
type MRT_StatefulTableOptions,
|
|
5
|
-
} from '../../types';
|
|
1
|
+
import { type MRT_ColumnDef, type MRT_RowData, type MRT_StatefulTableOptions } from '../../types';
|
|
6
2
|
import { defaultDisplayColumnProps } from '../../utils/displayColumn.utils';
|
|
7
3
|
import { MRT_DefaultDisplayColumn } from '../useMRT_TableOptions';
|
|
8
4
|
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { type Range, useVirtualizer } from '@tanstack/react-virtual';
|
|
2
2
|
import { useCallback, useMemo } from 'react';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
type MRT_ColumnVirtualizer,
|
|
6
|
-
type MRT_RowData,
|
|
7
|
-
type MRT_TableInstance,
|
|
8
|
-
} from '../types';
|
|
4
|
+
import { type MRT_ColumnVirtualizer, type MRT_RowData, type MRT_TableInstance } from '../types';
|
|
9
5
|
import { parseFromValuesOrFunc } from '../utils/utils';
|
|
10
6
|
import { extraIndexRangeExtractor } from '../utils/virtualization.utils';
|
|
11
7
|
|
|
@@ -15,7 +11,7 @@ export const useMRT_ColumnVirtualizer = <
|
|
|
15
11
|
TItemElement extends Element = HTMLTableCellElement,
|
|
16
12
|
>(
|
|
17
13
|
table: MRT_TableInstance<TData>,
|
|
18
|
-
): MRT_ColumnVirtualizer | undefined => {
|
|
14
|
+
): MRT_ColumnVirtualizer<TScrollElement, TItemElement> | undefined => {
|
|
19
15
|
const {
|
|
20
16
|
options: {
|
|
21
17
|
columnVirtualizerInstanceRef,
|
|
@@ -25,16 +21,13 @@ export const useMRT_ColumnVirtualizer = <
|
|
|
25
21
|
},
|
|
26
22
|
refs: { tableContainerRef },
|
|
27
23
|
} = table;
|
|
28
|
-
const {
|
|
24
|
+
const { draggingColumn } = table.state;
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
table,
|
|
36
|
-
},
|
|
37
|
-
);
|
|
26
|
+
const columnVirtualizerProps = enableColumnVirtualization
|
|
27
|
+
? parseFromValuesOrFunc(columnVirtualizerOptions, {
|
|
28
|
+
table,
|
|
29
|
+
})
|
|
30
|
+
: undefined;
|
|
38
31
|
|
|
39
32
|
const visibleColumns = table.getVisibleLeafColumns();
|
|
40
33
|
|
|
@@ -42,33 +35,27 @@ export const useMRT_ColumnVirtualizer = <
|
|
|
42
35
|
() =>
|
|
43
36
|
enableColumnPinning
|
|
44
37
|
? [
|
|
45
|
-
visibleColumns
|
|
46
|
-
.filter((c) => c.getIsPinned() === 'start')
|
|
47
|
-
.map((c) => c.getPinnedIndex()),
|
|
38
|
+
visibleColumns.filter((c) => c.getIsPinned() === 'start').map((c) => c.getPinnedIndex()),
|
|
48
39
|
visibleColumns
|
|
49
40
|
.filter((c) => c.getIsPinned() === 'end')
|
|
50
|
-
.map(
|
|
51
|
-
(column) => visibleColumns.length - column.getPinnedIndex() - 1,
|
|
52
|
-
)
|
|
41
|
+
.map((column) => visibleColumns.length - column.getPinnedIndex() - 1)
|
|
53
42
|
.sort((a, b) => a - b),
|
|
54
43
|
]
|
|
55
44
|
: [[], []],
|
|
56
|
-
[
|
|
45
|
+
[enableColumnPinning, visibleColumns],
|
|
57
46
|
);
|
|
58
47
|
|
|
59
48
|
const numPinnedLeft = leftPinnedIndexes.length;
|
|
60
49
|
const numPinnedRight = rightPinnedIndexes.length;
|
|
61
50
|
|
|
62
51
|
const draggingColumnIndex = useMemo(
|
|
63
|
-
() =>
|
|
64
|
-
|
|
65
|
-
? visibleColumns.findIndex((c) => c.id === draggingColumn?.id)
|
|
66
|
-
: undefined,
|
|
67
|
-
[draggingColumn?.id],
|
|
52
|
+
() => (draggingColumn?.id ? visibleColumns.findIndex((c) => c.id === draggingColumn?.id) : undefined),
|
|
53
|
+
[draggingColumn?.id, visibleColumns],
|
|
68
54
|
);
|
|
69
55
|
|
|
70
56
|
const columnVirtualizer = useVirtualizer({
|
|
71
57
|
count: visibleColumns.length,
|
|
58
|
+
enabled: !!enableColumnVirtualization,
|
|
72
59
|
estimateSize: (index) => visibleColumns[index].getSize(),
|
|
73
60
|
getScrollElement: () => tableContainerRef.current,
|
|
74
61
|
horizontal: true,
|
|
@@ -79,48 +66,40 @@ export const useMRT_ColumnVirtualizer = <
|
|
|
79
66
|
if (!numPinnedLeft && !numPinnedRight) {
|
|
80
67
|
return newIndexes;
|
|
81
68
|
}
|
|
82
|
-
return [
|
|
83
|
-
...new Set([
|
|
84
|
-
...leftPinnedIndexes,
|
|
85
|
-
...newIndexes,
|
|
86
|
-
...rightPinnedIndexes,
|
|
87
|
-
]),
|
|
88
|
-
];
|
|
69
|
+
return [...new Set([...leftPinnedIndexes, ...newIndexes, ...rightPinnedIndexes])];
|
|
89
70
|
},
|
|
90
|
-
[leftPinnedIndexes, rightPinnedIndexes, draggingColumnIndex],
|
|
71
|
+
[leftPinnedIndexes, rightPinnedIndexes, draggingColumnIndex, numPinnedLeft, numPinnedRight],
|
|
91
72
|
),
|
|
92
73
|
...columnVirtualizerProps,
|
|
93
74
|
}) as unknown as MRT_ColumnVirtualizer<TScrollElement, TItemElement>;
|
|
94
75
|
|
|
76
|
+
if (!enableColumnVirtualization) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
95
80
|
const virtualColumns = columnVirtualizer.getVirtualItems();
|
|
96
|
-
columnVirtualizer.virtualColumns = virtualColumns
|
|
81
|
+
columnVirtualizer.virtualColumns = virtualColumns;
|
|
97
82
|
const numColumns = virtualColumns.length;
|
|
98
83
|
|
|
99
84
|
if (numColumns) {
|
|
100
85
|
const totalSize = columnVirtualizer.getTotalSize();
|
|
101
86
|
|
|
102
87
|
const leftNonPinnedStart = virtualColumns[numPinnedLeft]?.start || 0;
|
|
103
|
-
const leftNonPinnedEnd =
|
|
104
|
-
virtualColumns[leftPinnedIndexes.length - 1]?.end || 0;
|
|
88
|
+
const leftNonPinnedEnd = virtualColumns[leftPinnedIndexes.length - 1]?.end || 0;
|
|
105
89
|
|
|
106
|
-
const rightNonPinnedStart =
|
|
107
|
-
|
|
108
|
-
const rightNonPinnedEnd =
|
|
109
|
-
virtualColumns[numColumns - numPinnedRight - 1]?.end || 0;
|
|
90
|
+
const rightNonPinnedStart = virtualColumns[numColumns - numPinnedRight]?.start || 0;
|
|
91
|
+
const rightNonPinnedEnd = virtualColumns[numColumns - numPinnedRight - 1]?.end || 0;
|
|
110
92
|
|
|
111
|
-
columnVirtualizer.virtualPaddingLeft =
|
|
112
|
-
leftNonPinnedStart - leftNonPinnedEnd;
|
|
93
|
+
columnVirtualizer.virtualPaddingLeft = leftNonPinnedStart - leftNonPinnedEnd;
|
|
113
94
|
|
|
114
95
|
columnVirtualizer.virtualPaddingRight =
|
|
115
|
-
totalSize -
|
|
116
|
-
rightNonPinnedEnd -
|
|
117
|
-
(numPinnedRight ? totalSize - rightNonPinnedStart : 0);
|
|
96
|
+
totalSize - rightNonPinnedEnd - (numPinnedRight ? totalSize - rightNonPinnedStart : 0);
|
|
118
97
|
}
|
|
119
98
|
|
|
120
99
|
if (columnVirtualizerInstanceRef) {
|
|
121
|
-
|
|
100
|
+
// @ts-expect-error: the ref is typed for the default element generics, this virtualizer uses TScrollElement and TItemElement
|
|
122
101
|
columnVirtualizerInstanceRef.current = columnVirtualizer;
|
|
123
102
|
}
|
|
124
103
|
|
|
125
|
-
return columnVirtualizer
|
|
104
|
+
return columnVirtualizer;
|
|
126
105
|
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { act, render } from '@testing-library/react';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { MaterialReactTable } from '../components/MaterialReactTable';
|
|
5
|
+
import { type MRT_ColumnDef } from '../types';
|
|
6
|
+
|
|
7
|
+
interface Person {
|
|
8
|
+
age: number;
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const data: Person[] = [
|
|
13
|
+
{ age: 30, name: 'John' },
|
|
14
|
+
{ age: 25, name: 'Sara' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const columns: MRT_ColumnDef<Person>[] = [
|
|
18
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
19
|
+
{ accessorKey: 'age', header: 'Age' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
describe('pinned rows', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.useFakeTimers();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
vi.useRealTimers();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('the table stops re-rendering after mount', () => {
|
|
32
|
+
const muiTablePaperProps = vi.fn(() => ({}));
|
|
33
|
+
|
|
34
|
+
render(
|
|
35
|
+
<MaterialReactTable
|
|
36
|
+
columns={columns}
|
|
37
|
+
data={data}
|
|
38
|
+
enableRowPinning
|
|
39
|
+
initialState={{ rowPinning: { bottom: [], top: ['0'] } }}
|
|
40
|
+
muiTablePaperProps={muiTablePaperProps}
|
|
41
|
+
/>,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
act(() => {
|
|
45
|
+
vi.advanceTimersByTime(1000);
|
|
46
|
+
});
|
|
47
|
+
const settledRenders = muiTablePaperProps.mock.calls.length;
|
|
48
|
+
|
|
49
|
+
act(() => {
|
|
50
|
+
vi.advanceTimersByTime(1000);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(muiTablePaperProps).toHaveBeenCalledTimes(settledRenders);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('controlled state effects', () => {
|
|
58
|
+
test('does not reset the column order again when the table re-renders', () => {
|
|
59
|
+
const onColumnOrderChange = vi.fn();
|
|
60
|
+
const table = (isLoading: boolean) => (
|
|
61
|
+
<MaterialReactTable
|
|
62
|
+
columns={columns}
|
|
63
|
+
data={data}
|
|
64
|
+
onColumnOrderChange={onColumnOrderChange}
|
|
65
|
+
state={{ columnOrder: ['name'], isLoading }}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
const { rerender } = render(table(false));
|
|
69
|
+
const mountCalls = onColumnOrderChange.mock.calls.length;
|
|
70
|
+
|
|
71
|
+
rerender(table(true));
|
|
72
|
+
rerender(table(false));
|
|
73
|
+
|
|
74
|
+
expect(onColumnOrderChange).toHaveBeenCalledTimes(mountCalls);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('does not clamp the page index again when the table re-renders', () => {
|
|
78
|
+
const onPaginationChange = vi.fn();
|
|
79
|
+
const table = (showProgressBars: boolean) => (
|
|
80
|
+
<MaterialReactTable
|
|
81
|
+
columns={columns}
|
|
82
|
+
data={data}
|
|
83
|
+
onPaginationChange={onPaginationChange}
|
|
84
|
+
state={{ pagination: { pageIndex: 5, pageSize: 10 }, showProgressBars }}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
const { rerender } = render(table(false));
|
|
88
|
+
const mountCalls = onPaginationChange.mock.calls.length;
|
|
89
|
+
|
|
90
|
+
rerender(table(true));
|
|
91
|
+
rerender(table(false));
|
|
92
|
+
|
|
93
|
+
expect(onPaginationChange).toHaveBeenCalledTimes(mountCalls);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('does not clear the sorting again when the table re-renders', () => {
|
|
97
|
+
const onSortingChange = vi.fn();
|
|
98
|
+
const table = (showProgressBars: boolean) => (
|
|
99
|
+
<MaterialReactTable
|
|
100
|
+
columns={columns}
|
|
101
|
+
data={data}
|
|
102
|
+
onSortingChange={onSortingChange}
|
|
103
|
+
state={{ globalFilter: 'John', showProgressBars, sorting: [] }}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
const { rerender } = render(table(false));
|
|
107
|
+
const mountCalls = onSortingChange.mock.calls.length;
|
|
108
|
+
|
|
109
|
+
rerender(table(true));
|
|
110
|
+
rerender(table(false));
|
|
111
|
+
|
|
112
|
+
expect(onSortingChange).toHaveBeenCalledTimes(mountCalls);
|
|
113
|
+
});
|
|
114
|
+
});
|