material-react-table 0.26.6 → 0.29.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 +7 -8
- package/dist/MaterialReactTable.d.ts +11 -7
- package/dist/column.utils.d.ts +1 -0
- package/dist/inputs/MRT_FilterTextField.d.ts +1 -1
- package/dist/localization.d.ts +9 -0
- package/dist/material-react-table.cjs.development.js +214 -146
- 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 +215 -147
- package/dist/material-react-table.esm.js.map +1 -1
- package/dist/menus/MRT_FilterOptionMenu.d.ts +7 -0
- package/package.json +5 -5
- package/src/MaterialReactTable.tsx +15 -7
- package/src/body/MRT_TableBody.tsx +12 -12
- package/src/body/MRT_TableBodyCell.tsx +7 -1
- package/src/buttons/MRT_ExpandAllButton.tsx +1 -0
- package/src/column.utils.ts +13 -0
- package/src/head/MRT_TableHeadCell.tsx +2 -4
- package/src/head/MRT_TableHeadCellFilterContainer.tsx +3 -1
- package/src/head/MRT_TableHeadCellFilterLabel.tsx +8 -3
- package/src/inputs/MRT_FilterRangeFields.tsx +2 -2
- package/src/inputs/MRT_FilterTextField.tsx +124 -84
- package/src/inputs/MRT_SelectCheckbox.tsx +3 -3
- package/src/localization.ts +18 -0
- package/src/menus/MRT_ColumnActionMenu.tsx +2 -2
- package/src/menus/MRT_FilterOptionMenu.tsx +103 -101
- package/src/table/MRT_TableRoot.tsx +2 -1
|
@@ -6,10 +6,13 @@ import React, {
|
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {
|
|
9
|
+
Box,
|
|
10
|
+
Checkbox,
|
|
9
11
|
Chip,
|
|
10
12
|
debounce,
|
|
11
13
|
IconButton,
|
|
12
14
|
InputAdornment,
|
|
15
|
+
ListItemText,
|
|
13
16
|
MenuItem,
|
|
14
17
|
TextField,
|
|
15
18
|
TextFieldProps,
|
|
@@ -20,20 +23,20 @@ import type { MRT_Header, MRT_TableInstance } from '..';
|
|
|
20
23
|
|
|
21
24
|
interface Props {
|
|
22
25
|
header: MRT_Header;
|
|
23
|
-
|
|
26
|
+
rangeFilterIndex?: number;
|
|
24
27
|
table: MRT_TableInstance;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export const MRT_FilterTextField: FC<Props> = ({
|
|
28
31
|
header,
|
|
29
|
-
|
|
32
|
+
rangeFilterIndex,
|
|
30
33
|
table,
|
|
31
34
|
}) => {
|
|
32
35
|
const {
|
|
33
36
|
getState,
|
|
34
37
|
options: {
|
|
35
38
|
enableColumnFilterChangeMode,
|
|
36
|
-
|
|
39
|
+
columnFilterModeOptions,
|
|
37
40
|
icons: { FilterListIcon, CloseIcon },
|
|
38
41
|
localization,
|
|
39
42
|
muiTableHeadCellFilterTextFieldProps,
|
|
@@ -45,11 +48,13 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
45
48
|
const { columnDef } = column;
|
|
46
49
|
const { currentFilterFns } = getState();
|
|
47
50
|
|
|
48
|
-
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
49
|
-
|
|
50
51
|
const mTableHeadCellFilterTextFieldProps =
|
|
51
52
|
muiTableHeadCellFilterTextFieldProps instanceof Function
|
|
52
|
-
? muiTableHeadCellFilterTextFieldProps({
|
|
53
|
+
? muiTableHeadCellFilterTextFieldProps({
|
|
54
|
+
column,
|
|
55
|
+
table,
|
|
56
|
+
rangeFilterIndex,
|
|
57
|
+
})
|
|
53
58
|
: muiTableHeadCellFilterTextFieldProps;
|
|
54
59
|
|
|
55
60
|
const mcTableHeadCellFilterTextFieldProps =
|
|
@@ -57,6 +62,7 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
57
62
|
? columnDef.muiTableHeadCellFilterTextFieldProps({
|
|
58
63
|
column,
|
|
59
64
|
table,
|
|
65
|
+
rangeFilterIndex,
|
|
60
66
|
})
|
|
61
67
|
: columnDef.muiTableHeadCellFilterTextFieldProps;
|
|
62
68
|
|
|
@@ -65,28 +71,71 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
65
71
|
...mcTableHeadCellFilterTextFieldProps,
|
|
66
72
|
} as TextFieldProps;
|
|
67
73
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
const isRangeFilter =
|
|
75
|
+
columnDef.filterVariant === 'range' || rangeFilterIndex !== undefined;
|
|
76
|
+
const isSelectFilter = columnDef.filterVariant === 'select';
|
|
77
|
+
const isMultiSelectFilter = columnDef.filterVariant === 'multiSelect';
|
|
78
|
+
const isTextboxFilter = !isSelectFilter && !isMultiSelectFilter;
|
|
79
|
+
|
|
80
|
+
const currentFilterOption = currentFilterFns?.[header.id];
|
|
81
|
+
const filterId = `mrt-${tableId}-${header.id}-filter-text-field${
|
|
82
|
+
rangeFilterIndex ?? ''
|
|
83
|
+
}`;
|
|
84
|
+
const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption)
|
|
85
|
+
? //@ts-ignore
|
|
86
|
+
localization[
|
|
87
|
+
`filter${
|
|
88
|
+
currentFilterOption?.charAt?.(0)?.toUpperCase() +
|
|
89
|
+
currentFilterOption?.slice(1)
|
|
90
|
+
}`
|
|
91
|
+
]
|
|
92
|
+
: '';
|
|
93
|
+
const filterPlaceholder = !isRangeFilter
|
|
94
|
+
? localization.filterByColumn?.replace('{column}', String(columnDef.header))
|
|
95
|
+
: rangeFilterIndex === 0
|
|
96
|
+
? localization.min
|
|
97
|
+
: rangeFilterIndex === 1
|
|
98
|
+
? localization.max
|
|
99
|
+
: '';
|
|
100
|
+
const allowedColumnFilterOptions =
|
|
101
|
+
columnDef?.columnFilterModeOptions ?? columnFilterModeOptions;
|
|
102
|
+
const showChangeModeButton =
|
|
103
|
+
enableColumnFilterChangeMode &&
|
|
104
|
+
columnDef.enableColumnFilterChangeMode !== false &&
|
|
105
|
+
!rangeFilterIndex &&
|
|
106
|
+
(allowedColumnFilterOptions === undefined ||
|
|
107
|
+
!!allowedColumnFilterOptions?.length);
|
|
108
|
+
|
|
109
|
+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
110
|
+
const [filterValue, setFilterValue] = useState<string | string[]>(() =>
|
|
111
|
+
isMultiSelectFilter
|
|
112
|
+
? (column.getFilterValue() as string[]) || []
|
|
113
|
+
: isRangeFilter
|
|
114
|
+
? (column.getFilterValue() as [string, string])?.[
|
|
115
|
+
rangeFilterIndex as number
|
|
116
|
+
] || []
|
|
71
117
|
: (column.getFilterValue() as string) ?? '',
|
|
72
118
|
);
|
|
73
119
|
|
|
74
120
|
const handleChangeDebounced = useCallback(
|
|
75
|
-
debounce(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
121
|
+
debounce(
|
|
122
|
+
(event: ChangeEvent<HTMLInputElement>) => {
|
|
123
|
+
let value =
|
|
124
|
+
textFieldProps.type === 'date'
|
|
125
|
+
? new Date(event.target.value)
|
|
126
|
+
: event.target.value;
|
|
127
|
+
if (isRangeFilter) {
|
|
128
|
+
column.setFilterValue((old: [string, string | Date]) => {
|
|
129
|
+
const newFilterValues = old ?? ['', ''];
|
|
130
|
+
newFilterValues[rangeFilterIndex as number] = value;
|
|
131
|
+
return newFilterValues;
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
column.setFilterValue(value ?? undefined);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
isTextboxFilter ? 200 : 1,
|
|
138
|
+
),
|
|
90
139
|
[],
|
|
91
140
|
);
|
|
92
141
|
|
|
@@ -95,24 +144,24 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
95
144
|
handleChangeDebounced(event);
|
|
96
145
|
};
|
|
97
146
|
|
|
98
|
-
const handleFilterMenuOpen = (event: MouseEvent<HTMLElement>) => {
|
|
99
|
-
setAnchorEl(event.currentTarget);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
147
|
const handleClear = () => {
|
|
103
|
-
|
|
104
|
-
|
|
148
|
+
if (isMultiSelectFilter) {
|
|
149
|
+
setFilterValue([]);
|
|
150
|
+
column.setFilterValue([]);
|
|
151
|
+
} else if (isRangeFilter) {
|
|
152
|
+
setFilterValue('');
|
|
105
153
|
column.setFilterValue((old: [string | undefined, string | undefined]) => {
|
|
106
154
|
const newFilterValues = old ?? ['', ''];
|
|
107
|
-
newFilterValues[
|
|
155
|
+
newFilterValues[rangeFilterIndex as number] = undefined;
|
|
108
156
|
return newFilterValues;
|
|
109
157
|
});
|
|
110
158
|
} else {
|
|
159
|
+
setFilterValue('');
|
|
111
160
|
column.setFilterValue(undefined);
|
|
112
161
|
}
|
|
113
162
|
};
|
|
114
163
|
|
|
115
|
-
const
|
|
164
|
+
const handleClearEmptyFilterChip = () => {
|
|
116
165
|
setFilterValue('');
|
|
117
166
|
column.setFilterValue(undefined);
|
|
118
167
|
setCurrentFilterFns((prev) => ({
|
|
@@ -121,47 +170,14 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
121
170
|
}));
|
|
122
171
|
};
|
|
123
172
|
|
|
173
|
+
const handleFilterMenuOpen = (event: MouseEvent<HTMLElement>) => {
|
|
174
|
+
setAnchorEl(event.currentTarget);
|
|
175
|
+
};
|
|
176
|
+
|
|
124
177
|
if (columnDef.Filter) {
|
|
125
178
|
return <>{columnDef.Filter?.({ header, table })}</>;
|
|
126
179
|
}
|
|
127
180
|
|
|
128
|
-
const filterId = `mrt-${tableId}-${header.id}-filter-text-field${
|
|
129
|
-
inputIndex ?? ''
|
|
130
|
-
}`;
|
|
131
|
-
const currentFilterOption = currentFilterFns?.[header.id];
|
|
132
|
-
const isSelectFilter = !!columnDef.filterSelectOptions;
|
|
133
|
-
const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption)
|
|
134
|
-
? //@ts-ignore
|
|
135
|
-
localization[
|
|
136
|
-
`filter${
|
|
137
|
-
currentFilterOption?.charAt(0)?.toUpperCase() +
|
|
138
|
-
currentFilterOption?.slice(1)
|
|
139
|
-
}`
|
|
140
|
-
]
|
|
141
|
-
: '';
|
|
142
|
-
const filterPlaceholder =
|
|
143
|
-
inputIndex === undefined
|
|
144
|
-
? localization.filterByColumn?.replace(
|
|
145
|
-
'{column}',
|
|
146
|
-
String(columnDef.header),
|
|
147
|
-
)
|
|
148
|
-
: inputIndex === 0
|
|
149
|
-
? localization.min
|
|
150
|
-
: inputIndex === 1
|
|
151
|
-
? localization.max
|
|
152
|
-
: '';
|
|
153
|
-
|
|
154
|
-
const allowedColumnFilterOptions =
|
|
155
|
-
columnDef?.enabledColumnFilterOptions ?? enabledColumnFilterOptions;
|
|
156
|
-
|
|
157
|
-
const showChangeModeButton =
|
|
158
|
-
enableColumnFilterChangeMode &&
|
|
159
|
-
columnDef.enableColumnFilterChangeMode !== false &&
|
|
160
|
-
!isSelectFilter &&
|
|
161
|
-
!inputIndex &&
|
|
162
|
-
(allowedColumnFilterOptions === undefined ||
|
|
163
|
-
!!allowedColumnFilterOptions?.length);
|
|
164
|
-
|
|
165
181
|
return (
|
|
166
182
|
<>
|
|
167
183
|
<TextField
|
|
@@ -200,12 +216,14 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
200
216
|
}}
|
|
201
217
|
margin="none"
|
|
202
218
|
placeholder={
|
|
203
|
-
filterChipLabel || isSelectFilter
|
|
219
|
+
filterChipLabel || isSelectFilter || isMultiSelectFilter
|
|
220
|
+
? undefined
|
|
221
|
+
: filterPlaceholder
|
|
204
222
|
}
|
|
205
223
|
onChange={handleChange}
|
|
206
224
|
onClick={(e: MouseEvent<HTMLInputElement>) => e.stopPropagation()}
|
|
207
|
-
select={isSelectFilter}
|
|
208
|
-
value={filterValue
|
|
225
|
+
select={isSelectFilter || isMultiSelectFilter}
|
|
226
|
+
value={filterValue}
|
|
209
227
|
variant="standard"
|
|
210
228
|
InputProps={{
|
|
211
229
|
startAdornment: showChangeModeButton ? (
|
|
@@ -224,7 +242,7 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
224
242
|
</Tooltip>
|
|
225
243
|
{filterChipLabel && (
|
|
226
244
|
<Chip
|
|
227
|
-
onDelete={
|
|
245
|
+
onDelete={handleClearEmptyFilterChip}
|
|
228
246
|
label={filterChipLabel}
|
|
229
247
|
/>
|
|
230
248
|
)}
|
|
@@ -236,7 +254,6 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
236
254
|
<InputAdornment position="end">
|
|
237
255
|
<Tooltip
|
|
238
256
|
arrow
|
|
239
|
-
disableHoverListener={isSelectFilter}
|
|
240
257
|
placement="right"
|
|
241
258
|
title={localization.clearFilter ?? ''}
|
|
242
259
|
>
|
|
@@ -258,11 +275,26 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
258
275
|
</InputAdornment>
|
|
259
276
|
),
|
|
260
277
|
}}
|
|
278
|
+
SelectProps={{
|
|
279
|
+
displayEmpty: true,
|
|
280
|
+
multiple: isMultiSelectFilter,
|
|
281
|
+
renderValue: isMultiSelectFilter
|
|
282
|
+
? (selected: any) =>
|
|
283
|
+
!selected?.length ? (
|
|
284
|
+
<Box sx={{ opacity: 0.5 }}>{filterPlaceholder}</Box>
|
|
285
|
+
) : (
|
|
286
|
+
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: '2px' }}>
|
|
287
|
+
{(selected as string[])?.map((value) => (
|
|
288
|
+
<Chip key={value} label={value} />
|
|
289
|
+
))}
|
|
290
|
+
</Box>
|
|
291
|
+
)
|
|
292
|
+
: undefined,
|
|
293
|
+
}}
|
|
261
294
|
{...textFieldProps}
|
|
262
295
|
sx={(theme) => ({
|
|
263
|
-
m: '-0.25rem',
|
|
264
296
|
p: 0,
|
|
265
|
-
minWidth: !filterChipLabel ? '
|
|
297
|
+
minWidth: !filterChipLabel ? '6rem' : 'auto',
|
|
266
298
|
width: 'calc(100% + 0.5rem)',
|
|
267
299
|
'& .MuiSelect-icon': {
|
|
268
300
|
mr: '1.5rem',
|
|
@@ -272,24 +304,32 @@ export const MRT_FilterTextField: FC<Props> = ({
|
|
|
272
304
|
: (textFieldProps?.sx as any)),
|
|
273
305
|
})}
|
|
274
306
|
>
|
|
275
|
-
{isSelectFilter && (
|
|
276
|
-
<MenuItem divider disabled
|
|
277
|
-
{
|
|
307
|
+
{(isSelectFilter || isMultiSelectFilter) && (
|
|
308
|
+
<MenuItem divider disabled hidden value="">
|
|
309
|
+
<Box sx={{ opacity: 0.5 }}>{filterPlaceholder}</Box>
|
|
278
310
|
</MenuItem>
|
|
279
311
|
)}
|
|
280
312
|
{columnDef?.filterSelectOptions?.map((option) => {
|
|
281
|
-
let value;
|
|
282
|
-
let text;
|
|
283
|
-
if (typeof option
|
|
313
|
+
let value: string;
|
|
314
|
+
let text: string;
|
|
315
|
+
if (typeof option !== 'object') {
|
|
284
316
|
value = option;
|
|
285
317
|
text = option;
|
|
286
|
-
} else
|
|
318
|
+
} else {
|
|
287
319
|
value = option.value;
|
|
288
320
|
text = option.text;
|
|
289
321
|
}
|
|
290
322
|
return (
|
|
291
323
|
<MenuItem key={value} value={value}>
|
|
292
|
-
{
|
|
324
|
+
{isMultiSelectFilter && (
|
|
325
|
+
<Checkbox
|
|
326
|
+
checked={(
|
|
327
|
+
(column.getFilterValue() ?? []) as string[]
|
|
328
|
+
).includes(value)}
|
|
329
|
+
sx={{ mr: '0.5rem' }}
|
|
330
|
+
/>
|
|
331
|
+
)}
|
|
332
|
+
<ListItemText>{text}</ListItemText>
|
|
293
333
|
</MenuItem>
|
|
294
334
|
);
|
|
295
335
|
})}
|
|
@@ -59,9 +59,9 @@ export const MRT_SelectCheckbox: FC<Props> = ({ row, selectAll, table }) => {
|
|
|
59
59
|
size={density === 'compact' ? 'small' : 'medium'}
|
|
60
60
|
{...checkboxProps}
|
|
61
61
|
sx={(theme) => ({
|
|
62
|
-
height: density === 'compact' ? '1.
|
|
63
|
-
width: density === 'compact' ? '1.
|
|
64
|
-
m: '-
|
|
62
|
+
height: density === 'compact' ? '1.75rem' : '2.5rem',
|
|
63
|
+
width: density === 'compact' ? '1.75rem' : '2.5rem',
|
|
64
|
+
m: density !== 'compact' ? '-0.4rem' : undefined,
|
|
65
65
|
...(checkboxProps?.sx instanceof Function
|
|
66
66
|
? checkboxProps.sx(theme)
|
|
67
67
|
: (checkboxProps?.sx as any)),
|
package/src/localization.ts
CHANGED
|
@@ -13,6 +13,9 @@ export interface MRT_Localization {
|
|
|
13
13
|
edit: string;
|
|
14
14
|
expand: string;
|
|
15
15
|
expandAll: string;
|
|
16
|
+
filterArrIncludes: string;
|
|
17
|
+
filterArrIncludesAll: string;
|
|
18
|
+
filterArrIncludesSome: string;
|
|
16
19
|
filterBetween: string;
|
|
17
20
|
filterBetweenInclusive: string;
|
|
18
21
|
filterByColumn: string;
|
|
@@ -20,15 +23,20 @@ export interface MRT_Localization {
|
|
|
20
23
|
filterEmpty: string;
|
|
21
24
|
filterEndsWith: string;
|
|
22
25
|
filterEquals: string;
|
|
26
|
+
filterEqualsString: string;
|
|
23
27
|
filterFuzzy: string;
|
|
24
28
|
filterGreaterThan: string;
|
|
25
29
|
filterGreaterThanOrEqualTo: string;
|
|
30
|
+
filterInNumberRange: string;
|
|
31
|
+
filterIncludesString: string;
|
|
32
|
+
filterIncludesStringSensitive: string;
|
|
26
33
|
filterLessThan: string;
|
|
27
34
|
filterLessThanOrEqualTo: string;
|
|
28
35
|
filterMode: string;
|
|
29
36
|
filterNotEmpty: string;
|
|
30
37
|
filterNotEquals: string;
|
|
31
38
|
filterStartsWith: string;
|
|
39
|
+
filterWeakEquals: string;
|
|
32
40
|
filteringByColumn: string;
|
|
33
41
|
grab: string;
|
|
34
42
|
groupByColumn: string;
|
|
@@ -38,6 +46,7 @@ export interface MRT_Localization {
|
|
|
38
46
|
max: string;
|
|
39
47
|
min: string;
|
|
40
48
|
move: string;
|
|
49
|
+
or: string;
|
|
41
50
|
pinToLeft: string;
|
|
42
51
|
pinToRight: string;
|
|
43
52
|
resetColumnSize: string;
|
|
@@ -85,6 +94,9 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
|
|
|
85
94
|
edit: 'Edit',
|
|
86
95
|
expand: 'Expand',
|
|
87
96
|
expandAll: 'Expand all',
|
|
97
|
+
filterArrIncludes: 'Includes',
|
|
98
|
+
filterArrIncludesAll: 'Includes all',
|
|
99
|
+
filterArrIncludesSome: 'Includes',
|
|
88
100
|
filterBetween: 'Between',
|
|
89
101
|
filterBetweenInclusive: 'Between Inclusive',
|
|
90
102
|
filterByColumn: 'Filter by {column}',
|
|
@@ -92,15 +104,20 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
|
|
|
92
104
|
filterEmpty: 'Empty',
|
|
93
105
|
filterEndsWith: 'Ends With',
|
|
94
106
|
filterEquals: 'Equals',
|
|
107
|
+
filterEqualsString: 'Equals',
|
|
95
108
|
filterFuzzy: 'Fuzzy',
|
|
96
109
|
filterGreaterThan: 'Greater Than',
|
|
97
110
|
filterGreaterThanOrEqualTo: 'Greater Than Or Equal To',
|
|
111
|
+
filterInNumberRange: 'Between',
|
|
112
|
+
filterIncludesString: 'Contains',
|
|
113
|
+
filterIncludesStringSensitive: 'Contains',
|
|
98
114
|
filterLessThan: 'Less Than',
|
|
99
115
|
filterLessThanOrEqualTo: 'Less Than Or Equal To',
|
|
100
116
|
filterMode: 'Filter Mode: {filterType}',
|
|
101
117
|
filterNotEmpty: 'Not Empty',
|
|
102
118
|
filterNotEquals: 'Not Equals',
|
|
103
119
|
filterStartsWith: 'Starts With',
|
|
120
|
+
filterWeakEquals: 'Equals',
|
|
104
121
|
filteringByColumn: 'Filtering by {column} - {filterType} {filterValue}',
|
|
105
122
|
grab: 'Grab',
|
|
106
123
|
groupByColumn: 'Group by {column}',
|
|
@@ -110,6 +127,7 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
|
|
|
110
127
|
max: 'Max',
|
|
111
128
|
min: 'Min',
|
|
112
129
|
move: 'Move',
|
|
130
|
+
or: 'or',
|
|
113
131
|
pinToLeft: 'Pin to left',
|
|
114
132
|
pinToRight: 'Pin to right',
|
|
115
133
|
resetColumnSize: 'Reset column size',
|
|
@@ -41,7 +41,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
|
|
|
41
41
|
enableHiding,
|
|
42
42
|
enablePinning,
|
|
43
43
|
enableSorting,
|
|
44
|
-
|
|
44
|
+
columnFilterModeOptions,
|
|
45
45
|
icons: {
|
|
46
46
|
ArrowRightIcon,
|
|
47
47
|
ClearAllIcon,
|
|
@@ -145,7 +145,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
|
|
|
145
145
|
const isSelectFilter = !!columnDef.filterSelectOptions;
|
|
146
146
|
|
|
147
147
|
const allowedColumnFilterOptions =
|
|
148
|
-
columnDef?.
|
|
148
|
+
columnDef?.columnFilterModeOptions ?? columnFilterModeOptions;
|
|
149
149
|
|
|
150
150
|
const showFilterModeSubMenu =
|
|
151
151
|
enableColumnFilterChangeMode &&
|
|
@@ -1,6 +1,101 @@
|
|
|
1
1
|
import React, { FC, useMemo } from 'react';
|
|
2
2
|
import { Box, Menu, MenuItem } from '@mui/material';
|
|
3
3
|
import type { MRT_FilterOption, MRT_Header, MRT_TableInstance } from '..';
|
|
4
|
+
import { MRT_Localization } from '../localization';
|
|
5
|
+
|
|
6
|
+
export const internalFilterOptions = (
|
|
7
|
+
localization: MRT_Localization,
|
|
8
|
+
): {
|
|
9
|
+
option: string;
|
|
10
|
+
symbol: string;
|
|
11
|
+
label: string;
|
|
12
|
+
divider: boolean;
|
|
13
|
+
}[] => [
|
|
14
|
+
{
|
|
15
|
+
option: 'fuzzy',
|
|
16
|
+
symbol: '≈',
|
|
17
|
+
label: localization.filterFuzzy,
|
|
18
|
+
divider: false,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
option: 'contains',
|
|
22
|
+
symbol: '*',
|
|
23
|
+
label: localization.filterContains,
|
|
24
|
+
divider: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
option: 'startsWith',
|
|
28
|
+
symbol: 'a',
|
|
29
|
+
label: localization.filterStartsWith,
|
|
30
|
+
divider: false,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
option: 'endsWith',
|
|
34
|
+
symbol: 'z',
|
|
35
|
+
label: localization.filterEndsWith,
|
|
36
|
+
divider: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
option: 'equals',
|
|
40
|
+
symbol: '=',
|
|
41
|
+
label: localization.filterEquals,
|
|
42
|
+
divider: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
option: 'notEquals',
|
|
46
|
+
symbol: '≠',
|
|
47
|
+
label: localization.filterNotEquals,
|
|
48
|
+
divider: true,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
option: 'between',
|
|
52
|
+
symbol: '⇿',
|
|
53
|
+
label: localization.filterBetween,
|
|
54
|
+
divider: false,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
option: 'betweenInclusive',
|
|
58
|
+
symbol: '⬌',
|
|
59
|
+
label: localization.filterBetweenInclusive,
|
|
60
|
+
divider: true,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
option: 'greaterThan',
|
|
64
|
+
symbol: '>',
|
|
65
|
+
label: localization.filterGreaterThan,
|
|
66
|
+
divider: false,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
option: 'greaterThanOrEqualTo',
|
|
70
|
+
symbol: '≥',
|
|
71
|
+
label: localization.filterGreaterThanOrEqualTo,
|
|
72
|
+
divider: false,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
option: 'lessThan',
|
|
76
|
+
symbol: '<',
|
|
77
|
+
label: localization.filterLessThan,
|
|
78
|
+
divider: false,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
option: 'lessThanOrEqualTo',
|
|
82
|
+
symbol: '≤',
|
|
83
|
+
label: localization.filterLessThanOrEqualTo,
|
|
84
|
+
divider: true,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
option: 'empty',
|
|
88
|
+
symbol: '∅',
|
|
89
|
+
label: localization.filterEmpty,
|
|
90
|
+
divider: false,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
option: 'notEmpty',
|
|
94
|
+
symbol: '!∅',
|
|
95
|
+
label: localization.filterNotEmpty,
|
|
96
|
+
divider: false,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
4
99
|
|
|
5
100
|
interface Props {
|
|
6
101
|
anchorEl: HTMLElement | null;
|
|
@@ -21,7 +116,7 @@ export const MRT_FilterOptionMenu: FC<Props> = ({
|
|
|
21
116
|
getState,
|
|
22
117
|
options: {
|
|
23
118
|
enabledGlobalFilterOptions,
|
|
24
|
-
|
|
119
|
+
columnFilterModeOptions,
|
|
25
120
|
localization,
|
|
26
121
|
},
|
|
27
122
|
setCurrentFilterFns,
|
|
@@ -32,110 +127,17 @@ export const MRT_FilterOptionMenu: FC<Props> = ({
|
|
|
32
127
|
const { columnDef } = column ?? {};
|
|
33
128
|
|
|
34
129
|
const allowedColumnFilterOptions =
|
|
35
|
-
columnDef?.
|
|
130
|
+
columnDef?.columnFilterModeOptions ?? columnFilterModeOptions;
|
|
36
131
|
|
|
37
132
|
const filterOptions = useMemo(
|
|
38
133
|
() =>
|
|
39
|
-
(
|
|
40
|
-
[
|
|
41
|
-
{
|
|
42
|
-
option: 'fuzzy',
|
|
43
|
-
symbol: '≈',
|
|
44
|
-
label: localization.filterFuzzy,
|
|
45
|
-
divider: false,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
option: 'contains',
|
|
49
|
-
symbol: '*',
|
|
50
|
-
label: localization.filterContains,
|
|
51
|
-
divider: false,
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
option: 'startsWith',
|
|
55
|
-
symbol: 'a',
|
|
56
|
-
label: localization.filterStartsWith,
|
|
57
|
-
divider: false,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
option: 'endsWith',
|
|
61
|
-
symbol: 'z',
|
|
62
|
-
label: localization.filterEndsWith,
|
|
63
|
-
divider: true,
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
option: 'equals',
|
|
67
|
-
symbol: '=',
|
|
68
|
-
label: localization.filterEquals,
|
|
69
|
-
divider: false,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
option: 'notEquals',
|
|
73
|
-
symbol: '≠',
|
|
74
|
-
label: localization.filterNotEquals,
|
|
75
|
-
divider: true,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
option: 'between',
|
|
79
|
-
symbol: '⇿',
|
|
80
|
-
label: localization.filterBetween,
|
|
81
|
-
divider: false,
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
option: 'betweenInclusive',
|
|
85
|
-
symbol: '⬌',
|
|
86
|
-
label: localization.filterBetweenInclusive,
|
|
87
|
-
divider: true,
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
option: 'greaterThan',
|
|
91
|
-
symbol: '>',
|
|
92
|
-
label: localization.filterGreaterThan,
|
|
93
|
-
divider: false,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
option: 'greaterThanOrEqualTo',
|
|
97
|
-
symbol: '≥',
|
|
98
|
-
label: localization.filterGreaterThanOrEqualTo,
|
|
99
|
-
divider: false,
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
option: 'lessThan',
|
|
103
|
-
symbol: '<',
|
|
104
|
-
label: localization.filterLessThan,
|
|
105
|
-
divider: false,
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
option: 'lessThanOrEqualTo',
|
|
109
|
-
symbol: '≤',
|
|
110
|
-
label: localization.filterLessThanOrEqualTo,
|
|
111
|
-
divider: true,
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
option: 'empty',
|
|
115
|
-
symbol: '∅',
|
|
116
|
-
label: localization.filterEmpty,
|
|
117
|
-
divider: false,
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
option: 'notEmpty',
|
|
121
|
-
symbol: '!∅',
|
|
122
|
-
label: localization.filterNotEmpty,
|
|
123
|
-
divider: false,
|
|
124
|
-
},
|
|
125
|
-
] as Array<{
|
|
126
|
-
divider: boolean;
|
|
127
|
-
fn: Function;
|
|
128
|
-
label: string;
|
|
129
|
-
option: MRT_FilterOption;
|
|
130
|
-
symbol?: string;
|
|
131
|
-
}>
|
|
132
|
-
).filter((filterType) =>
|
|
134
|
+
internalFilterOptions(localization).filter((filterOption) =>
|
|
133
135
|
columnDef
|
|
134
136
|
? allowedColumnFilterOptions === undefined ||
|
|
135
|
-
allowedColumnFilterOptions?.includes(
|
|
137
|
+
allowedColumnFilterOptions?.includes(filterOption.option)
|
|
136
138
|
: (!enabledGlobalFilterOptions ||
|
|
137
|
-
enabledGlobalFilterOptions.includes(
|
|
138
|
-
['fuzzy', 'contains'].includes(
|
|
139
|
+
enabledGlobalFilterOptions.includes(filterOption.option)) &&
|
|
140
|
+
['fuzzy', 'contains'].includes(filterOption.option),
|
|
139
141
|
),
|
|
140
142
|
[],
|
|
141
143
|
);
|
|
@@ -146,7 +148,7 @@ export const MRT_FilterOptionMenu: FC<Props> = ({
|
|
|
146
148
|
...prev,
|
|
147
149
|
[header.id]: option,
|
|
148
150
|
}));
|
|
149
|
-
if (['empty', 'notEmpty'].includes(option)) {
|
|
151
|
+
if (['empty', 'notEmpty'].includes(option as string)) {
|
|
150
152
|
column.setFilterValue(' ');
|
|
151
153
|
} else if (option === 'between') {
|
|
152
154
|
column.setFilterValue(['', '']);
|
|
@@ -178,7 +180,7 @@ export const MRT_FilterOptionMenu: FC<Props> = ({
|
|
|
178
180
|
<MenuItem
|
|
179
181
|
divider={divider}
|
|
180
182
|
key={index}
|
|
181
|
-
onClick={() => handleSelectFilterType(option)}
|
|
183
|
+
onClick={() => handleSelectFilterType(option as MRT_FilterOption)}
|
|
182
184
|
selected={option === filterOption}
|
|
183
185
|
sx={{
|
|
184
186
|
py: '6px',
|