material-react-table 0.7.3 → 0.7.6
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/MaterialReactTable.d.ts +19 -21
- package/dist/buttons/MRT_ColumnPinningButtons.d.ts +8 -0
- package/dist/enums.d.ts +1 -1
- package/dist/localization.d.ts +1 -0
- package/dist/material-react-table.cjs.development.js +236 -115
- package/dist/material-react-table.cjs.development.js.map +1 -1
- package/dist/material-react-table.cjs.production.min.js +1 -1
- package/dist/material-react-table.cjs.production.min.js.map +1 -1
- package/dist/material-react-table.esm.js +237 -116
- package/dist/material-react-table.esm.js.map +1 -1
- package/dist/menus/{MRT_FilterTypeMenu.d.ts → MRT_FilterOptionMenu.d.ts} +1 -1
- package/dist/utils.d.ts +6 -6
- package/package.json +7 -7
- package/src/MaterialReactTable.tsx +30 -21
- package/src/buttons/MRT_ColumnPinningButtons.tsx +69 -0
- package/src/enums.ts +1 -1
- package/src/head/MRT_TableHeadCell.tsx +3 -5
- package/src/inputs/MRT_FilterTextField.tsx +16 -16
- package/src/inputs/MRT_SearchTextField.tsx +2 -2
- package/src/localization.ts +2 -0
- package/src/menus/MRT_ColumnActionMenu.tsx +2 -2
- package/src/menus/{MRT_FilterTypeMenu.tsx → MRT_FilterOptionMenu.tsx} +35 -33
- package/src/menus/MRT_ShowHideColumnsMenu.tsx +25 -11
- package/src/menus/MRT_ShowHideColumnsMenuItems.tsx +15 -3
- package/src/table/MRT_Table.tsx +3 -3
- package/src/table/MRT_TableContainer.tsx +16 -6
- package/src/table/MRT_TableRoot.tsx +94 -40
- package/src/utils.ts +10 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { FC, useMemo } from 'react';
|
|
2
2
|
import { Menu, MenuItem } from '@mui/material';
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
3
|
+
import type { MRT_FilterFn, MRT_Header, MRT_TableInstance } from '..';
|
|
4
|
+
import { MRT_FILTER_OPTION } from '../enums';
|
|
5
5
|
import {
|
|
6
6
|
bestMatch,
|
|
7
7
|
bestMatchFirst,
|
|
@@ -30,7 +30,7 @@ interface Props {
|
|
|
30
30
|
tableInstance: MRT_TableInstance;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export const
|
|
33
|
+
export const MRT_FilterOptionMenu: FC<Props> = ({
|
|
34
34
|
anchorEl,
|
|
35
35
|
header,
|
|
36
36
|
onSelect,
|
|
@@ -39,16 +39,16 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
|
|
|
39
39
|
}) => {
|
|
40
40
|
const {
|
|
41
41
|
getState,
|
|
42
|
-
options: {
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
options: { enabledGlobalFilterOptions, localization },
|
|
43
|
+
setCurrentFilterFns,
|
|
44
|
+
setCurrentGlobalFilterFn,
|
|
45
45
|
} = tableInstance;
|
|
46
46
|
|
|
47
|
-
const { isDensePadding,
|
|
47
|
+
const { isDensePadding, currentFilterFns, currentGlobalFilterFn } =
|
|
48
48
|
getState();
|
|
49
49
|
|
|
50
|
-
const
|
|
51
|
-
type:
|
|
50
|
+
const filterOptions: {
|
|
51
|
+
type: MRT_FILTER_OPTION;
|
|
52
52
|
label: string;
|
|
53
53
|
divider: boolean;
|
|
54
54
|
fn: Function;
|
|
@@ -56,104 +56,106 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
|
|
|
56
56
|
() =>
|
|
57
57
|
[
|
|
58
58
|
{
|
|
59
|
-
type:
|
|
59
|
+
type: MRT_FILTER_OPTION.BEST_MATCH_FIRST,
|
|
60
60
|
label: localization.filterBestMatchFirst,
|
|
61
61
|
divider: false,
|
|
62
62
|
fn: bestMatchFirst,
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
type:
|
|
65
|
+
type: MRT_FILTER_OPTION.BEST_MATCH,
|
|
66
66
|
label: localization.filterBestMatch,
|
|
67
67
|
divider: !!header,
|
|
68
68
|
fn: bestMatch,
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
type:
|
|
71
|
+
type: MRT_FILTER_OPTION.CONTAINS,
|
|
72
72
|
label: localization.filterContains,
|
|
73
73
|
divider: false,
|
|
74
74
|
fn: contains,
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
type:
|
|
77
|
+
type: MRT_FILTER_OPTION.STARTS_WITH,
|
|
78
78
|
label: localization.filterStartsWith,
|
|
79
79
|
divider: false,
|
|
80
80
|
fn: startsWith,
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
|
-
type:
|
|
83
|
+
type: MRT_FILTER_OPTION.ENDS_WITH,
|
|
84
84
|
label: localization.filterEndsWith,
|
|
85
85
|
divider: true,
|
|
86
86
|
fn: endsWith,
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
|
-
type:
|
|
89
|
+
type: MRT_FILTER_OPTION.EQUALS,
|
|
90
90
|
label: localization.filterEquals,
|
|
91
91
|
divider: false,
|
|
92
92
|
fn: equals,
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
|
-
type:
|
|
95
|
+
type: MRT_FILTER_OPTION.NOT_EQUALS,
|
|
96
96
|
label: localization.filterNotEquals,
|
|
97
97
|
divider: true,
|
|
98
98
|
fn: notEquals,
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
|
-
type:
|
|
101
|
+
type: MRT_FILTER_OPTION.GREATER_THAN,
|
|
102
102
|
label: localization.filterGreaterThan,
|
|
103
103
|
divider: false,
|
|
104
104
|
fn: greaterThan,
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
|
-
type:
|
|
107
|
+
type: MRT_FILTER_OPTION.LESS_THAN,
|
|
108
108
|
label: localization.filterLessThan,
|
|
109
109
|
divider: true,
|
|
110
110
|
fn: lessThan,
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
|
-
type:
|
|
113
|
+
type: MRT_FILTER_OPTION.EMPTY,
|
|
114
114
|
label: localization.filterEmpty,
|
|
115
115
|
divider: false,
|
|
116
116
|
fn: empty,
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
|
-
type:
|
|
119
|
+
type: MRT_FILTER_OPTION.NOT_EMPTY,
|
|
120
120
|
label: localization.filterNotEmpty,
|
|
121
121
|
divider: false,
|
|
122
122
|
fn: notEmpty,
|
|
123
123
|
},
|
|
124
124
|
].filter((filterType) =>
|
|
125
125
|
header
|
|
126
|
-
? !header.column.
|
|
127
|
-
header.column.
|
|
128
|
-
: (!
|
|
129
|
-
|
|
126
|
+
? !header.column.enabledColumnFilterOptions ||
|
|
127
|
+
header.column.enabledColumnFilterOptions.includes(filterType.type)
|
|
128
|
+
: (!enabledGlobalFilterOptions ||
|
|
129
|
+
enabledGlobalFilterOptions.includes(filterType.type)) &&
|
|
130
130
|
[
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
MRT_FILTER_OPTION.BEST_MATCH_FIRST,
|
|
132
|
+
MRT_FILTER_OPTION.BEST_MATCH,
|
|
133
133
|
].includes(filterType.type),
|
|
134
134
|
),
|
|
135
135
|
[],
|
|
136
136
|
);
|
|
137
137
|
|
|
138
|
-
const handleSelectFilterType = (value:
|
|
138
|
+
const handleSelectFilterType = (value: MRT_FILTER_OPTION) => {
|
|
139
139
|
if (header) {
|
|
140
|
-
|
|
140
|
+
setCurrentFilterFns((prev: { [key: string]: MRT_FilterFn }) => ({
|
|
141
141
|
...prev,
|
|
142
142
|
[header.id]: value,
|
|
143
143
|
}));
|
|
144
|
-
if (
|
|
144
|
+
if (
|
|
145
|
+
[MRT_FILTER_OPTION.EMPTY, MRT_FILTER_OPTION.NOT_EMPTY].includes(value)
|
|
146
|
+
) {
|
|
145
147
|
header.column.setColumnFilterValue(' ');
|
|
146
148
|
}
|
|
147
149
|
} else {
|
|
148
|
-
|
|
150
|
+
setCurrentGlobalFilterFn(value);
|
|
149
151
|
}
|
|
150
152
|
setAnchorEl(null);
|
|
151
153
|
onSelect?.();
|
|
152
154
|
};
|
|
153
155
|
|
|
154
156
|
const filterType = !!header
|
|
155
|
-
?
|
|
156
|
-
:
|
|
157
|
+
? currentFilterFns[header.id]
|
|
158
|
+
: currentGlobalFilterFn;
|
|
157
159
|
|
|
158
160
|
return (
|
|
159
161
|
<Menu
|
|
@@ -165,7 +167,7 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
|
|
|
165
167
|
dense: isDensePadding,
|
|
166
168
|
}}
|
|
167
169
|
>
|
|
168
|
-
{
|
|
170
|
+
{filterOptions.map(({ type, label, divider, fn }, index) => (
|
|
169
171
|
<MenuItem
|
|
170
172
|
divider={divider}
|
|
171
173
|
key={index}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { FC, useMemo } from 'react';
|
|
2
2
|
import { Button, Menu, Divider, Box } from '@mui/material';
|
|
3
3
|
import { MRT_ShowHideColumnsMenuItems } from './MRT_ShowHideColumnsMenuItems';
|
|
4
|
-
import { MRT_TableInstance } from '..';
|
|
4
|
+
import { MRT_Column, MRT_TableInstance } from '..';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
anchorEl: HTMLElement | null;
|
|
@@ -24,7 +24,7 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
|
|
|
24
24
|
getState,
|
|
25
25
|
toggleAllColumnsVisible,
|
|
26
26
|
getAllLeafColumns,
|
|
27
|
-
options: { localization },
|
|
27
|
+
options: { localization, enablePinning },
|
|
28
28
|
} = tableInstance;
|
|
29
29
|
|
|
30
30
|
const { isDensePadding } = getState();
|
|
@@ -40,14 +40,16 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
|
|
|
40
40
|
[getAllColumns()],
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
const allDataColumns = useMemo(() => {
|
|
43
|
+
const allDataColumns: (MRT_Column | null)[] = useMemo(() => {
|
|
44
44
|
const dataColumns = getAllColumns().filter(
|
|
45
45
|
(col) => col.columnDefType !== 'display',
|
|
46
46
|
);
|
|
47
47
|
return getIsSomeColumnsPinned()
|
|
48
48
|
? [
|
|
49
49
|
...dataColumns.filter((c) => c.getIsPinned() === 'left'),
|
|
50
|
+
null,
|
|
50
51
|
...dataColumns.filter((c) => c.getIsPinned() === false),
|
|
52
|
+
null,
|
|
51
53
|
...dataColumns.filter((c) => c.getIsPinned() === 'right'),
|
|
52
54
|
]
|
|
53
55
|
: dataColumns;
|
|
@@ -78,6 +80,14 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
|
|
|
78
80
|
{localization.hideAll}
|
|
79
81
|
</Button>
|
|
80
82
|
)}
|
|
83
|
+
{!isSubMenu && enablePinning && (
|
|
84
|
+
<Button
|
|
85
|
+
disabled={!getIsSomeColumnsPinned()}
|
|
86
|
+
onClick={() => tableInstance.setColumnPinning({})}
|
|
87
|
+
>
|
|
88
|
+
{localization.unpinAll}
|
|
89
|
+
</Button>
|
|
90
|
+
)}
|
|
81
91
|
<Button
|
|
82
92
|
disabled={getIsAllColumnsVisible()}
|
|
83
93
|
onClick={() => toggleAllColumnsVisible(true)}
|
|
@@ -95,14 +105,18 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
|
|
|
95
105
|
/>
|
|
96
106
|
))}
|
|
97
107
|
<Divider />
|
|
98
|
-
{allDataColumns.map((column, index) =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
{allDataColumns.map((column, index) =>
|
|
109
|
+
column ? (
|
|
110
|
+
<MRT_ShowHideColumnsMenuItems
|
|
111
|
+
column={column}
|
|
112
|
+
isSubMenu={isSubMenu}
|
|
113
|
+
key={`${index}-${column.id}`}
|
|
114
|
+
tableInstance={tableInstance}
|
|
115
|
+
/>
|
|
116
|
+
) : (
|
|
117
|
+
<Divider key={`${index}-divider`} />
|
|
118
|
+
),
|
|
119
|
+
)}
|
|
106
120
|
</Menu>
|
|
107
121
|
);
|
|
108
122
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
2
|
import { FormControlLabel, MenuItem, Switch } from '@mui/material';
|
|
3
3
|
import type { MRT_Column, MRT_TableInstance } from '..';
|
|
4
|
-
import {
|
|
4
|
+
import { MRT_ColumnPinningButtons } from '../buttons/MRT_ColumnPinningButtons';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
column: MRT_Column;
|
|
@@ -16,7 +16,7 @@ export const MRT_ShowHideColumnsMenuItems: FC<Props> = ({
|
|
|
16
16
|
}) => {
|
|
17
17
|
const {
|
|
18
18
|
getState,
|
|
19
|
-
options: { onToggleColumnVisibility },
|
|
19
|
+
options: { onToggleColumnVisibility, enablePinning },
|
|
20
20
|
} = tableInstance;
|
|
21
21
|
|
|
22
22
|
const { columnVisibility } = getState();
|
|
@@ -44,8 +44,20 @@ export const MRT_ShowHideColumnsMenuItems: FC<Props> = ({
|
|
|
44
44
|
return (
|
|
45
45
|
<>
|
|
46
46
|
<MenuItem
|
|
47
|
-
sx={{
|
|
47
|
+
sx={{
|
|
48
|
+
alignItems: 'center',
|
|
49
|
+
justifyContent: 'flex-start',
|
|
50
|
+
my: 0,
|
|
51
|
+
pl: `${(column.depth + 0.5) * 2}rem`,
|
|
52
|
+
py: '6px',
|
|
53
|
+
}}
|
|
48
54
|
>
|
|
55
|
+
{!isSubMenu && enablePinning && (
|
|
56
|
+
<MRT_ColumnPinningButtons
|
|
57
|
+
column={column}
|
|
58
|
+
tableInstance={tableInstance}
|
|
59
|
+
/>
|
|
60
|
+
)}
|
|
49
61
|
<FormControlLabel
|
|
50
62
|
componentsProps={{ typography: { sx: { marginBottom: 0 } } }}
|
|
51
63
|
checked={switchChecked}
|
package/src/table/MRT_Table.tsx
CHANGED
|
@@ -14,10 +14,10 @@ export const MRT_Table: FC<Props> = ({ pinned, tableInstance }) => {
|
|
|
14
14
|
const {
|
|
15
15
|
getTableProps,
|
|
16
16
|
options: {
|
|
17
|
-
muiTableProps,
|
|
18
|
-
enableTableHead,
|
|
19
|
-
enableTableFooter,
|
|
20
17
|
enableStickyHeader,
|
|
18
|
+
enableTableFooter,
|
|
19
|
+
enableTableHead,
|
|
20
|
+
muiTableProps,
|
|
21
21
|
},
|
|
22
22
|
} = tableInstance;
|
|
23
23
|
|
|
@@ -30,7 +30,6 @@ interface Props {
|
|
|
30
30
|
export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
31
31
|
const {
|
|
32
32
|
getCenterTableWidth,
|
|
33
|
-
getIsSomeColumnsPinned,
|
|
34
33
|
getLeftTableWidth,
|
|
35
34
|
getRightTableWidth,
|
|
36
35
|
getState,
|
|
@@ -42,7 +41,7 @@ export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
|
42
41
|
},
|
|
43
42
|
} = tableInstance;
|
|
44
43
|
|
|
45
|
-
const { isFullScreen
|
|
44
|
+
const { isFullScreen } = getState();
|
|
46
45
|
|
|
47
46
|
const [totalToolbarHeight, setTotalToolbarHeight] = useState(0);
|
|
48
47
|
|
|
@@ -67,6 +66,9 @@ export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
|
67
66
|
setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
|
|
68
67
|
});
|
|
69
68
|
|
|
69
|
+
const isSomeColumnsPinnedLeft = !!tableInstance.getLeftFlatHeaders().length;
|
|
70
|
+
const isSomeColumnsPinnedRight = !!tableInstance.getRightFlatHeaders().length;
|
|
71
|
+
|
|
70
72
|
return (
|
|
71
73
|
<TableContainer
|
|
72
74
|
{...tableContainerProps}
|
|
@@ -84,7 +86,8 @@ export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
|
84
86
|
: undefined,
|
|
85
87
|
}}
|
|
86
88
|
>
|
|
87
|
-
{enablePinning &&
|
|
89
|
+
{(enablePinning && isSomeColumnsPinnedLeft) ||
|
|
90
|
+
isSomeColumnsPinnedRight ? (
|
|
88
91
|
<Box
|
|
89
92
|
sx={{
|
|
90
93
|
display: 'grid',
|
|
@@ -96,13 +99,20 @@ export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
|
96
99
|
commonBoxStyles({
|
|
97
100
|
pinned: 'left',
|
|
98
101
|
theme,
|
|
99
|
-
visible:
|
|
102
|
+
visible: isSomeColumnsPinnedLeft,
|
|
100
103
|
})
|
|
101
104
|
}
|
|
102
105
|
>
|
|
103
106
|
<MRT_Table pinned="left" tableInstance={tableInstance} />
|
|
104
107
|
</Box>
|
|
105
|
-
<Box
|
|
108
|
+
<Box
|
|
109
|
+
sx={(theme: Theme) =>
|
|
110
|
+
commonBoxStyles({
|
|
111
|
+
theme,
|
|
112
|
+
visible: !!tableInstance.getCenterFlatHeaders().length,
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
>
|
|
106
116
|
<MRT_Table pinned="center" tableInstance={tableInstance} />
|
|
107
117
|
</Box>
|
|
108
118
|
<Box
|
|
@@ -110,7 +120,7 @@ export const MRT_TableContainer: FC<Props> = ({ tableInstance }) => {
|
|
|
110
120
|
commonBoxStyles({
|
|
111
121
|
pinned: 'right',
|
|
112
122
|
theme,
|
|
113
|
-
visible:
|
|
123
|
+
visible: isSomeColumnsPinnedRight,
|
|
114
124
|
})
|
|
115
125
|
}
|
|
116
126
|
>
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
ColumnDef,
|
|
4
|
+
FilterFn,
|
|
3
5
|
PaginationState,
|
|
4
6
|
Table,
|
|
5
7
|
createTable,
|
|
6
8
|
functionalUpdate,
|
|
7
9
|
getColumnFilteredRowModelSync,
|
|
10
|
+
getCoreRowModelSync,
|
|
8
11
|
getExpandedRowModel,
|
|
9
12
|
getGlobalFilteredRowModelSync,
|
|
10
13
|
getGroupedRowModelSync,
|
|
11
14
|
getPaginationRowModel,
|
|
12
15
|
getSortedRowModelSync,
|
|
13
16
|
useTableInstance,
|
|
14
|
-
getCoreRowModelSync,
|
|
15
|
-
ColumnDef,
|
|
16
17
|
} from '@tanstack/react-table';
|
|
17
18
|
import {
|
|
18
19
|
MRT_Cell,
|
|
19
20
|
MRT_ColumnDef,
|
|
20
|
-
|
|
21
|
+
MRT_FilterFn,
|
|
21
22
|
MRT_Row,
|
|
22
23
|
MRT_TableInstance,
|
|
24
|
+
MRT_TableState,
|
|
23
25
|
} from '..';
|
|
24
26
|
import { MRT_ExpandAllButton } from '../buttons/MRT_ExpandAllButton';
|
|
25
27
|
import { MRT_ExpandButton } from '../buttons/MRT_ExpandButton';
|
|
@@ -34,7 +36,7 @@ import {
|
|
|
34
36
|
getAllLeafColumnDefs,
|
|
35
37
|
} from '../utils';
|
|
36
38
|
import { defaultFilterFNs } from '../filtersFNs';
|
|
37
|
-
import {
|
|
39
|
+
import { MRT_FILTER_OPTION } from '../enums';
|
|
38
40
|
import { Box, Dialog, Grow } from '@mui/material';
|
|
39
41
|
|
|
40
42
|
export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
@@ -47,50 +49,75 @@ export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
|
47
49
|
[props.idPrefix],
|
|
48
50
|
);
|
|
49
51
|
|
|
52
|
+
const initialState: Partial<MRT_TableState<D>> = useMemo(() => {
|
|
53
|
+
if (!props.enablePersistentState || !props.idPrefix) {
|
|
54
|
+
return props.initialState;
|
|
55
|
+
}
|
|
56
|
+
if (typeof window === 'undefined') {
|
|
57
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
58
|
+
console.error(
|
|
59
|
+
'The MRT Persistent Table State feature is not supported if using SSR, but you can wrap your <MaterialReactTable /> in a MUI <NoSsr> tags to let it work',
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return props.initialState;
|
|
63
|
+
}
|
|
64
|
+
const storedState =
|
|
65
|
+
props.persistentStateMode === 'localStorage'
|
|
66
|
+
? localStorage.getItem(`mrt-${idPrefix}-table-state`)
|
|
67
|
+
: props.persistentStateMode === 'sessionStorage'
|
|
68
|
+
? sessionStorage.getItem(`mrt-${idPrefix}-table-state`)
|
|
69
|
+
: '{}';
|
|
70
|
+
if (storedState) {
|
|
71
|
+
const parsedState = JSON.parse(storedState);
|
|
72
|
+
if (parsedState) {
|
|
73
|
+
return { ...props.initialState, ...parsedState };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return props.initialState;
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
50
79
|
const [currentEditingCell, setCurrentEditingCell] =
|
|
51
|
-
useState<MRT_Cell<D> | null>(
|
|
52
|
-
props.initialState?.currentEditingCell ?? null,
|
|
53
|
-
);
|
|
80
|
+
useState<MRT_Cell<D> | null>(initialState?.currentEditingCell ?? null);
|
|
54
81
|
const [currentEditingRow, setCurrentEditingRow] = useState<MRT_Row<D> | null>(
|
|
55
|
-
|
|
82
|
+
initialState?.currentEditingRow ?? null,
|
|
56
83
|
);
|
|
57
84
|
const [isDensePadding, setIsDensePadding] = useState(
|
|
58
|
-
|
|
85
|
+
initialState?.isDensePadding ?? false,
|
|
59
86
|
);
|
|
60
87
|
const [isFullScreen, setIsFullScreen] = useState(
|
|
61
|
-
|
|
88
|
+
initialState?.isFullScreen ?? false,
|
|
62
89
|
);
|
|
63
90
|
const [showFilters, setShowFilters] = useState(
|
|
64
|
-
|
|
91
|
+
initialState?.showFilters ?? false,
|
|
65
92
|
);
|
|
66
93
|
const [showGlobalFilter, setShowGlobalFilter] = useState(
|
|
67
|
-
|
|
94
|
+
initialState?.showGlobalFilter ?? false,
|
|
68
95
|
);
|
|
69
96
|
const [pagination, setPagination] = useState<PaginationState>({
|
|
70
|
-
pageIndex:
|
|
71
|
-
pageSize:
|
|
72
|
-
pageCount:
|
|
97
|
+
pageIndex: initialState?.pagination?.pageIndex ?? 0,
|
|
98
|
+
pageSize: initialState?.pagination?.pageSize ?? 10,
|
|
99
|
+
pageCount: initialState?.pagination?.pageCount ?? -1,
|
|
73
100
|
});
|
|
74
101
|
|
|
75
|
-
const [
|
|
76
|
-
[key: string]:
|
|
102
|
+
const [currentFilterFns, setCurrentFilterFns] = useState<{
|
|
103
|
+
[key: string]: MRT_FilterFn;
|
|
77
104
|
}>(() =>
|
|
78
105
|
Object.assign(
|
|
79
106
|
{},
|
|
80
107
|
...getAllLeafColumnDefs(props.columns as MRT_ColumnDef[]).map((c) => ({
|
|
81
108
|
[c.id as string]:
|
|
82
|
-
c.
|
|
83
|
-
|
|
109
|
+
c.filterFn ??
|
|
110
|
+
initialState?.currentFilterFns?.[c.id] ??
|
|
84
111
|
(!!c.filterSelectOptions?.length
|
|
85
|
-
?
|
|
86
|
-
:
|
|
112
|
+
? MRT_FILTER_OPTION.EQUALS
|
|
113
|
+
: MRT_FILTER_OPTION.BEST_MATCH),
|
|
87
114
|
})),
|
|
88
115
|
),
|
|
89
116
|
);
|
|
90
117
|
|
|
91
|
-
const [
|
|
92
|
-
|
|
93
|
-
);
|
|
118
|
+
const [currentGlobalFilterFn, setCurrentGlobalFilterFn] = useState<
|
|
119
|
+
MRT_FILTER_OPTION | FilterFn<D> | string | number | symbol
|
|
120
|
+
>(props.globalFilterFn ?? MRT_FILTER_OPTION.BEST_MATCH_FIRST);
|
|
94
121
|
|
|
95
122
|
const table = useMemo(() => createTable() as unknown as Table<D>, []);
|
|
96
123
|
|
|
@@ -177,11 +204,11 @@ export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
|
177
204
|
...displayColumns,
|
|
178
205
|
...props.columns.map((column) =>
|
|
179
206
|
column.columns
|
|
180
|
-
? createGroup(table, column,
|
|
181
|
-
: createDataColumn(table, column,
|
|
207
|
+
? createGroup(table, column, currentFilterFns)
|
|
208
|
+
: createDataColumn(table, column, currentFilterFns),
|
|
182
209
|
),
|
|
183
210
|
] as ColumnDef<D>[]),
|
|
184
|
-
[table, props.columns,
|
|
211
|
+
[table, props.columns, currentFilterFns],
|
|
185
212
|
);
|
|
186
213
|
|
|
187
214
|
const data: D['Row'][] = useMemo(
|
|
@@ -205,7 +232,7 @@ export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
|
205
232
|
const tableInstance: MRT_TableInstance<{}> = {
|
|
206
233
|
...useTableInstance(table, {
|
|
207
234
|
//@ts-ignore
|
|
208
|
-
|
|
235
|
+
filterFns: defaultFilterFNs,
|
|
209
236
|
getColumnFilteredRowModel: getColumnFilteredRowModelSync(),
|
|
210
237
|
getCoreRowModel: getCoreRowModelSync(),
|
|
211
238
|
getExpandedRowModel: getExpandedRowModel(),
|
|
@@ -214,18 +241,20 @@ export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
|
214
241
|
getPaginationRowModel: getPaginationRowModel(),
|
|
215
242
|
getSortedRowModel: getSortedRowModelSync(),
|
|
216
243
|
getSubRows: (originalRow: D) => originalRow.subRows,
|
|
217
|
-
|
|
218
|
-
idPrefix,
|
|
244
|
+
globalFilterFn: currentGlobalFilterFn,
|
|
219
245
|
onPaginationChange: (updater: any) =>
|
|
220
246
|
setPagination((old) => functionalUpdate(updater, old)),
|
|
221
247
|
...props,
|
|
222
248
|
columns,
|
|
223
249
|
data,
|
|
250
|
+
idPrefix,
|
|
251
|
+
//@ts-ignore
|
|
252
|
+
initialState,
|
|
224
253
|
state: {
|
|
225
254
|
currentEditingCell,
|
|
226
255
|
currentEditingRow,
|
|
227
|
-
|
|
228
|
-
|
|
256
|
+
currentFilterFns,
|
|
257
|
+
currentGlobalFilterFn,
|
|
229
258
|
isDensePadding,
|
|
230
259
|
isFullScreen,
|
|
231
260
|
//@ts-ignore
|
|
@@ -239,31 +268,56 @@ export const MRT_TableRoot = <D extends Record<string, any> = {}>(
|
|
|
239
268
|
setCurrentEditingCell,
|
|
240
269
|
//@ts-ignore
|
|
241
270
|
setCurrentEditingRow,
|
|
242
|
-
|
|
243
|
-
|
|
271
|
+
setCurrentFilterFns,
|
|
272
|
+
//@ts-ignore
|
|
273
|
+
setCurrentGlobalFilterFn,
|
|
244
274
|
setIsDensePadding,
|
|
245
275
|
setIsFullScreen,
|
|
246
276
|
setShowFilters,
|
|
247
277
|
setShowGlobalFilter,
|
|
248
278
|
};
|
|
249
279
|
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
if (typeof window === 'undefined' || !props.enablePersistentState) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (!props.idPrefix && process.env.NODE_ENV !== 'production') {
|
|
285
|
+
console.warn(
|
|
286
|
+
'a unique idPrefix prop is required for persistent table state to work',
|
|
287
|
+
);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const itemArgs: [string, string] = [
|
|
291
|
+
`mrt-${idPrefix}-table-state`,
|
|
292
|
+
JSON.stringify(tableInstance.getState()),
|
|
293
|
+
];
|
|
294
|
+
if (props.persistentStateMode === 'localStorage') {
|
|
295
|
+
localStorage.setItem(...itemArgs);
|
|
296
|
+
} else if (props.persistentStateMode === 'sessionStorage') {
|
|
297
|
+
sessionStorage.setItem(...itemArgs);
|
|
298
|
+
}
|
|
299
|
+
}, [
|
|
300
|
+
props.enablePersistentState,
|
|
301
|
+
props.idPrefix,
|
|
302
|
+
props.persistentStateMode,
|
|
303
|
+
tableInstance,
|
|
304
|
+
]);
|
|
305
|
+
|
|
250
306
|
return (
|
|
251
307
|
<>
|
|
252
308
|
<Dialog
|
|
253
|
-
TransitionComponent={Grow}
|
|
254
309
|
PaperComponent={Box}
|
|
310
|
+
TransitionComponent={Grow}
|
|
255
311
|
disablePortal
|
|
256
312
|
fullScreen
|
|
257
313
|
keepMounted={false}
|
|
258
|
-
onClose={() =>
|
|
259
|
-
open={
|
|
314
|
+
onClose={() => setIsFullScreen(false)}
|
|
315
|
+
open={isFullScreen}
|
|
260
316
|
transitionDuration={400}
|
|
261
317
|
>
|
|
262
318
|
<MRT_TablePaper tableInstance={tableInstance} />
|
|
263
319
|
</Dialog>
|
|
264
|
-
{!
|
|
265
|
-
<MRT_TablePaper tableInstance={tableInstance} />
|
|
266
|
-
)}
|
|
320
|
+
{!isFullScreen && <MRT_TablePaper tableInstance={tableInstance} />}
|
|
267
321
|
</>
|
|
268
322
|
);
|
|
269
323
|
};
|
package/src/utils.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ColumnDef, Table } from '@tanstack/react-table';
|
|
2
|
-
import { MRT_ColumnDef,
|
|
3
|
-
import {
|
|
2
|
+
import { MRT_ColumnDef, MRT_FilterFn } from '.';
|
|
3
|
+
import { MRT_FILTER_OPTION } from './enums';
|
|
4
4
|
import { defaultFilterFNs } from './filtersFNs';
|
|
5
5
|
|
|
6
6
|
export const getAllLeafColumnDefs = (
|
|
@@ -24,31 +24,31 @@ export const getAllLeafColumnDefs = (
|
|
|
24
24
|
export const createGroup = <D extends Record<string, any> = {}>(
|
|
25
25
|
table: Table<D>,
|
|
26
26
|
column: MRT_ColumnDef<D>,
|
|
27
|
-
|
|
27
|
+
currentFilterFns: { [key: string]: MRT_FilterFn },
|
|
28
28
|
): ColumnDef<D> =>
|
|
29
29
|
table.createGroup({
|
|
30
30
|
...column,
|
|
31
31
|
columns: column?.columns?.map?.((col) =>
|
|
32
32
|
col.columns
|
|
33
|
-
? createGroup<D>(table, col,
|
|
34
|
-
: createDataColumn(table, col,
|
|
33
|
+
? createGroup<D>(table, col, currentFilterFns)
|
|
34
|
+
: createDataColumn(table, col, currentFilterFns),
|
|
35
35
|
),
|
|
36
36
|
} as any);
|
|
37
37
|
|
|
38
38
|
export const createDataColumn = <D extends Record<string, any> = {}>(
|
|
39
39
|
table: Table<D>,
|
|
40
40
|
column: MRT_ColumnDef<D>,
|
|
41
|
-
|
|
41
|
+
currentFilterFns: { [key: string]: MRT_FilterFn },
|
|
42
42
|
): ColumnDef<D> => // @ts-ignore
|
|
43
43
|
table.createDataColumn(column.id, {
|
|
44
44
|
filterFn:
|
|
45
|
-
|
|
46
|
-
?
|
|
47
|
-
: defaultFilterFNs[
|
|
45
|
+
currentFilterFns[column.id] instanceof Function
|
|
46
|
+
? currentFilterFns[column.id]
|
|
47
|
+
: defaultFilterFNs[currentFilterFns[column.id] as MRT_FILTER_OPTION],
|
|
48
48
|
...column,
|
|
49
49
|
}) as any;
|
|
50
50
|
|
|
51
51
|
export const createDisplayColumn = <D extends Record<string, any> = {}>(
|
|
52
52
|
table: Table<D>,
|
|
53
53
|
column: Omit<MRT_ColumnDef<D>, 'header'> & { header?: string },
|
|
54
|
-
): ColumnDef<D> => table.createDisplayColumn(column);
|
|
54
|
+
): ColumnDef<D> => table.createDisplayColumn(column as ColumnDef<D>);
|