@cutting/material-react-table 5.0.0 → 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 +186 -524
- package/dist/index.js +323 -342
- 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 +19 -27
- 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 +8 -37
- package/src/fns/filterFns.ts +71 -96
- package/src/fns/sortingFns.test.tsx +5 -21
- package/src/fns/sortingFns.ts +10 -14
- 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
|
@@ -11,20 +11,13 @@ interface Person {
|
|
|
11
11
|
|
|
12
12
|
const data: Person[] = [{ name: 'Alice' }];
|
|
13
13
|
|
|
14
|
-
const columns = (): MRT_ColumnDef<Person>[] => [
|
|
15
|
-
{ accessorKey: 'name', header: 'Name' },
|
|
16
|
-
];
|
|
14
|
+
const columns = (): MRT_ColumnDef<Person>[] => [{ accessorKey: 'name', header: 'Name' }];
|
|
17
15
|
|
|
18
16
|
describe('cell editing', () => {
|
|
19
17
|
test('opens a text field in the cell that was clicked', async () => {
|
|
20
18
|
const user = userEvent.setup();
|
|
21
19
|
const { container } = render(
|
|
22
|
-
<MaterialReactTable
|
|
23
|
-
columns={columns()}
|
|
24
|
-
data={data}
|
|
25
|
-
editDisplayMode="cell"
|
|
26
|
-
enableEditing
|
|
27
|
-
/>,
|
|
20
|
+
<MaterialReactTable columns={columns()} data={data} editDisplayMode="cell" enableEditing />,
|
|
28
21
|
);
|
|
29
22
|
|
|
30
23
|
expect(container.querySelectorAll('tbody input')).toHaveLength(0);
|
|
@@ -1,23 +1,12 @@
|
|
|
1
|
-
import { MenuItem } from '@mui/material';
|
|
2
|
-
import { TextField } from '@mui/material';
|
|
1
|
+
import { MenuItem, TextField } from '@mui/material';
|
|
3
2
|
import { type TextFieldProps } from '@mui/material/TextField';
|
|
4
|
-
import {
|
|
5
|
-
type ChangeEvent,
|
|
6
|
-
type FocusEvent,
|
|
7
|
-
type KeyboardEvent,
|
|
8
|
-
useState,
|
|
9
|
-
} from 'react';
|
|
3
|
+
import { type ChangeEvent, type FocusEvent, type KeyboardEvent, useState } from 'react';
|
|
10
4
|
|
|
11
|
-
import {
|
|
12
|
-
type MRT_Cell,
|
|
13
|
-
type MRT_RowData,
|
|
14
|
-
type MRT_TableInstance,
|
|
15
|
-
} from '../../types';
|
|
5
|
+
import { type MRT_Cell, type MRT_RowData, type MRT_TableInstance } from '../../types';
|
|
16
6
|
import { getTextFieldSlotProps } from '../../utils/slotProps.utils';
|
|
17
7
|
import { getValueAndLabel, parseFromValuesOrFunc } from '../../utils/utils';
|
|
18
8
|
|
|
19
|
-
export interface MRT_EditCellTextFieldProps<TData extends MRT_RowData>
|
|
20
|
-
extends TextFieldProps<'standard'> {
|
|
9
|
+
export interface MRT_EditCellTextFieldProps<TData extends MRT_RowData> extends TextFieldProps<'standard'> {
|
|
21
10
|
cell: MRT_Cell<TData>;
|
|
22
11
|
table: MRT_TableInstance<TData>;
|
|
23
12
|
}
|
|
@@ -26,7 +15,7 @@ export const MRT_EditCellTextField = <TData extends MRT_RowData>({
|
|
|
26
15
|
cell,
|
|
27
16
|
table,
|
|
28
17
|
...rest
|
|
29
|
-
}: MRT_EditCellTextFieldProps<TData>) => {
|
|
18
|
+
}: MRT_EditCellTextFieldProps<TData>): JSX.Element => {
|
|
30
19
|
const {
|
|
31
20
|
options: { createDisplayMode, editDisplayMode, muiEditTextFieldProps },
|
|
32
21
|
refs: { editInputRefs },
|
|
@@ -112,27 +101,21 @@ export const MRT_EditCellTextField = <TData extends MRT_RowData>({
|
|
|
112
101
|
fullWidth
|
|
113
102
|
inputRef={(inputRef) => {
|
|
114
103
|
if (inputRef) {
|
|
115
|
-
editInputRefs.current![column.id] = isSelectEdit
|
|
116
|
-
? inputRef.node
|
|
117
|
-
: inputRef;
|
|
104
|
+
editInputRefs.current![column.id] = isSelectEdit ? inputRef.node : inputRef;
|
|
118
105
|
if (textFieldProps.inputRef) {
|
|
119
106
|
textFieldProps.inputRef = inputRef;
|
|
120
107
|
}
|
|
121
108
|
}
|
|
122
109
|
}}
|
|
123
110
|
label={
|
|
124
|
-
['custom', 'modal'].includes(
|
|
125
|
-
(isCreating ? createDisplayMode : editDisplayMode) as string,
|
|
126
|
-
)
|
|
111
|
+
['custom', 'modal'].includes((isCreating ? createDisplayMode : editDisplayMode) as string)
|
|
127
112
|
? columnDef.header
|
|
128
113
|
: undefined
|
|
129
114
|
}
|
|
130
115
|
margin="none"
|
|
131
116
|
name={column.id}
|
|
132
117
|
placeholder={
|
|
133
|
-
!['custom', 'modal'].includes(
|
|
134
|
-
(isCreating ? createDisplayMode : editDisplayMode) as string,
|
|
135
|
-
)
|
|
118
|
+
!['custom', 'modal'].includes((isCreating ? createDisplayMode : editDisplayMode) as string)
|
|
136
119
|
? columnDef.header
|
|
137
120
|
: undefined
|
|
138
121
|
}
|
|
@@ -153,9 +136,7 @@ export const MRT_EditCellTextField = <TData extends MRT_RowData>({
|
|
|
153
136
|
slotProps={{
|
|
154
137
|
htmlInput: { autoComplete: 'off', ...consumerSlots.htmlInput },
|
|
155
138
|
input: {
|
|
156
|
-
...(textFieldProps.variant !== 'outlined'
|
|
157
|
-
? { disableUnderline: editDisplayMode === 'table' }
|
|
158
|
-
: {}),
|
|
139
|
+
...(textFieldProps.variant !== 'outlined' ? { disableUnderline: editDisplayMode === 'table' } : {}),
|
|
159
140
|
...consumerSlots.input,
|
|
160
141
|
sx: { mb: 0, ...consumerSlots.input?.sx },
|
|
161
142
|
},
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { Checkbox, type CheckboxProps } from '@mui/material';
|
|
2
|
-
import {
|
|
3
|
-
import { Tooltip } from '@mui/material';
|
|
1
|
+
import { Checkbox, type CheckboxProps, FormControlLabel, Tooltip } from '@mui/material';
|
|
2
|
+
import { type CSSObject } from '@mui/material/styles';
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
type MRT_Column,
|
|
7
|
-
type MRT_RowData,
|
|
8
|
-
type MRT_TableInstance,
|
|
9
|
-
} from '../../types';
|
|
4
|
+
import { type MRT_Column, type MRT_RowData, type MRT_TableInstance } from '../../types';
|
|
10
5
|
import { getCommonTooltipProps } from '../../utils/style.utils';
|
|
11
6
|
import { parseFromValuesOrFunc } from '../../utils/utils';
|
|
12
7
|
|
|
13
|
-
export interface MRT_FilterCheckboxProps<TData extends MRT_RowData>
|
|
14
|
-
extends CheckboxProps {
|
|
8
|
+
export interface MRT_FilterCheckboxProps<TData extends MRT_RowData> extends CheckboxProps {
|
|
15
9
|
column: MRT_Column<TData>;
|
|
16
10
|
table: MRT_TableInstance<TData>;
|
|
17
11
|
}
|
|
@@ -20,7 +14,7 @@ export const MRT_FilterCheckbox = <TData extends MRT_RowData>({
|
|
|
20
14
|
column,
|
|
21
15
|
table,
|
|
22
16
|
...rest
|
|
23
|
-
}: MRT_FilterCheckboxProps<TData>) => {
|
|
17
|
+
}: MRT_FilterCheckboxProps<TData>): JSX.Element => {
|
|
24
18
|
const {
|
|
25
19
|
options: { localization, muiFilterCheckboxProps },
|
|
26
20
|
} = table;
|
|
@@ -39,23 +33,15 @@ export const MRT_FilterCheckbox = <TData extends MRT_RowData>({
|
|
|
39
33
|
...rest,
|
|
40
34
|
};
|
|
41
35
|
|
|
42
|
-
const filterLabel = localization.filterByColumn?.replace(
|
|
43
|
-
'{column}',
|
|
44
|
-
columnDef.header,
|
|
45
|
-
);
|
|
36
|
+
const filterLabel = localization.filterByColumn?.replace('{column}', columnDef.header);
|
|
46
37
|
|
|
47
38
|
return (
|
|
48
|
-
<Tooltip
|
|
49
|
-
{...getCommonTooltipProps()}
|
|
50
|
-
title={checkboxProps?.title ?? filterLabel}
|
|
51
|
-
>
|
|
39
|
+
<Tooltip {...getCommonTooltipProps()} title={checkboxProps?.title ?? filterLabel}>
|
|
52
40
|
<FormControlLabel
|
|
53
41
|
control={
|
|
54
42
|
<Checkbox
|
|
55
43
|
checked={column.getFilterValue() === 'true'}
|
|
56
|
-
color={
|
|
57
|
-
column.getFilterValue() === undefined ? 'default' : 'primary'
|
|
58
|
-
}
|
|
44
|
+
color={column.getFilterValue() === undefined ? 'default' : 'primary'}
|
|
59
45
|
indeterminate={column.getFilterValue() === undefined}
|
|
60
46
|
size={density === 'compact' ? 'small' : 'medium'}
|
|
61
47
|
{...checkboxProps}
|
|
@@ -76,7 +62,7 @@ export const MRT_FilterCheckbox = <TData extends MRT_RowData>({
|
|
|
76
62
|
sx={(theme) => ({
|
|
77
63
|
height: '2.5rem',
|
|
78
64
|
width: '2.5rem',
|
|
79
|
-
...(parseFromValuesOrFunc(checkboxProps?.sx, theme) as
|
|
65
|
+
...(parseFromValuesOrFunc(checkboxProps?.sx, theme) as CSSObject),
|
|
80
66
|
})}
|
|
81
67
|
/>
|
|
82
68
|
}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { Box, type BoxProps } from '@mui/material';
|
|
2
|
+
import { type CSSObject } from '@mui/material/styles';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
type MRT_Header,
|
|
5
|
-
type MRT_RowData,
|
|
6
|
-
type MRT_TableInstance,
|
|
7
|
-
} from '../../types';
|
|
4
|
+
import { type MRT_Header, type MRT_RowData, type MRT_TableInstance } from '../../types';
|
|
8
5
|
import { parseFromValuesOrFunc } from '../../utils/utils';
|
|
9
6
|
import { MRT_FilterTextField } from './MRT_FilterTextField';
|
|
10
7
|
|
|
11
|
-
export interface MRT_FilterRangeFieldsProps<TData extends MRT_RowData>
|
|
12
|
-
extends BoxProps {
|
|
8
|
+
export interface MRT_FilterRangeFieldsProps<TData extends MRT_RowData> extends BoxProps {
|
|
13
9
|
header: MRT_Header<TData>;
|
|
14
10
|
table: MRT_TableInstance<TData>;
|
|
15
11
|
}
|
|
@@ -18,7 +14,7 @@ export const MRT_FilterRangeFields = <TData extends MRT_RowData>({
|
|
|
18
14
|
header,
|
|
19
15
|
table,
|
|
20
16
|
...rest
|
|
21
|
-
}: MRT_FilterRangeFieldsProps<TData>) => {
|
|
17
|
+
}: MRT_FilterRangeFieldsProps<TData>): JSX.Element => {
|
|
22
18
|
return (
|
|
23
19
|
<Box
|
|
24
20
|
{...rest}
|
|
@@ -26,16 +22,11 @@ export const MRT_FilterRangeFields = <TData extends MRT_RowData>({
|
|
|
26
22
|
display: 'grid',
|
|
27
23
|
gap: '1rem',
|
|
28
24
|
gridTemplateColumns: '1fr 1fr',
|
|
29
|
-
...(parseFromValuesOrFunc(rest?.sx, theme) as
|
|
25
|
+
...(parseFromValuesOrFunc(rest?.sx, theme) as CSSObject),
|
|
30
26
|
})}
|
|
31
27
|
>
|
|
32
28
|
{[0, 1].map((rangeFilterIndex) => (
|
|
33
|
-
<MRT_FilterTextField
|
|
34
|
-
header={header}
|
|
35
|
-
key={rangeFilterIndex}
|
|
36
|
-
rangeFilterIndex={rangeFilterIndex}
|
|
37
|
-
table={table}
|
|
38
|
-
/>
|
|
29
|
+
<MRT_FilterTextField header={header} key={rangeFilterIndex} rangeFilterIndex={rangeFilterIndex} table={table} />
|
|
39
30
|
))}
|
|
40
31
|
</Box>
|
|
41
32
|
);
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { FormHelperText } from '@mui/material';
|
|
2
|
-
import {
|
|
3
|
-
import { Stack } from '@mui/material';
|
|
1
|
+
import { FormHelperText, Slider, type SliderProps, Stack } from '@mui/material';
|
|
2
|
+
import { type CSSObject } from '@mui/material/styles';
|
|
4
3
|
import { useEffect, useRef, useState } from 'react';
|
|
5
4
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
type MRT_RowData,
|
|
9
|
-
type MRT_TableInstance,
|
|
10
|
-
} from '../../types';
|
|
11
|
-
import { getColumnFilterInfo } from '../../utils/column.utils';
|
|
5
|
+
import { type MRT_Header, type MRT_RowData, type MRT_TableInstance } from '../../types';
|
|
6
|
+
import { getColumnFilterInfo, getFilterOptionLabel } from '../../utils/column.utils';
|
|
12
7
|
import { parseFromValuesOrFunc } from '../../utils/utils';
|
|
13
8
|
|
|
14
|
-
export interface MRT_FilterRangeSliderProps<TData extends MRT_RowData>
|
|
15
|
-
extends SliderProps {
|
|
9
|
+
export interface MRT_FilterRangeSliderProps<TData extends MRT_RowData> extends SliderProps {
|
|
16
10
|
header: MRT_Header<TData>;
|
|
17
11
|
table: MRT_TableInstance<TData>;
|
|
18
12
|
}
|
|
@@ -21,7 +15,7 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
21
15
|
header,
|
|
22
16
|
table,
|
|
23
17
|
...rest
|
|
24
|
-
}: MRT_FilterRangeSliderProps<TData>) => {
|
|
18
|
+
}: MRT_FilterRangeSliderProps<TData>): JSX.Element => {
|
|
25
19
|
const {
|
|
26
20
|
options: { enableColumnFilterModes, localization, muiFilterSliderProps },
|
|
27
21
|
refs: { filterInputRefs },
|
|
@@ -31,8 +25,7 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
31
25
|
|
|
32
26
|
const { currentFilterOption } = getColumnFilterInfo({ header, table });
|
|
33
27
|
|
|
34
|
-
const showChangeModeButton =
|
|
35
|
-
enableColumnFilterModes && columnDef.enableColumnFilterModes !== false;
|
|
28
|
+
const showChangeModeButton = enableColumnFilterModes && columnDef.enableColumnFilterModes !== false;
|
|
36
29
|
|
|
37
30
|
const sliderProps = {
|
|
38
31
|
...parseFromValuesOrFunc(muiFilterSliderProps, { column, table }),
|
|
@@ -46,10 +39,18 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
46
39
|
: (column.getFacetedMinMaxValues() ?? [0, 1]);
|
|
47
40
|
|
|
48
41
|
//fix potential TanStack Table bugs where min or max is an array
|
|
49
|
-
if (Array.isArray(min))
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (max
|
|
42
|
+
if (Array.isArray(min)) {
|
|
43
|
+
min = min[0];
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(max)) {
|
|
46
|
+
max = max[0];
|
|
47
|
+
}
|
|
48
|
+
if (min === null) {
|
|
49
|
+
min = 0;
|
|
50
|
+
}
|
|
51
|
+
if (max === null) {
|
|
52
|
+
max = 1;
|
|
53
|
+
}
|
|
53
54
|
|
|
54
55
|
const [filterValues, setFilterValues] = useState([min, max]);
|
|
55
56
|
const columnFilterValue = column.getFilterValue();
|
|
@@ -102,10 +103,9 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
102
103
|
ref: (node) => {
|
|
103
104
|
if (node) {
|
|
104
105
|
filterInputRefs.current![`${column.id}-0`] = node;
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
sliderProps.slotProps.input.ref = node;
|
|
106
|
+
const inputSlot = sliderProps?.slotProps?.input;
|
|
107
|
+
if (inputSlot && typeof inputSlot === 'object' && inputSlot.ref && typeof inputSlot.ref === 'object') {
|
|
108
|
+
inputSlot.ref.current = node;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
},
|
|
@@ -117,7 +117,7 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
117
117
|
mt: !showChangeModeButton ? '10px' : '6px',
|
|
118
118
|
px: '4px',
|
|
119
119
|
width: 'calc(100% - 8px)',
|
|
120
|
-
...(parseFromValuesOrFunc(sliderProps?.sx, theme) as
|
|
120
|
+
...(parseFromValuesOrFunc(sliderProps?.sx, theme) as CSSObject),
|
|
121
121
|
})}
|
|
122
122
|
/>
|
|
123
123
|
{showChangeModeButton ? (
|
|
@@ -129,15 +129,7 @@ export const MRT_FilterRangeSlider = <TData extends MRT_RowData>({
|
|
|
129
129
|
whiteSpace: 'nowrap',
|
|
130
130
|
}}
|
|
131
131
|
>
|
|
132
|
-
{localization.filterMode.replace(
|
|
133
|
-
'{filterType}',
|
|
134
|
-
localization[
|
|
135
|
-
`filter${
|
|
136
|
-
currentFilterOption?.charAt(0)?.toUpperCase() +
|
|
137
|
-
currentFilterOption?.slice(1)
|
|
138
|
-
}` as keyof typeof localization
|
|
139
|
-
],
|
|
140
|
-
)}
|
|
132
|
+
{localization.filterMode.replace('{filterType}', getFilterOptionLabel(localization, currentFilterOption))}
|
|
141
133
|
</FormHelperText>
|
|
142
134
|
) : null}
|
|
143
135
|
</Stack>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { render, waitFor } from '@testing-library/react';
|
|
1
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
|
-
import { describe, expect, test } from 'vitest';
|
|
3
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
4
4
|
|
|
5
5
|
import { type MRT_ColumnDef } from '../../types';
|
|
6
6
|
import { MaterialReactTable } from '../MaterialReactTable';
|
|
@@ -33,15 +33,13 @@ describe('faceted select filter', () => {
|
|
|
33
33
|
/>,
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
const selects = container.querySelectorAll<HTMLElement>(
|
|
37
|
-
'thead [role="combobox"]',
|
|
38
|
-
);
|
|
36
|
+
const selects = container.querySelectorAll<HTMLElement>('thead [role="combobox"]');
|
|
39
37
|
|
|
40
38
|
await user.click(selects[selects.length - 1]);
|
|
41
39
|
|
|
42
|
-
const options = Array.from(
|
|
43
|
-
|
|
44
|
-
)
|
|
40
|
+
const options = Array.from(baseElement.querySelectorAll<HTMLElement>('li[role="option"]')).map(
|
|
41
|
+
(li) => li.textContent,
|
|
42
|
+
);
|
|
45
43
|
|
|
46
44
|
expect(options).toContain('Glasgow (2)');
|
|
47
45
|
expect(options).toContain('Dundee (1)');
|
|
@@ -58,18 +56,78 @@ describe('faceted select filter', () => {
|
|
|
58
56
|
/>,
|
|
59
57
|
);
|
|
60
58
|
|
|
61
|
-
const selects = container.querySelectorAll<HTMLElement>(
|
|
62
|
-
'thead [role="combobox"]',
|
|
63
|
-
);
|
|
59
|
+
const selects = container.querySelectorAll<HTMLElement>('thead [role="combobox"]');
|
|
64
60
|
|
|
65
61
|
await user.click(selects[selects.length - 1]);
|
|
66
62
|
await user.keyboard('{ArrowDown}{Enter}');
|
|
67
63
|
|
|
68
64
|
await waitFor(() => {
|
|
69
|
-
const names = Array.from(container.querySelectorAll('tbody tr')).map(
|
|
70
|
-
(tr) => tr.querySelector('td')?.textContent,
|
|
71
|
-
);
|
|
65
|
+
const names = Array.from(container.querySelectorAll('tbody tr')).map((tr) => tr.querySelector('td')?.textContent);
|
|
72
66
|
expect(names).toEqual(['Alice', 'Cara']);
|
|
73
67
|
});
|
|
74
68
|
});
|
|
75
69
|
});
|
|
70
|
+
|
|
71
|
+
describe('empty text filter', () => {
|
|
72
|
+
test('does not reset the column filters when the table re-renders', () => {
|
|
73
|
+
const onColumnFiltersChange = vi.fn();
|
|
74
|
+
const table = (isLoading: boolean) => (
|
|
75
|
+
<MaterialReactTable
|
|
76
|
+
columns={columns()}
|
|
77
|
+
data={data}
|
|
78
|
+
initialState={{ showColumnFilters: true }}
|
|
79
|
+
onColumnFiltersChange={onColumnFiltersChange}
|
|
80
|
+
state={{ columnFilters: [], isLoading }}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
const { rerender } = render(table(false));
|
|
84
|
+
|
|
85
|
+
rerender(table(true));
|
|
86
|
+
rerender(table(false));
|
|
87
|
+
|
|
88
|
+
expect(onColumnFiltersChange).not.toHaveBeenCalled();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('filter mode labels', () => {
|
|
93
|
+
test('shows the current filter mode under the text filter', () => {
|
|
94
|
+
render(
|
|
95
|
+
<MaterialReactTable
|
|
96
|
+
columns={[{ accessorKey: 'name', header: 'Name' }]}
|
|
97
|
+
data={data}
|
|
98
|
+
enableColumnFilterModes
|
|
99
|
+
initialState={{ showColumnFilters: true }}
|
|
100
|
+
/>,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(screen.getByText('Filter Mode: Fuzzy')).toBeTruthy();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('shows the filter mode under the range slider', () => {
|
|
107
|
+
render(
|
|
108
|
+
<MaterialReactTable
|
|
109
|
+
columns={[
|
|
110
|
+
{ accessorFn: (person) => person.name.length, filterVariant: 'range-slider', header: 'Length', id: 'length' },
|
|
111
|
+
]}
|
|
112
|
+
data={data}
|
|
113
|
+
enableColumnFilterModes
|
|
114
|
+
initialState={{ showColumnFilters: true }}
|
|
115
|
+
/>,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(screen.getByText('Filter Mode: Between Inclusive')).toBeTruthy();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('shows a chip for the empty filter mode', () => {
|
|
122
|
+
render(
|
|
123
|
+
<MaterialReactTable
|
|
124
|
+
columns={[{ accessorKey: 'name', header: 'Name' }]}
|
|
125
|
+
data={data}
|
|
126
|
+
enableColumnFilterModes
|
|
127
|
+
initialState={{ columnFilterFns: { name: 'empty' }, showColumnFilters: true }}
|
|
128
|
+
/>,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
expect(screen.getAllByText('Empty').length).toBeGreaterThan(0);
|
|
132
|
+
});
|
|
133
|
+
});
|