material-react-table 0.5.2 → 0.5.5

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.
Files changed (37) hide show
  1. package/dist/MaterialReactTable.d.ts +10 -5
  2. package/dist/filtersFNs.d.ts +67 -0
  3. package/dist/icons.d.ts +3 -0
  4. package/dist/localization.d.ts +14 -1
  5. package/dist/material-react-table.cjs.development.js +448 -85
  6. package/dist/material-react-table.cjs.development.js.map +1 -1
  7. package/dist/material-react-table.cjs.production.min.js +1 -1
  8. package/dist/material-react-table.cjs.production.min.js.map +1 -1
  9. package/dist/material-react-table.esm.js +449 -86
  10. package/dist/material-react-table.esm.js.map +1 -1
  11. package/dist/menus/MRT_FilterTypeMenu.d.ts +10 -0
  12. package/dist/useMRT.d.ts +13 -9
  13. package/package.json +6 -2
  14. package/src/MaterialReactTable.tsx +25 -5
  15. package/src/body/MRT_TableBody.tsx +7 -2
  16. package/src/buttons/MRT_EditActionButtons.tsx +3 -1
  17. package/src/buttons/MRT_ShowHideColumnsButton.tsx +34 -31
  18. package/src/buttons/MRT_ToggleColumnActionMenuButton.tsx +4 -3
  19. package/src/buttons/MRT_ToggleFiltersButton.tsx +3 -1
  20. package/src/buttons/MRT_ToggleSearchButton.tsx +5 -2
  21. package/src/filtersFNs.ts +112 -0
  22. package/src/footer/MRT_TableFooter.tsx +6 -1
  23. package/src/footer/MRT_TableFooterCell.tsx +1 -1
  24. package/src/head/MRT_TableHeadCell.tsx +91 -44
  25. package/src/{icons.tsx → icons.ts} +9 -0
  26. package/src/index.tsx +0 -2
  27. package/src/inputs/MRT_FilterTextField.tsx +121 -52
  28. package/src/inputs/MRT_SearchTextField.tsx +2 -1
  29. package/src/inputs/MRT_SelectCheckbox.tsx +5 -7
  30. package/src/localization.ts +30 -4
  31. package/src/menus/MRT_ColumnActionMenu.tsx +145 -78
  32. package/src/menus/MRT_FilterTypeMenu.tsx +107 -0
  33. package/src/menus/MRT_RowActionMenu.tsx +20 -9
  34. package/src/menus/MRT_ShowHideColumnsMenu.tsx +1 -1
  35. package/src/table/MRT_Table.tsx +7 -2
  36. package/src/table/MRT_TableContainer.tsx +15 -2
  37. package/src/useMRT.tsx +67 -13
