material-react-table 1.7.3 → 1.8.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.
Files changed (54) hide show
  1. package/README.md +5 -13
  2. package/dist/cjs/index.js +110 -72
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/types/MaterialReactTable.d.ts +22 -8
  5. package/dist/cjs/types/body/MRT_TableBody.d.ts +3 -4
  6. package/dist/cjs/types/body/MRT_TableBodyCell.d.ts +2 -3
  7. package/dist/cjs/types/body/MRT_TableBodyRow.d.ts +4 -5
  8. package/dist/cjs/types/body/MRT_TableDetailPanel.d.ts +2 -3
  9. package/dist/cjs/types/column.utils.d.ts +3 -2
  10. package/dist/cjs/types/footer/MRT_TableFooter.d.ts +2 -3
  11. package/dist/cjs/types/footer/MRT_TableFooterRow.d.ts +2 -3
  12. package/dist/cjs/types/head/MRT_TableHead.d.ts +2 -3
  13. package/dist/cjs/types/head/MRT_TableHeadRow.d.ts +2 -3
  14. package/dist/cjs/types/icons.d.ts +0 -1
  15. package/dist/cjs/types/table/MRT_TableRoot.d.ts +1 -272
  16. package/dist/esm/material-react-table.esm.js +108 -72
  17. package/dist/esm/material-react-table.esm.js.map +1 -1
  18. package/dist/esm/types/MaterialReactTable.d.ts +22 -8
  19. package/dist/esm/types/body/MRT_TableBody.d.ts +3 -4
  20. package/dist/esm/types/body/MRT_TableBodyCell.d.ts +2 -3
  21. package/dist/esm/types/body/MRT_TableBodyRow.d.ts +4 -5
  22. package/dist/esm/types/body/MRT_TableDetailPanel.d.ts +2 -3
  23. package/dist/esm/types/column.utils.d.ts +3 -2
  24. package/dist/esm/types/footer/MRT_TableFooter.d.ts +2 -3
  25. package/dist/esm/types/footer/MRT_TableFooterRow.d.ts +2 -3
  26. package/dist/esm/types/head/MRT_TableHead.d.ts +2 -3
  27. package/dist/esm/types/head/MRT_TableHeadRow.d.ts +2 -3
  28. package/dist/esm/types/icons.d.ts +0 -1
  29. package/dist/esm/types/table/MRT_TableRoot.d.ts +1 -272
  30. package/dist/index.d.ts +22 -8
  31. package/package.json +13 -14
  32. package/src/MaterialReactTable.tsx +50 -7
  33. package/src/body/MRT_TableBody.tsx +11 -10
  34. package/src/body/MRT_TableBodyCell.tsx +11 -13
  35. package/src/body/MRT_TableBodyCellValue.tsx +1 -0
  36. package/src/body/MRT_TableBodyRow.tsx +14 -7
  37. package/src/body/MRT_TableDetailPanel.tsx +2 -3
  38. package/src/buttons/MRT_ExpandAllButton.tsx +10 -8
  39. package/src/buttons/MRT_ExpandButton.tsx +10 -8
  40. package/src/buttons/MRT_ToggleRowActionMenuButton.tsx +4 -1
  41. package/src/column.utils.ts +16 -6
  42. package/src/footer/MRT_TableFooter.tsx +2 -3
  43. package/src/footer/MRT_TableFooterRow.tsx +7 -3
  44. package/src/head/MRT_TableHead.tsx +2 -3
  45. package/src/head/MRT_TableHeadCell.tsx +1 -0
  46. package/src/head/MRT_TableHeadCellColumnActionsButton.tsx +1 -1
  47. package/src/head/MRT_TableHeadCellResizeHandle.tsx +2 -5
  48. package/src/head/MRT_TableHeadRow.tsx +7 -3
  49. package/src/icons.ts +0 -3
  50. package/src/inputs/MRT_EditCellTextField.tsx +38 -2
  51. package/src/menus/MRT_FilterOptionMenu.tsx +14 -5
  52. package/src/menus/MRT_RowActionMenu.tsx +12 -10
  53. package/src/table/MRT_Table.tsx +6 -5
  54. package/src/table/MRT_TableRoot.tsx +33 -19
@@ -1,5 +1,6 @@
1
1
  import React, { ChangeEvent, FocusEvent, KeyboardEvent, useState } from 'react';
2
2
  import TextField from '@mui/material/TextField';
3
+ import MenuItem from '@mui/material/MenuItem';
3
4
  import type { TextFieldProps } from '@mui/material/TextField';
4
5
  import type { MRT_Cell, MRT_TableInstance } from '..';
5
6
 
@@ -47,6 +48,8 @@ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
47
48
  ...mcTableBodyCellEditTextFieldProps,
