material-react-table 0.6.7 → 0.6.10

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 +12 -3
  2. package/dist/enums.d.ts +2 -1
  3. package/dist/filtersFNs.d.ts +13 -5
  4. package/dist/localization.d.ts +3 -1
  5. package/dist/material-react-table.cjs.development.js +339 -248
  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 +340 -249
  10. package/dist/material-react-table.esm.js.map +1 -1
  11. package/dist/menus/MRT_FilterTypeMenu.d.ts +1 -1
  12. package/dist/useMRT.d.ts +1 -0
  13. package/dist/utils.d.ts +2 -2
  14. package/package.json +1 -1
  15. package/src/MaterialReactTable.tsx +29 -4
  16. package/src/body/MRT_TableBodyCell.tsx +8 -2
  17. package/src/body/MRT_TableBodyRow.tsx +30 -7
  18. package/src/buttons/MRT_CopyButton.tsx +24 -6
  19. package/src/buttons/MRT_ExpandAllButton.tsx +13 -20
  20. package/src/buttons/MRT_ExpandButton.tsx +20 -33
  21. package/src/buttons/MRT_ToggleColumnActionMenuButton.tsx +19 -1
  22. package/src/enums.ts +2 -1
  23. package/src/filtersFNs.ts +17 -3
  24. package/src/head/MRT_TableHeadCell.tsx +6 -3
  25. package/src/head/MRT_TableHeadRow.tsx +38 -15
  26. package/src/inputs/MRT_EditCellTextField.tsx +0 -6
  27. package/src/inputs/MRT_FilterTextField.tsx +1 -12
  28. package/src/inputs/MRT_SearchTextField.tsx +27 -3
  29. package/src/inputs/MRT_SelectCheckbox.tsx +58 -31
  30. package/src/localization.ts +7 -3
  31. package/src/menus/MRT_ColumnActionMenu.tsx +6 -1
  32. package/src/menus/MRT_FilterTypeMenu.tsx +44 -18
  33. package/src/menus/MRT_ShowHideColumnsMenu.tsx +12 -1
  34. package/src/menus/MRT_ShowHideColumnsMenuItems.tsx +1 -1
  35. package/src/table/MRT_TableSpacerCell.tsx +1 -8
  36. package/src/useMRT.tsx +12 -1
  37. package/src/utils.ts +8 -4
@@ -1,7 +1,14 @@
1
- import React, { ChangeEvent, FC, useState } from 'react';
2
- import { Collapse, IconButton, InputAdornment, TextField } from '@mui/material';
1
+ import React, { ChangeEvent, FC, MouseEvent, useState } from 'react';
2
+ import {
3
+ Collapse,
4
+ IconButton,
5
+ InputAdornment,
6
+ TextField,
7
+ Tooltip,
8
+ } from '@mui/material';
3
9
  import { useMRT } from '../useMRT';
4
10
  import { useAsyncDebounce } from 'react-table';
11
+ import { MRT_FilterTypeMenu } from '../menus/MRT_FilterTypeMenu';
5
12
 
6
13
  interface Props {}
7
14
 
@@ -15,6 +22,7 @@ export const MRT_SearchTextField: FC<Props> = () => {
15
22
  tableInstance,
16
23
  } = useMRT();
17
24
 
25
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
18
26
  const [searchValue, setSearchValue] = useState('');
19
27
 