@@ -0,0 +1,107 @@
1
+ import React, { FC, useMemo } from 'react';
2
+ import { Menu, MenuItem, MenuList } from '@mui/material';
3
+ import { useMRT } from '../useMRT';
4
+ import { MRT_FilterType, MRT_HeaderGroup } from '..';
5
+
6
+ interface Props {
7
+ anchorEl: HTMLElement | null;
8
+ column: MRT_HeaderGroup;
9
+ setAnchorEl: (anchorEl: HTMLElement | null) => void;
10
+ onSelect?: () => void;
11
+ }
12
+
13
+ export const MRT_FilterTypeMenu: FC<Props> = ({
14
+ anchorEl,
15
+ column,
16
+ onSelect,
17
+ setAnchorEl,
18
+ }) => {
19
+ const { localization, setCurrentFilterTypes, tableInstance } = useMRT();
20
+
21
+ const filterTypes: {
22
+ type: MRT_FilterType;
23
+ label: string;
24
+ divider: boolean;
25
+ }[] = useMemo(
26
+ () => [
27
+ {
28
+ type: 'fuzzy',
29
+ label: localization.filterMenuItemFuzzy,
30
+ divider: false,
31
+ },
32
+ {
33
+ type: 'contains',
34
+ label: localization.filterMenuItemContains,
35
+ divider: true,
36
+ },
37
+ {
38
+ type: 'startsWith',
39
+ label: localization.filterMenuItemStartsWith,
40
+ divider: false,
41
+ },
42
+ {
43
+ type: 'endsWith',
44
+ label: localization.filterMenuItemEndsWith,
45
+ divider: true,
46
+ },
47
+ {
48
+ type: 'equals',
49
+ label: localization.filterMenuItemEquals,
50
+ divider: false,
51
+ },
52
+ {
53
+ type: 'notEquals',
54
+ label: localization.filterMenuItemNotEquals,
55
+ divider: true,
56
+ },
57
+ {
58
+ type: 'empty',
59
+ label: localization.filterMenuItemEmpty,
60
+ divider: false,
61
+ },
62
+ {
63
+ type: 'notEmpty',
64
+ label: localization.filterMenuItemNotEmpty,
65
+ divider: false,
66
+ },
67
+ ],
68
+ [],
69
+ );
70
+
71
+ const handleSelectFilterType = (value: MRT_FilterType) => {
72
+ setAnchorEl(null);
73
+ setCurrentFilterTypes((prev: { [key: string]: MRT_FilterType }) => ({
74
+ ...prev,
75
+ [column.id]: value,
76
+ }));
77
+ if (['empty', 'notEmpty'].includes(value)) {
78
+ column.setFilter(' ');
79
+ }
80
+ onSelect?.();
81
+ };
82
+
83
+ const filterType = tableInstance.state.currentFilterTypes[column.id];
84
+
85
+ return (
86
+ <Menu
87
+ anchorEl={anchorEl}
88
+ anchorOrigin={{ vertical: 'center', horizontal: 'right' }}
89
+ onClose={() => setAnchorEl(null)}
90
+ open={!!anchorEl}
91
+ >
92
+ <MenuList dense={tableInstance.state.densePadding} disablePadding>
93
+ {filterTypes.map(({ type, label, divider }) => (
94
+ <MenuItem
95
+ divider={divider}
96
+ key={type}
97
+ onClick={() => handleSelectFilterType(type)}
98
+ selected={type === filterType}
99
+ value={type}
100
+ >
101
+ {label}
102
+ </MenuItem>
103
+ ))}
104
+ </MenuList>
105
+ </Menu>
106
+ );
107
+ };
@@ -1,5 +1,11 @@
1
1
  import React, { FC } from 'react';
2
- import { Menu, MenuItem } from '@mui/material';
2
+ import {
3
+ ListItemIcon,
4
+ ListItemText,
5
+ Menu,
6
+ MenuItem,
7
+ MenuList,
8
+ } from '@mui/material';
3
9
  import { useMRT } from '../useMRT';
4
10
  import { MRT_Row } from '..';
5
11
 
@@ -30,14 +36,19 @@ export const MRT_RowActionMenu: FC<Props> = ({
30
36
  open={!!anchorEl}
31
37
  onClose={() => setAnchorEl(null)}
32
38
  >
33
- {enableRowEditing && (
34
- <MenuItem sx={{ display: 'flex', gap: '0.75rem' }} onClick={handleEdit}>
35
- <EditIcon /> {localization.rowActionMenuItemEdit}
36
- </MenuItem>
37
- )}
38
- {renderRowActionMenuItems?.(row, tableInstance, () =>
39
- setAnchorEl(null),
40
- ) ?? null}
39
+ <MenuList dense={tableInstance.state.densePadding} disablePadding>
40
+ {enableRowEditing && (
41
+ <MenuItem onClick={handleEdit}>
42
+ <ListItemIcon>
43
+ <EditIcon />
44
+ </ListItemIcon>
45
+ <ListItemText>{localization.rowActionMenuItemEdit}</ListItemText>
46
+ </MenuItem>
47
+ )}
48
+ {renderRowActionMenuItems?.(row, tableInstance, () =>
49
+ setAnchorEl(null),
50
+ ) ?? null}
51
+ </MenuList>
41
52
  </Menu>
42
53
  );
43
54
  };
@@ -8,7 +8,7 @@ interface Props {
8
8
  }
9
9
 