48
49
  };
49
50
 
51
+ const isSelectEdit = columnDef.editVariant === 'select';
52
+
50
53
  const saveRow = (newValue: string) => {
51
54
  if (editingRow) {
52
55
  setEditingRow({
@@ -83,7 +86,11 @@ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
83
86
 
84
87
  return (
85
88
  <TextField
86
- disabled={columnDef.enableEditing === false}
89
+ disabled={
90
+ (columnDef.enableEditing instanceof Function
91
+ ? columnDef.enableEditing(row)
92
+ : columnDef.enableEditing) === false
93
+ }
87
94
  fullWidth
88
95
  inputRef={(inputRef) => {
89
96
  if (inputRef) {
@@ -97,6 +104,7 @@ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
97
104
  margin="none"
98
105
  name={column.id}
99
106
  placeholder={columnDef.header}
107
+ select={isSelectEdit}
100
108
  value={value}
101
109
  variant="standard"
102
110
  {...textFieldProps}
@@ -107,6 +115,34 @@ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
107
115
  onBlur={handleBlur}
108
116
  onChange={handleChange}
109
117
  onKeyDown={handleEnterKeyDown}
110
- />
118
+ >
119
+ {columnDef?.editSelectOptions?.map(
120
+ (option: string | { text: string; value: string }) => {
121
+ let value: string;
122
+ let text: string;
123
+ if (typeof option !== 'object') {
124
+ value = option;
125
+ text = option;
126
+ } else {
127
+ value = option.value;
128
+ text = option.text;
129
+ }
130
+ return (
131
+ <MenuItem
132
+ key={value}
133
+ sx={{
134
+ display: 'flex',
135
+ m: 0,
136
+ alignItems: 'center',
137
+ gap: '0.5rem',
138
+ }}
139
+ value={value}
140
+ >
141
+ {text}
142
+ </MenuItem>
143
+ );
144
+ },
145
+ )}
146
+ </TextField>
111
147
  );
112
148
  };
@@ -131,6 +131,7 @@ export const MRT_FilterOptionMenu = <TData extends Record<string, any> = {}>({
131
131
  const { globalFilterFn, density } = getState();
132
132
  const { column } = header ?? {};
133
133
  const { columnDef } = column ?? {};
134
+ const currentFilterValue = column?.getFilterValue();
134
135
 
135
136
  const allowedColumnFilterOptions =
136
137
  columnDef?.columnFilterModeOptions ?? columnFilterModeOptions;
@@ -155,15 +156,19 @@ export const MRT_FilterOptionMenu = <TData extends Record<string, any> = {}>({
155
156
  [header.id]: option,
156
157
  }));
157
158
  if (['empty', 'notEmpty'].includes(option as string)) {
158
- column.setFilterValue(' ');
159
+ if (currentFilterValue !== ' ') {
160
+ column.setFilterValue(' ');
161
+ }
159
162
  } else if (
160
163
  columnDef?.filterVariant === 'multi-select' ||
161
164
  ['arrIncludesSome', 'arrIncludesAll', 'arrIncludes'].includes(
162
165
  option as string,
163
166
  )
164
167
  ) {
165
- column.setFilterValue([]);
166
- setFilterValue?.([]);
168
+ if ((currentFilterValue as Array<any>)?.length) {
169
+ column.setFilterValue([]);
170
+ setFilterValue?.([]);
171
+ }
167
172
  } else if (
168
173
  columnDef?.filterVariant === 'range' ||
169
174
  ['between', 'betweenInclusive', 'inNumberRange'].includes(
@@ -173,8 +178,12 @@ export const MRT_FilterOptionMenu = <TData extends Record<string, any> = {}>({
173
178
  column.setFilterValue(['', '']);
174
179
  setFilterValue?.('');
175
180
  } else {
176
- column.setFilterValue('');
177
- setFilterValue?.('');
181
+ if (
182
+ !['', undefined].includes(currentFilterValue as string | undefined)
183
+ ) {
184
+ column.setFilterValue('');
185
+ setFilterValue?.('');
186
+ }
178
187
  }
179
188
  } else {
180
189
  setGlobalFilterFn(option);
@@ -44,16 +44,18 @@ export const MRT_RowActionMenu = ({
44
44
  dense: density === 'compact',
45
45
  }}
46
46
  >
47
- {enableEditing && (
48
- <MenuItem onClick={handleEdit} sx={commonMenuItemStyles}>
49
- <Box sx={commonListItemStyles}>
50
- <ListItemIcon>
51
- <EditIcon />
52
- </ListItemIcon>
53
- {localization.edit}
54
- </Box>
55
- </MenuItem>
56
- )}
47
+ {enableEditing instanceof Function
48
+ ? enableEditing(row)
49
+ : enableEditing && (
50
+ <MenuItem onClick={handleEdit} sx={commonMenuItemStyles}>
51
+ <Box sx={commonListItemStyles}>
52
+ <ListItemIcon>
53
+ <EditIcon />
54
+ </ListItemIcon>
55
+ {localization.edit}
56
+ </Box>
57
+ </MenuItem>
58
+ )}
57
59
  {renderRowActionMenuItems?.({
58
60
  row,
59
61
  table,
@@ -3,14 +3,13 @@ import {
3
3
  defaultRangeExtractor,
4
4
  Range,
5
5
  useVirtualizer,
6
- Virtualizer,
7
6
  } from '@tanstack/react-virtual';
8
7
  import Table from '@mui/material/Table';
9
8
  import { MRT_TableHead } from '../head/MRT_TableHead';
10
9
  import { Memo_MRT_TableBody, MRT_TableBody } from '../body/MRT_TableBody';
11
10
  import { MRT_TableFooter } from '../footer/MRT_TableFooter';
12
11
  import { parseCSSVarId } from '../column.utils';
13
- import type { MRT_TableInstance } from '..';
12
+ import type { MRT_TableInstance, MRT_Virtualizer } from '..';
14
13
 
15
14
  interface Props {
16
15
  table: MRT_TableInstance;
@@ -58,8 +57,10 @@ export const MRT_Table = ({ table }: Props) => {
58
57
  const headers = getFlatHeaders();
59
58
  const colSizes: { [key: string]: number } = {};
60
59
  for (let i = 0; i < headers.length; i++) {
61
- const h = headers[i];
62
- colSizes[`--col-${parseCSSVarId(h.column.id)}-size`] = h.getSize();
60
+ const header = headers[i];
61
+ const colSize = header.getSize();
62
+ colSizes[`--header-${parseCSSVarId(header.id)}-size`] = colSize;
63
+ colSizes[`--col-${parseCSSVarId(header.column.id)}-size`] = colSize;
63
64
  }
64
65
  return colSizes;
65
66
  }, [columns, columnSizing, columnSizingInfo]);
@@ -93,7 +94,7 @@ export const MRT_Table = ({ table }: Props) => {
93
94
  );
94
95
 
95
96
  const columnVirtualizer:
96
- | Virtualizer<HTMLDivElement, HTMLTableCellElement>
97
+ | MRT_Virtualizer<HTMLDivElement, HTMLTableCellElement>
97
98
  | undefined = enableColumnVirtualization
98
99
  ? useVirtualizer({
99
100
  count: table.getVisibleLeafColumns().length,
@@ -26,8 +26,7 @@ import {
26
26
  showExpandColumn,
27
27
  getColumnId,
28
28
  } from '../column.utils';
29
- import type { GroupingState, TableState } from '@tanstack/react-table';
30
- import type {
29
+ import {
31
30
  MRT_Cell,
32
31
  MRT_Column,
33
32
  MRT_ColumnDef,
@@ -37,11 +36,14 @@ import type {
37
36
  MRT_TableInstance,
38
37
  MRT_TableState,
39
38
  MaterialReactTableProps,
39
+ MRT_DensityState,
40
+ MRT_ColumnOrderState,
41
+ MRT_GroupingState,
40
42
  } from '..';
41
43
 
42
- export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
44
+ export const MRT_TableRoot: any = <TData extends Record<string, any> = {}>(
43
45
  props: MaterialReactTableProps<TData> & { localization: MRT_Localization },
44
- ) => {
46
+ ): JSX.Element => {
45
47
  const bottomToolbarRef = useRef<HTMLDivElement>(null);
46
48
  const editInputRefs = useRef<Record<string, HTMLInputElement>>({});
47
49
  const filterInputRefs = useRef<Record<string, HTMLInputElement>>({});
@@ -76,10 +78,10 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
76
78
  ),
77
79
  ),
78
80
  );
79
- const [columnOrder, setColumnOrder] = useState(
81
+ const [columnOrder, setColumnOrder] = useState<MRT_ColumnOrderState>(
80
82
  initialState.columnOrder ?? [],
81
83
  );
82
- const [density, setDensity] = useState(
84
+ const [density, setDensity] = useState<MRT_DensityState>(
83
85
  initialState?.density ?? 'comfortable',
84
86
  );
85
87
  const [draggingColumn, setDraggingColumn] =
@@ -96,7 +98,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
96
98
  const [globalFilterFn, setGlobalFilterFn] = useState<MRT_FilterOption>(
97
99
  initialState.globalFilterFn ?? 'fuzzy',
98
100
  );
99
- const [grouping, setGrouping] = useState<GroupingState>(
101
+ const [grouping, setGrouping] = useState<MRT_GroupingState>(
100
102
  initialState.grouping ?? [],
101
103
  );
102
104
  const [hoveredColumn, setHoveredColumn] = useState<
@@ -105,19 +107,19 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
105
107
  const [hoveredRow, setHoveredRow] = useState<
106
108
  MRT_Row<TData> | { id: string } | null
107
109
  >(initialState.hoveredRow ?? null);
108
- const [isFullScreen, setIsFullScreen] = useState(
110
+ const [isFullScreen, setIsFullScreen] = useState<boolean>(
109
111
  initialState?.isFullScreen ?? false,
110
112
  );
111
- const [showAlertBanner, setShowAlertBanner] = useState(
113
+ const [showAlertBanner, setShowAlertBanner] = useState<boolean>(
112
114
  props.initialState?.showAlertBanner ?? false,
113
115
  );
114
- const [showColumnFilters, setShowFilters] = useState(
116
+ const [showColumnFilters, setShowFilters] = useState<boolean>(
115
117
  initialState?.showColumnFilters ?? false,
116
118
  );
117
- const [showGlobalFilter, setShowGlobalFilter] = useState(
119
+ const [showGlobalFilter, setShowGlobalFilter] = useState<boolean>(
118
120
  initialState?.showGlobalFilter ?? false,
119
121
  );
120
- const [showToolbarDropZone, setShowToolbarDropZone] = useState(
122
+ const [showToolbarDropZone, setShowToolbarDropZone] = useState<boolean>(
121
123
  initialState?.showToolbarDropZone ?? false,
122
124
  );
123
125
 
@@ -125,14 +127,18 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
125
127
  () =>
126
128
  (
127
129
  [
128
- columnOrder.includes('mrt-row-drag') && {
130
+ (props.state?.columnOrder ?? columnOrder).includes(
131
+ 'mrt-row-drag',
132
+ ) && {
129
133
  header: props.localization.move,
130
134
  size: 60,
131
135
  ...props.defaultDisplayColumn,
132
136
  ...props.displayColumnDefOptions?.['mrt-row-drag'],
133
137
  id: 'mrt-row-drag',
134
138
  },
135
- columnOrder.includes('mrt-row-actions') && {
139
+ (props.state?.columnOrder ?? columnOrder).includes(
140
+ 'mrt-row-actions',
141
+ ) && {
136
142
  Cell: ({ cell, row }) => (
137
143
  <MRT_ToggleRowActionMenuButton
138
144
  cell={cell as any}
@@ -146,8 +152,10 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
146
152
  ...props.displayColumnDefOptions?.['mrt-row-actions'],
147
153
  id: 'mrt-row-actions',
148
154
  },
149
- columnOrder.includes('mrt-row-expand') &&
150
- showExpandColumn(props, grouping) && {
155
+ (props.state?.columnOrder ?? columnOrder).includes(
156
+ 'mrt-row-expand',
157
+ ) &&
158
+ showExpandColumn(props, props.state?.grouping ?? grouping) && {
151
159
  Cell: ({ row }) => (
152
160
  <MRT_ExpandButton row={row as any} table={table as any} />
153
161
  ),
@@ -160,7 +168,9 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
160
168
  ...props.displayColumnDefOptions?.['mrt-row-expand'],
161
169
  id: 'mrt-row-expand',
162
170
  },
163
- columnOrder.includes('mrt-row-select') && {
171
+ (props.state?.columnOrder ?? columnOrder).includes(
172
+ 'mrt-row-select',
173
+ ) && {
164
174
  Cell: ({ row }) => (
165
175
  <MRT_SelectCheckbox row={row as any} table={table as any} />
166
176
  ),
@@ -174,7 +184,9 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
174
184
  ...props.displayColumnDefOptions?.['mrt-row-select'],
175
185
  id: 'mrt-row-select',
176
186
  },
177
- columnOrder.includes('mrt-row-numbers') && {
187
+ (props.state?.columnOrder ?? columnOrder).includes(
188
+ 'mrt-row-numbers',
189
+ ) && {
178
190
  Cell: ({ row }) => row.index + 1,
179
191
  Header: () => props.localization.rowNumber,
180
192
  header: props.localization.rowNumbers,
@@ -206,6 +218,8 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
206
218
  props.localization,
207
219
  props.positionActionsColumn,
208
220
  props.renderDetailPanel,
221
+ props.state?.columnOrder,
222
+ props.state?.grouping,
209
223
  ],
210
224
  );
211
225
 
@@ -289,7 +303,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
289
303
  showGlobalFilter,
290
304
  showToolbarDropZone,
291
305
  ...props.state,
292
- } as TableState,
306
+ },
293
307
  }),
294
308
  refs: {
295
309
  bottomToolbarRef,