20
28
  const handleChange = useAsyncDebounce(
@@ -25,6 +33,10 @@ export const MRT_SearchTextField: FC<Props> = () => {
25
33
  200,
26
34
  );
27
35
 
36
+ const handleGlobalFilterMenuOpen = (event: MouseEvent<HTMLElement>) => {
37
+ setAnchorEl(event.currentTarget);
38
+ };
39
+
28
40
  const handleClear = () => {
29
41
  setSearchValue('');
30
42
  tableInstance.setGlobalFilter(undefined);
@@ -44,7 +56,18 @@ export const MRT_SearchTextField: FC<Props> = () => {
44
56
  InputProps={{
45
57
  startAdornment: (
46
58
  <InputAdornment position="start">
47
- <SearchIcon fontSize="small" />
59
+ <Tooltip arrow title={localization.changeSearchMode}>
60
+ <span>
61
+ <IconButton
62
+ aria-label={localization.changeSearchMode}
63
+ onClick={handleGlobalFilterMenuOpen}
64
+ size="small"
65
+ sx={{ height: '1.75rem', width: '1.75rem' }}
66
+ >
67
+ <SearchIcon fontSize="small" />
68
+ </IconButton>
69
+ </span>
70
+ </Tooltip>
48
71
  </InputAdornment>
49
72
  ),
50
73
  endAdornment: (
@@ -64,6 +87,7 @@ export const MRT_SearchTextField: FC<Props> = () => {
64
87
  {...muiSearchTextFieldProps}
65
88
  sx={{ justifySelf: 'end', ...muiSearchTextFieldProps?.sx }}
66
89
  />
90
+ <MRT_FilterTypeMenu anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
67
91
  </Collapse>
68
92
  );
69
93
  };
@@ -1,8 +1,7 @@
1
1
  import React, { ChangeEvent, FC } from 'react';
2
- import { Checkbox, TableCell, Tooltip } from '@mui/material';
2
+ import { Checkbox, Tooltip } from '@mui/material';
3
3
  import { useMRT } from '../useMRT';
4
4
  import type { MRT_Row } from '..';
5
- import { commonTableBodyButtonCellStyles } from '../body/MRT_TableBodyCell';
6
5
 
7
6
  interface Props {
8
7
  row?: MRT_Row;
@@ -10,48 +9,76 @@ interface Props {
10
9
  }
11
10
 
12
11
  export const MRT_SelectCheckbox: FC<Props> = ({ row, selectAll }) => {
13
- const { localization, onRowSelectChange, onSelectAllChange, tableInstance } =
14
- useMRT();
12
+ const {
13
+ localization,
14
+ muiSelectCheckboxProps,
15
+ onSelectChange,
16
+ onSelectAllChange,
17
+ tableInstance,
18
+ tableInstance: {
19
+ state: { densePadding },
20
+ },
21
+ } = useMRT();
15
22
 
16
- const onSelectChange = (event: ChangeEvent<HTMLInputElement>) => {
23
+ const handleSelectChange = (event: ChangeEvent<HTMLInputElement>) => {
17
24
  if (selectAll) {
18
25
  tableInstance?.getToggleAllRowsSelectedProps?.()?.onChange?.(event);
19
- onSelectAllChange?.(event, tableInstance.selectedFlatRows);
26
+ onSelectAllChange?.(
27
+ event,
28
+ event.target.checked ? tableInstance.rows : [],
29
+ );
20
30
  } else if (row) {
21
31
  row?.getToggleRowSelectedProps()?.onChange?.(event);
22
- onRowSelectChange?.(event, row, tableInstance.selectedFlatRows);
32
+ onSelectChange?.(
33
+ event,
34
+ row,
35
+ event.target.checked
36
+ ? [...tableInstance.selectedFlatRows, row]
37
+ : tableInstance.selectedFlatRows.filter(
38
+ (selectedRow) => selectedRow.id !== row.id,
39
+ ),
40
+ );
23
41
  }
24
42
  };
25
43
 
26
- const checkboxProps = selectAll
44
+ const mTableBodyRowSelectCheckboxProps =
45
+ muiSelectCheckboxProps instanceof Function
46
+ ? muiSelectCheckboxProps(selectAll, row, tableInstance)
47
+ : muiSelectCheckboxProps;
48
+
49
+ const rtSelectCheckboxProps = selectAll
27
50
  ? tableInstance.getToggleAllRowsSelectedProps()
28
51
  : row?.getToggleRowSelectedProps();
29
52
 
53
+ const checkboxProps = {
54
+ ...mTableBodyRowSelectCheckboxProps,
55
+ ...rtSelectCheckboxProps,
56
+ style: {
57
+ ...rtSelectCheckboxProps?.style,
58
+ ...mTableBodyRowSelectCheckboxProps?.style,
59
+ },
60
+ };
61
+
30
62
  return (
31
- <TableCell
32
- sx={commonTableBodyButtonCellStyles(tableInstance.state.densePadding)}
63
+ <Tooltip
64
+ arrow
65
+ enterDelay={1000}
66
+ enterNextDelay={1000}
67
+ title={
68
+ selectAll ? localization.toggleSelectAll : localization.toggleSelectRow
69
+ }
33
70
  >
34
- <Tooltip
35
- arrow
36
- enterDelay={1000}
37
- enterNextDelay={1000}
38
- title={
39
- selectAll
71
+ <Checkbox
72
+ inputProps={{
73
+ 'aria-label': selectAll
40
74
  ? localization.toggleSelectAll
41
- : localization.toggleSelectRow
42
- }
43
- >
44
- <Checkbox
45
- inputProps={{
46
- 'aria-label': selectAll
47
- ? localization.toggleSelectAll
48
- : localization.toggleSelectRow,
49
- }}
50
- onChange={onSelectChange}
51
- {...checkboxProps}
52
- title={undefined}
53
- />
54
- </Tooltip>
55
- </TableCell>
75
+ : localization.toggleSelectRow,
76
+ }}
77
+ size={densePadding ? 'small' : 'medium'}
78
+ {...checkboxProps}
79
+ onChange={handleSelectChange}
80
+ title={undefined}
81
+ />
82
+ </Tooltip>
56
83
  );
57
84
  };
@@ -2,6 +2,7 @@ export interface MRT_Localization {
2
2
  actions: string;
3
3
  cancel: string;
4
4
  changeFilterMode: string;
5
+ changeSearchMode: string;
5
6
  clearFilter: string;
6
7
  clearSearch: string;
7
8
  clearSort: string;
@@ -11,12 +12,13 @@ export interface MRT_Localization {
11
12
  edit: string;
12
13
  expand: string;
13
14
  expandAll: string;
15
+ filterBestMatchFirst: string;
14
16
  filterByColumn: string;
15
17
  filterContains: string;
16
18
  filterEmpty: string;
17
19
  filterEndsWith: string;
18
20
  filterEquals: string;
19
- filterFuzzy: string;
21
+ filterBestMatch: string;
20
22
  filterGreaterThan: string;
21
23
  filterLessThan: string;
22
24
  filterMode: string;
@@ -51,6 +53,7 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
51
53
  actions: 'Actions',
52
54
  cancel: 'Cancel',
53
55
  changeFilterMode: 'Change filter mode',
56
+ changeSearchMode: 'Change search mode',
54
57
  clearFilter: 'Clear filter',
55
58
  clearSearch: 'Clear search',
56
59
  clearSort: 'Clear sort',
@@ -60,12 +63,13 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
60
63
  edit: 'Edit',
61
64
  expand: 'Expand',
62
65
  expandAll: 'Expand all',
66
+ filterBestMatch: 'Best Match',
67
+ filterBestMatchFirst: 'Best Match First',
63
68
  filterByColumn: 'Filter by {column}',
64
- filterContains: 'Contains Exact',
69
+ filterContains: 'Contains',
65
70
  filterEmpty: 'Empty',
66
71
  filterEndsWith: 'Ends With',
67
72
  filterEquals: 'Equals',
68
- filterFuzzy: 'Fuzzy Match',
69
73
  filterGreaterThan: 'Greater Than',
70
74
  filterLessThan: 'Less Than',
71
75
  filterMode: 'Filter Mode: {filterType}',
@@ -246,7 +246,12 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
246
246
  </MenuItem>,
247
247
  ]}
248
248
  {!disableColumnHiding && [
249
- <MenuItem key={0} onClick={handleHideColumn} sx={commonMenuItemStyles}>
249
+ <MenuItem
250
+ disabled={column.disableColumnHiding}
251
+ key={0}
252
+ onClick={handleHideColumn}
253
+ sx={commonMenuItemStyles}
254
+ >
250
255
  <Box sx={commonListItemStyles}>
251
256
  <ListItemIcon>
252
257
  <VisibilityOffIcon />
@@ -4,11 +4,12 @@ import { useMRT } from '../useMRT';
4
4
  import type { MRT_FilterType, MRT_HeaderGroup } from '..';
5
5
  import { MRT_FILTER_TYPE } from '../enums';
6
6
  import {
7
+ bestMatch,
8
+ bestMatchFirst,
7
9
  contains,
8
10
  empty,
9
11
  endsWith,
10
12
  equals,
11
- fuzzy,
12
13
  greaterThan,
13
14
  lessThan,
14
15
  notEmpty,
@@ -24,7 +25,7 @@ const commonMenuItemStyles = {
24
25
 
25
26
  interface Props {
26
27
  anchorEl: HTMLElement | null;
27
- column: MRT_HeaderGroup;
28
+ column?: MRT_HeaderGroup;
28
29
  setAnchorEl: (anchorEl: HTMLElement | null) => void;
29
30
  onSelect?: () => void;
30
31
  }
@@ -35,7 +36,13 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
35
36
  onSelect,
36
37
  setAnchorEl,
37
38
  }) => {
38
- const { localization, setCurrentFilterTypes, tableInstance } = useMRT();
39
+ const {
40
+ enabledGlobalFilterTypes,
41
+ localization,
42
+ setCurrentFilterTypes,
43
+ setCurrentGlobalFilterType,
44
+ tableInstance,
45
+ } = useMRT();
39
46
 
40
47
  const filterTypes: {
41
48
  type: MRT_FILTER_TYPE;
@@ -46,15 +53,21 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
46
53
  () =>
47
54
  [
48
55
  {
49
- type: MRT_FILTER_TYPE.FUZZY,
50
- label: localization.filterFuzzy,
56
+ type: MRT_FILTER_TYPE.BEST_MATCH_FIRST,
57
+ label: localization.filterBestMatchFirst,
51
58
  divider: false,
52
- fn: fuzzy,
59
+ fn: bestMatchFirst,
60
+ },
61
+ {
62
+ type: MRT_FILTER_TYPE.BEST_MATCH,
63
+ label: localization.filterBestMatch,
64
+ divider: !!column,
65
+ fn: bestMatch,
53
66
  },
54
67
  {
55
68
  type: MRT_FILTER_TYPE.CONTAINS,
56
69
  label: localization.filterContains,
57
- divider: true,
70
+ divider: false,
58
71
  fn: contains,
59
72
  },
60
73
  {
@@ -105,26 +118,39 @@ export const MRT_FilterTypeMenu: FC<Props> = ({
105
118
  divider: false,
106
119
  fn: notEmpty,
107
120
  },
108
- ].filter(
109
- (filterType) =>
110
- !column.filterTypes || column.filterTypes.includes(filterType.type),
121
+ ].filter((filterType) =>
122
+ column
123
+ ? !column.enabledFilterTypes ||
124
+ column.enabledFilterTypes.includes(filterType.type)
125
+ : (!enabledGlobalFilterTypes ||
126
+ enabledGlobalFilterTypes.includes(filterType.type)) &&
127
+ [
128
+ MRT_FILTER_TYPE.BEST_MATCH_FIRST,
129
+ MRT_FILTER_TYPE.BEST_MATCH,
130
+ ].includes(filterType.type),
111
131
  ),
112
132
  [],
113
133
  );
114
134
 
115
135
  const handleSelectFilterType = (value: MRT_FILTER_TYPE) => {
116
- setAnchorEl(null);
117
- setCurrentFilterTypes((prev: { [key: string]: MRT_FilterType }) => ({
118
- ...prev,
119
- [column.id]: value,
120
- }));
121
- if ([MRT_FILTER_TYPE.EMPTY, MRT_FILTER_TYPE.NOT_EMPTY].includes(value)) {
122
- column.setFilter(' ');
136
+ if (column) {
137
+ setCurrentFilterTypes((prev: { [key: string]: MRT_FilterType }) => ({
138
+ ...prev,
139
+ [column.id]: value,
140
+ }));
141
+ if ([MRT_FILTER_TYPE.EMPTY, MRT_FILTER_TYPE.NOT_EMPTY].includes(value)) {
142
+ column.setFilter(' ');
143
+ }
144
+ } else {
145
+ setCurrentGlobalFilterType(value);
123
146
  }
147
+ setAnchorEl(null);
124
148
  onSelect?.();
125
149
  };
126
150
 
127
- const filterType = tableInstance.state.currentFilterTypes[column.id];
151
+ const filterType = column
152
+ ? tableInstance.state.currentFilterTypes[column.id]
153
+ : tableInstance.state.currentGlobalFilterType;
128
154
 
129
155
  return (
130
156
  <Menu
@@ -3,6 +3,7 @@ import { Button, Menu, Divider, Box } from '@mui/material';
3
3
  import type { MRT_ColumnInstance } from '..';
4
4
  import { useMRT } from '../useMRT';
5
5
  import { MRT_ShowHideColumnsMenuItems } from './MRT_ShowHideColumnsMenuItems';
6
+ import { findLowestLevelCols } from '../utils';
6
7
 
7
8
  interface Props {
8
9
  anchorEl: HTMLElement | null;
@@ -17,6 +18,16 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
17
18
  }) => {
18
19
  const { localization, tableInstance } = useMRT();
19
20
 
21
+ const hideAllColumns = () => {
22
+ (
23
+ findLowestLevelCols(
24
+ tableInstance.columns as MRT_ColumnInstance[],
25
+ ) as MRT_ColumnInstance[]
26
+ )
27
+ .filter((col: MRT_ColumnInstance) => !col.disableColumnHiding)
28
+ .forEach((col: MRT_ColumnInstance) => col.toggleHidden(true));
29
+ };
30
+
20
31
  return (
21
32
  <Menu
22
33
  anchorEl={anchorEl}
@@ -40,7 +51,7 @@ export const MRT_ShowHideColumnsMenu: FC<Props> = ({
40
51
  !tableInstance.getToggleHideAllColumnsProps().checked &&
41
52
  !tableInstance.getToggleHideAllColumnsProps().indeterminate
42
53
  }
43
- onClick={() => tableInstance.toggleHideAllColumns(true)}
54
+ onClick={hideAllColumns}
44
55
  >
45
56
  {localization.hideAll}
46
57
  </Button>
@@ -43,7 +43,7 @@ export const MRT_ShowHideColumnsMenuItems: FC<Props> = ({
43
43
  componentsProps={{ typography: { sx: { marginBottom: 0 } } }}
44
44
  checked={switchChecked}
45
45
  control={<Switch />}
46
- disabled={isSubMenu && switchChecked}
46
+ disabled={(isSubMenu && switchChecked) || column.disableColumnHiding}
47
47
  label={column.Header as string}
48
48
  onChange={() => handleToggleColumnHidden(column)}
49
49
  />
@@ -9,18 +9,11 @@ interface Props {
9
9
  export const MRT_TableSpacerCell: FC<Props> = ({ width }) => {
10
10
  const { muiTableBodyCellProps } = useMRT();
11
11
 
12
- const mTableBodyCellrops =
12
+ const tableCellProps =
13
13
  muiTableBodyCellProps instanceof Function
14
14
  ? muiTableBodyCellProps()
15
15
  : muiTableBodyCellProps;
16
16
 
17
- const tableCellProps = {
18
- ...mTableBodyCellrops,
19
- style: {
20
- ...mTableBodyCellrops?.style,
21
- },
22
- };
23
-
24
17
  return (
25
18
  <TableCell {...tableCellProps} sx={{ width, ...tableCellProps?.sx }} />
26
19
  );
package/src/useMRT.tsx CHANGED
@@ -47,6 +47,7 @@ export type UseMRT<D extends {} = {}> = MaterialReactTableProps<D> & {
47
47
  [key: string]: MRT_FilterType;
48
48
  }>
49
49
  >;
50
+ setCurrentGlobalFilterType: Dispatch<SetStateAction<MRT_FILTER_TYPE>>;
50
51
  setDensePadding: Dispatch<SetStateAction<boolean>>;
51
52
  setFullScreen: Dispatch<SetStateAction<boolean>>;
52
53
  setShowFilters: Dispatch<SetStateAction<boolean>>;
@@ -98,11 +99,17 @@ export const MaterialReactTableProvider = <D extends {} = {}>(
98
99
  [c.accessor as string]:
99
100
  c.filter ??
100
101
  props?.initialState?.filters?.[c.accessor as any] ??
101
- (!!c.filterSelectOptions ? 'equals' : 'fuzzy'),
102
+ (!!c.filterSelectOptions?.length
103
+ ? MRT_FILTER_TYPE.EQUALS
104
+ : MRT_FILTER_TYPE.BEST_MATCH),
102
105
  })),
103
106
  ),
104
107
  );
105
108
 
109
+ const [currentGlobalFilterType, setCurrentGlobalFilterType] = useState<
110
+ MRT_FilterType | string | undefined
111
+ >(props.globalFilter);
112
+
106
113
  const applyFiltersToColumns = useCallback(
107
114
  (cols: MRT_ColumnInterface[]) =>
108
115
  cols.map((column) => {
@@ -146,12 +153,14 @@ export const MaterialReactTableProvider = <D extends {} = {}>(
146
153
  // @ts-ignore
147
154
  columns,
148
155
  data,
156
+ globalFilter: currentGlobalFilterType,
149
157
  useControlledState: (state) =>
150
158
  useMemo(
151
159
  () => ({
152
160
  ...state,
153
161
  currentEditingRow,
154
162
  currentFilterTypes,
163
+ currentGlobalFilterType,
155
164
  densePadding,
156
165
  fullScreen,
157
166
  showFilters,
@@ -162,6 +171,7 @@ export const MaterialReactTableProvider = <D extends {} = {}>(
162
171
  [
163
172
  currentEditingRow,
164
173
  currentFilterTypes,
174
+ currentGlobalFilterType,
165
175
  densePadding,
166
176
  fullScreen,
167
177
  showFilters,
@@ -196,6 +206,7 @@ export const MaterialReactTableProvider = <D extends {} = {}>(
196
206
  //@ts-ignore
197
207
  setCurrentEditingRow,
198
208
  setCurrentFilterTypes,
209
+ setCurrentGlobalFilterType,
199
210
  setDensePadding,
200
211
  setFullScreen,
201
212
  setShowFilters,
package/src/utils.ts CHANGED
@@ -1,8 +1,12 @@
1
- import { MRT_ColumnInterface } from '.';
1
+ import { MRT_ColumnInstance, MRT_ColumnInterface } from '.';
2
2
 
3
- export const findLowestLevelCols = (columns: MRT_ColumnInterface[]) => {
4
- let lowestLevelColumns: MRT_ColumnInterface[] = columns;
5
- let currentCols: MRT_ColumnInterface[] | undefined = columns;
3
+ export const findLowestLevelCols = (
4
+ columns: MRT_ColumnInterface[] | MRT_ColumnInstance[],
5
+ ) => {
6
+ let lowestLevelColumns: MRT_ColumnInterface[] | MRT_ColumnInstance[] =
7
+ columns;
8
+ let currentCols: MRT_ColumnInterface[] | MRT_ColumnInstance[] | undefined =
9
+ columns;
6
10
  while (!!currentCols?.length && currentCols.some((col) => col.columns)) {
7
11
  const nextCols: MRT_ColumnInterface[] = currentCols
8
12
  .filter((col) => !!col.columns)