10
10
  export const MRT_ShowHideColumnsMenu: FC<Props> = ({ column }) => {
11
- const isParentHeader = (column?.columns?.length ?? 0) > 0;
11
+ const isParentHeader = !!column?.columns?.length;
12
12
 
13
13
  const allChildColumnsVisible =
14
14
  isParentHeader &&
@@ -11,12 +11,17 @@ export const MRT_Table: FC<Props> = () => {
11
11
  const { tableInstance, muiTableProps, hideTableHead, hideTableFooter } =
12
12
  useMRT();
13
13
 
14
+ const mTableProps =
15
+ muiTableProps instanceof Function
16
+ ? muiTableProps(tableInstance)
17
+ : muiTableProps;
18
+
14
19
  const tableProps = {
15
- ...muiTableProps,
20
+ ...mTableProps,
16
21
  ...tableInstance.getTableProps(),
17
22
  style: {
18
23
  ...tableInstance.getTableProps().style,
19
- ...muiTableProps?.style,
24
+ ...mTableProps?.style,
20
25
  },
21
26
  };
22
27
 
@@ -1,5 +1,11 @@
1
1
  import React, { FC, useEffect, useRef } from 'react';
2
- import { LinearProgress, Paper, TableContainer, Collapse } from '@mui/material';
2
+ import {
3
+ LinearProgress,
4
+ Paper,
5
+ TableContainer,
6
+ Collapse,
7
+ Box,
8
+ } from '@mui/material';
3
9
  import { useMRT } from '../useMRT';
4
10
  import { MRT_Table } from './MRT_Table';
5
11
  import { MRT_ToolbarTop } from '../toolbar/MRT_ToolbarTop';
@@ -63,7 +69,14 @@ export const MRT_TableContainer: FC<Props> = () => {
63
69
  <Collapse in={isFetching || isLoading} unmountOnExit>
64
70
  <LinearProgress />
65
71
  </Collapse>
66
- <MRT_Table />
72
+ <Box
73
+ sx={{
74
+ maxWidth: '100%',
75
+ overflowX: 'auto',
76
+ }}
77
+ >
78
+ <MRT_Table />
79
+ </Box>
67
80
  {!hideToolbarBottom && <MRT_ToolbarBottom />}
68
81
  </TableContainer>
69
82
  );
package/src/useMRT.tsx CHANGED
@@ -5,6 +5,8 @@ import React, {
5
5
  useContext,
6
6
  useMemo,
7
7
  useState,
8
+ Dispatch,
9
+ SetStateAction,
8
10
  } from 'react';
9
11
  import {
10
12
  PluginHook,
@@ -19,7 +21,8 @@ import {
19
21
  useSortBy,
20
22
  useTable,
21
23
  } from 'react-table';
22
- import { MRT_Row, MRT_TableInstance } from '.';
24
+ import { MRT_FilterType, MRT_Row, MRT_TableInstance } from '.';
25
+ import { defaultFilterFNs } from './filtersFNs';
23
26
  import { MRT_Icons } from './icons';
24
27
  import { MRT_Localization } from './localization';
25
28
  import { MaterialReactTableProps } from './MaterialReactTable';
@@ -28,19 +31,25 @@ export type UseMRT<D extends {} = {}> = MaterialReactTableProps<D> & {
28
31
  anyRowsCanExpand: boolean;
29
32
  anyRowsExpanded: boolean;
30
33
  icons: MRT_Icons;
34
+ idPrefix: string;
31
35
  localization: MRT_Localization;
32
- setCurrentEditingRow: (currentRowEditingId: MRT_Row<D> | null) => void;
33
- setDensePadding: (densePadding: boolean) => void;
34
- setFullScreen: (fullScreen: boolean) => void;
35
- setShowFilters: (showFilters: boolean) => void;
36
- setShowSearch: (showSearch: boolean) => void;
36
+ setCurrentEditingRow: Dispatch<SetStateAction<MRT_Row<D> | null>>;
37
+ setCurrentFilterTypes: Dispatch<
38
+ SetStateAction<{
39
+ [key: string]: MRT_FilterType;
40
+ }>
41
+ >;
42
+ setDensePadding: Dispatch<SetStateAction<boolean>>;
43
+ setFullScreen: Dispatch<SetStateAction<boolean>>;
44
+ setShowFilters: Dispatch<SetStateAction<boolean>>;
45
+ setShowSearch: Dispatch<SetStateAction<boolean>>;
37
46
  tableInstance: MRT_TableInstance<D>;
38
47
  };
39
48
 
40
- const MaterialReactTableContext = (<D extends {}>() =>
49
+ const MaterialReactTableContext = (<D extends {} = {}>() =>
41
50
  createContext<UseMRT<D>>({} as UseMRT<D>) as Context<UseMRT<D>>)();
42
51
 
43
- export const MaterialReactTableProvider = <D extends {}>(
52
+ export const MaterialReactTableProvider = <D extends {} = {}>(
44
53
  props: PropsWithChildren<MaterialReactTableProps<D>>,
45
54
  ) => {
46
55
  const hooks: PluginHook<D>[] = [
@@ -56,7 +65,7 @@ export const MaterialReactTableProvider = <D extends {}>(
56
65
  if (props.enableColumnResizing)
57
66
  hooks.unshift(useResizeColumns, useFlexLayout);
58
67
 
59
- const [currentEditingRow, setCurrentEditingRow] = useState<MRT_Row | null>(
68
+ const [currentEditingRow, setCurrentEditingRow] = useState<MRT_Row<D> | null>(
60
69
  null,
61
70
  );
62
71
  const [densePadding, setDensePadding] = useState(
@@ -72,14 +81,50 @@ export const MaterialReactTableProvider = <D extends {}>(
72
81
  props.initialState?.showSearch ?? false,
73
82
  );
74
83
 
75
- const tableInstance = useTable<D>(
84
+ const filterTypes = useMemo<Partial<{ [key in MRT_FilterType]: any }>>(
85
+ () => ({
86
+ ...defaultFilterFNs,
87
+ ...props.filterTypes,
88
+ }),
89
+ [props.filterTypes],
90
+ );
91
+
92
+ const [currentFilterTypes, setCurrentFilterTypes] = useState<{
93
+ [key: string]: MRT_FilterType;
94
+ }>(() =>
95
+ Object.assign(
96
+ {},
97
+ ...props.columns
98
+ .map((c) => c.accessor?.toString() as string)
99
+ .map((accessor) => ({
100
+ [accessor]:
101
+ props?.initialState?.filters?.[accessor as any] ?? 'fuzzy',
102
+ })),
103
+ ),
104
+ );
105
+
106
+ const columns = useMemo(
107
+ () =>
108
+ props.columns.map((column) => {
109
+ column.filter =
110
+ filterTypes[currentFilterTypes[column.accessor as string]];
111
+ return column;
112
+ }),
113
+ [props.columns, filterTypes, currentFilterTypes],
114
+ );
115
+
116
+ const tableInstance = useTable(
76
117
  {
77
118
  ...props,
119
+ columns,
120
+ // @ts-ignore
121
+ filterTypes,
78
122
  useControlledState: (state) =>
79
123
  useMemo(
80
124
  () => ({
81
125
  ...state,
82
126
  currentEditingRow,
127
+ currentFilterTypes,
83
128
  densePadding,
84
129
  fullScreen,
85
130
  showFilters,
@@ -89,6 +134,7 @@ export const MaterialReactTableProvider = <D extends {}>(
89
134
  }),
90
135
  [
91
136
  currentEditingRow,
137
+ currentFilterTypes,
92
138
  densePadding,
93
139
  fullScreen,
94
140
  showFilters,
@@ -100,6 +146,10 @@ export const MaterialReactTableProvider = <D extends {}>(
100
146
  ...hooks,
101
147
  ) as MRT_TableInstance<D>;
102
148
 
149
+ const idPrefix = useMemo(
150
+ () => props.idPrefix ?? Math.random().toString(36).substring(2, 9),
151
+ [props.idPrefix],
152
+ );
103
153
  const anyRowsCanExpand = useMemo(
104
154
  () => tableInstance.rows.some((row) => row.canExpand),
105
155
  [tableInstance.rows],
@@ -115,7 +165,10 @@ export const MaterialReactTableProvider = <D extends {}>(
115
165
  ...props,
116
166
  anyRowsCanExpand,
117
167
  anyRowsExpanded,
168
+ idPrefix,
169
+ //@ts-ignore
118
170
  setCurrentEditingRow,
171
+ setCurrentFilterTypes,
119
172
  setDensePadding,
120
173
  setFullScreen,
121
174
  setShowFilters,
@@ -129,6 +182,7 @@ export const MaterialReactTableProvider = <D extends {}>(
129
182
  );
130
183
  };
131
184
 
132
- export const useMRT = <D extends {}>(): UseMRT<D> =>
133
- // @ts-ignore
134
- useContext<UseMRT<D>>(MaterialReactTableContext);
185
+ export const useMRT = <D extends {} = {}>(): UseMRT<D> =>
186
+ useContext<UseMRT<D>>(
187
+ MaterialReactTableContext as unknown as Context<UseMRT<D>>,
188
+ );