material-react-table 0.36.1 → 0.37.1

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 (35) hide show
  1. package/README.md +7 -3
  2. package/dist/cjs/MaterialReactTable.d.ts +33 -15
  3. package/dist/cjs/body/MRT_EditRowModal.d.ts +8 -0
  4. package/dist/cjs/buttons/MRT_EditActionButtons.d.ts +5 -5
  5. package/dist/cjs/column.utils.d.ts +2 -1
  6. package/dist/cjs/index.js +187 -118
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/inputs/MRT_EditCellTextField.d.ts +5 -5
  9. package/dist/esm/MaterialReactTable.d.ts +33 -15
  10. package/dist/esm/body/MRT_EditRowModal.d.ts +8 -0
  11. package/dist/esm/buttons/MRT_EditActionButtons.d.ts +5 -5
  12. package/dist/esm/column.utils.d.ts +2 -1
  13. package/dist/esm/inputs/MRT_EditCellTextField.d.ts +5 -5
  14. package/dist/esm/material-react-table.esm.js +188 -119
  15. package/dist/esm/material-react-table.esm.js.map +1 -1
  16. package/dist/index.d.ts +33 -15
  17. package/package.json +4 -4
  18. package/src/MaterialReactTable.tsx +48 -12
  19. package/src/body/MRT_EditRowModal.tsx +59 -0
  20. package/src/body/MRT_TableBodyCell.tsx +12 -16
  21. package/src/body/MRT_TableBodyRow.tsx +1 -1
  22. package/src/body/MRT_TableBodyRowGrabHandle.tsx +3 -2
  23. package/src/buttons/MRT_CopyButton.tsx +2 -2
  24. package/src/buttons/MRT_EditActionButtons.tsx +49 -25
  25. package/src/buttons/MRT_ToggleGlobalFilterButton.tsx +3 -16
  26. package/src/buttons/MRT_ToggleRowActionMenuButton.tsx +2 -1
  27. package/src/column.utils.ts +19 -12
  28. package/src/inputs/MRT_EditCellTextField.tsx +33 -19
  29. package/src/inputs/MRT_FilterTextField.tsx +9 -6
  30. package/src/inputs/MRT_GlobalFilterTextField.tsx +7 -2
  31. package/src/menus/MRT_ColumnActionMenu.tsx +2 -12
  32. package/src/table/MRT_TableContainer.tsx +10 -10
  33. package/src/table/MRT_TableRoot.tsx +48 -30
  34. package/src/toolbar/MRT_BottomToolbar.tsx +8 -2
  35. package/src/toolbar/MRT_TopToolbar.tsx +8 -2
@@ -24,6 +24,7 @@ export const MRT_ToggleRowActionMenuButton: FC<Props> = ({ row, table }) => {
24
24
  const {
25
25
  getState,
26
26
  options: {
27
+ editingMode,
27
28
  enableEditing,
28
29
  icons: { EditIcon, MoreHorizIcon },
29
30
  localization,
@@ -52,7 +53,7 @@ export const MRT_ToggleRowActionMenuButton: FC<Props> = ({ row, table }) => {
52
53
  <>
53
54
  {renderRowActions ? (
54
55
  <>{renderRowActions({ row, table })}</>
55
- ) : row.id === editingRow?.id ? (
56
+ ) : row.id === editingRow?.id && editingMode === 'row' ? (
56
57
  <MRT_EditActionButtons row={row} table={table} />
57
58
  ) : !renderRowActionMenuItems && enableEditing ? (
58
59
  <Tooltip placement="right" arrow title={localization.edit}>
@@ -1,4 +1,4 @@
1
- import { ColumnOrderState } from '@tanstack/react-table';
1
+ import { ColumnOrderState, GroupingState } from '@tanstack/react-table';
2
2
  import {
3
3
  MaterialReactTableProps,
4
4
  MRT_Column,
@@ -74,10 +74,9 @@ export const prepareColumns = <TData extends Record<string, any> = {}>(
74
74
  } else if (columnDef.columnDefType === 'data') {
75
75
  if (Object.keys(filterFns).includes(columnFilterFns[columnDef.id])) {
76
76
  columnDef.filterFn =
77
- // @ts-ignore
78
77
  filterFns[columnFilterFns[columnDef.id]] ?? filterFns.fuzzy;
79
- //@ts-ignore
80
- columnDef._filterFn = columnFilterFns[columnDef.id];
78
+ (columnDef as MRT_DefinedColumnDef)._filterFn =
79
+ columnFilterFns[columnDef.id];
81
80
  }
82
81
  if (Object.keys(sortingFns).includes(columnDef.sortingFn as string)) {
83
82
  // @ts-ignore
@@ -108,6 +107,16 @@ export const reorderColumn = <TData extends Record<string, any> = {}>(
108
107
  return [...columnOrder];
109
108
  };
110
109
 
110
+ export const showExpandColumn = <TData extends Record<string, any> = {}>(
111
+ props: MaterialReactTableProps<TData>,
112
+ grouping?: GroupingState,
113
+ ) =>
114
+ !!(
115
+ props.enableExpanding ||
116
+ (props.enableGrouping && (grouping === undefined || grouping?.length)) ||
117
+ props.renderDetailPanel
118
+ );
119
+
111
120
  export const getLeadingDisplayColumnIds = <
112
121
  TData extends Record<string, any> = {},
113
122
  >(
@@ -116,12 +125,11 @@ export const getLeadingDisplayColumnIds = <
116
125
  [
117
126
  (props.enableRowDragging || props.enableRowOrdering) && 'mrt-row-drag',
118
127
  ((props.positionActionsColumn === 'first' && props.enableRowActions) ||
119
- (props.enableEditing && props.editingMode === 'row')) &&
128
+ (props.enableEditing &&
129
+ ['row', 'modal'].includes(props.editingMode ?? ''))) &&
120
130
  'mrt-row-actions',
121
131
  props.positionExpandColumn === 'first' &&
122
- (props.enableExpanding ||
123
- props.enableGrouping ||
124
- props.renderDetailPanel) &&
132
+ showExpandColumn(props) &&
125
133
  'mrt-row-expand',
126
134
  props.enableRowSelection && 'mrt-row-select',
127
135
  props.enableRowNumbers && 'mrt-row-numbers',
@@ -133,12 +141,11 @@ export const getTrailingDisplayColumnIds = <
133
141
  props: MaterialReactTableProps<TData>,
134
142
  ) => [
135
143
  ((props.positionActionsColumn === 'last' && props.enableRowActions) ||
136
- (props.enableEditing && props.editingMode === 'row')) &&
144
+ (props.enableEditing &&
145
+ ['row', 'modal'].includes(props.editingMode ?? ''))) &&
137
146
  'mrt-row-actions',
138
147
  props.positionExpandColumn === 'last' &&
139
- (props.enableExpanding ||
140
- props.enableGrouping ||
141
- props.renderDetailPanel) &&
148
+ showExpandColumn(props) &&
142
149
  'mrt-row-expand',
143
150
  ];
144
151
 
@@ -1,22 +1,22 @@
1
- import React, {
2
- ChangeEvent,
3
- FC,
4
- FocusEvent,
5
- MouseEvent,
6
- useState,
7
- } from 'react';
1
+ import React, { ChangeEvent, FocusEvent, MouseEvent, useState } from 'react';
8
2
  import { TextField, TextFieldProps } from '@mui/material';
9
- import type { MRT_Cell, MRT_Row, MRT_TableInstance } from '..';
3
+ import type { MRT_Cell, MRT_TableInstance } from '..';
10
4
 
11
- interface Props {
12
- cell: MRT_Cell;
13
- table: MRT_TableInstance;
5
+ interface Props<TData extends Record<string, any> = {}> {
6
+ cell: MRT_Cell<TData>;
7
+ table: MRT_TableInstance<TData>;
8
+ showLabel?: boolean;
14
9
  }
15
10
 
16
- export const MRT_EditCellTextField: FC<Props> = ({ cell, table }) => {
11
+ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
12
+ cell,
13
+ showLabel,
14
+ table,
15
+ }: Props<TData>) => {
17
16
  const {
18
17
  getState,
19
- options: { tableId, muiTableBodyCellEditTextFieldProps },
18
+ options: { muiTableBodyCellEditTextFieldProps },
19
+ refs: { editInputRefs },
20
20
  setEditingCell,
21
21
  setEditingRow,
22
22
  } = table;
@@ -28,13 +28,15 @@ export const MRT_EditCellTextField: FC<Props> = ({ cell, table }) => {
28
28
 
29
29
  const mTableBodyCellEditTextFieldProps =
30
30
  muiTableBodyCellEditTextFieldProps instanceof Function
31
- ? muiTableBodyCellEditTextFieldProps({ cell, table })
31
+ ? muiTableBodyCellEditTextFieldProps({ cell, column, row, table })
32
32
  : muiTableBodyCellEditTextFieldProps;
33
33
 
34
34
  const mcTableBodyCellEditTextFieldProps =
35
35
  columnDef.muiTableBodyCellEditTextFieldProps instanceof Function
36
36
  ? columnDef.muiTableBodyCellEditTextFieldProps({
37
37
  cell,
38
+ column,
39
+ row,
38
40
  table,
39
41
  })
40
42
  : columnDef.muiTableBodyCellEditTextFieldProps;
@@ -52,26 +54,38 @@ export const MRT_EditCellTextField: FC<Props> = ({ cell, table }) => {
52
54
  const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
53
55
  textFieldProps.onBlur?.(event);
54
56
  if (editingRow) {
55
- if (!row._valuesCache) row._valuesCache = {};
56
- (row._valuesCache as Record<string, any>)[column.id] = value;
57
- setEditingRow({ ...editingRow } as MRT_Row);
57
+ setEditingRow({
58
+ ...editingRow,
59
+ _valuesCache: { ...editingRow._valuesCache, [column.id]: value },
60
+ } as any);
58
61
  }
59
62
  setEditingCell(null);
60
63
  };
61
64
 
62
65
  if (columnDef.Edit) {
63
- return <>{columnDef.Edit?.({ cell, column, table })}</>;
66
+ return <>{columnDef.Edit?.({ cell, column, row, table })}</>;
64
67
  }
65
68
 
66
69
  return (
67
70
  <TextField
68
- id={`mrt-${tableId}-edit-cell-text-field-${cell.id}`}
71
+ disabled={columnDef.enableEditing === false}
72
+ fullWidth
73
+ label={showLabel ? column.columnDef.header : undefined}
69
74
  margin="none"
75
+ name={cell.id}
70
76
  onClick={(e: MouseEvent<HTMLInputElement>) => e.stopPropagation()}
71
77
  placeholder={columnDef.header}
72
78
  value={value}
73
79
  variant="standard"
74
80
  {...textFieldProps}
81
+ inputRef={(inputRef) => {
82
+ if (inputRef) {
83
+ editInputRefs.current[column.id] = inputRef;
84
+ if (textFieldProps.inputRef) {
85
+ textFieldProps.inputRef = inputRef;
86
+ }
87
+ }
88
+ }}
75
89
  onBlur={handleBlur}
76
90
  onChange={handleChange}
77
91
  />
@@ -40,8 +40,8 @@ export const MRT_FilterTextField: FC<Props> = ({
40
40
  icons: { FilterListIcon, CloseIcon },
41
41
  localization,
42
42
  muiTableHeadCellFilterTextFieldProps,
43
- tableId,
44
43
  },
44
+ refs: { filterInputRefs },
45
45
  setColumnFilterFns,
46
46
  } = table;
47
47
  const { column } = header;
@@ -80,9 +80,6 @@ export const MRT_FilterTextField: FC<Props> = ({
80
80
  (!isSelectFilter && !isMultiSelectFilter);
81
81
 
82
82
  const currentFilterOption = columnFilterFns?.[header.id];
83
- const filterId = `mrt-${tableId}-${header.id}-filter-text-field${
84
- rangeFilterIndex ?? ''
85
- }`;
86
83
  const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption)
87
84
  ? //@ts-ignore
88
85
  localization[
@@ -184,7 +181,6 @@ export const MRT_FilterTextField: FC<Props> = ({
184
181
  <>
185
182
  <TextField
186
183
  fullWidth
187
- id={filterId}
188
184
  inputProps={{
189
185
  disabled: !!filterChipLabel,
190
186
  sx: {
@@ -195,7 +191,7 @@ export const MRT_FilterTextField: FC<Props> = ({
195
191
  }}
196
192
  helperText={
197
193
  showChangeModeButton ? (
198
- <label htmlFor={filterId}>
194
+ <label>
199
195
  {localization.filterMode.replace(
200
196
  '{filterType}',
201
197
  // @ts-ignore
@@ -294,6 +290,13 @@ export const MRT_FilterTextField: FC<Props> = ({
294
290
  : undefined,
295
291
  }}
296
292
  {...textFieldProps}
293
+ inputRef={(inputRef) => {
294
+ filterInputRefs.current[`${column.id}-${rangeFilterIndex ?? 0}`] =
295
+ inputRef;
296
+ if (textFieldProps.inputRef) {
297
+ textFieldProps.inputRef = inputRef;
298
+ }
299
+ }}
297
300
  sx={(theme) => ({
298
301
  p: 0,
299
302
  minWidth: !filterChipLabel ? '6rem' : 'auto',
@@ -27,8 +27,8 @@ export const MRT_GlobalFilterTextField = <
27
27
  icons: { SearchIcon, CloseIcon },
28
28
  localization,
29
29
  muiSearchTextFieldProps,
30
- tableId,
31
30
  },
31
+ refs: { searchInputRef },
32
32
  } = table;
33
33
  const { globalFilter, showGlobalFilter } = getState();
34
34
 
@@ -64,7 +64,6 @@ export const MRT_GlobalFilterTextField = <
64
64
  return (
65
65
  <Collapse in={showGlobalFilter} orientation="horizontal">
66
66
  <TextField
67
- id={`mrt-${tableId}-search-text-field`}
68
67
  placeholder={localization.search}
69
68
  onChange={handleChange}
70
69
  value={searchValue ?? ''}
@@ -104,6 +103,12 @@ export const MRT_GlobalFilterTextField = <
104
103
  ),
105
104
  }}
106
105
  {...textFieldProps}
106
+ inputRef={(inputRef) => {
107
+ searchInputRef.current = inputRef;
108
+ if (textFieldProps?.inputRef) {
109
+ textFieldProps.inputRef = inputRef;
110
+ }
111
+ }}
107
112
  />
108
113
  <MRT_FilterOptionMenu
109
114
  anchorEl={anchorEl}
@@ -54,9 +54,9 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
54
54
  RestartAltIcon,
55
55
  VisibilityOffIcon,
56
56
  },
57
- tableId,
58
57
  localization,
59
58
  },
59
+ refs: { filterInputRefs },
60
60
  setShowFilters,
61
61
  } = table;
62
62
  const { column } = header;
@@ -111,17 +111,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
111
111
 
112
112
  const handleFilterByColumn = () => {
113
113
  setShowFilters(true);
114
- setTimeout(
115
- () =>
116
- document
117
- .getElementById(
118
- // @ts-ignore
119
- header.muiTableHeadCellFilterTextFieldProps?.id ??
120
- `mrt-${tableId}-${header.id}-filter-text-field`,
121
- )
122
- ?.focus(),
123
- 200,
124
- );
114
+ queueMicrotask(() => filterInputRefs.current[`${column.id}-0`]?.focus());
125
115
  setAnchorEl(null);
126
116
  };
127
117
 
@@ -3,7 +3,6 @@ import React, {
3
3
  RefObject,
4
4
  useEffect,
5
5
  useLayoutEffect,
6
- useRef,
7
6
  useState,
8
7
  } from 'react';
9
8
  import { TableContainer } from '@mui/material';
@@ -24,8 +23,8 @@ export const MRT_TableContainer: FC<Props> = ({ table }) => {
24
23
  enableStickyHeader,
25
24
  enableRowVirtualization,
26
25
  muiTableContainerProps,
27
- tableId,
28
26
  },
27
+ refs: { tableContainerRef, bottomToolbarRef, topToolbarRef },
29
28
  } = table;
30
29
  const { isFullScreen } = getState();
31
30
 
@@ -36,20 +35,15 @@ export const MRT_TableContainer: FC<Props> = ({ table }) => {
36
35
  ? muiTableContainerProps({ table })
37
36
  : muiTableContainerProps;
38
37
 
39
- const tableContainerRef =
40
- tableContainerProps?.ref ?? useRef<HTMLDivElement>(null);
41
-
42
38
  useIsomorphicLayoutEffect(() => {
43
39
  const topToolbarHeight =
44
40
  typeof document !== 'undefined'
45
- ? document?.getElementById(`mrt-${tableId}-toolbar-top`)
46
- ?.offsetHeight ?? 0
41
+ ? topToolbarRef.current?.offsetHeight ?? 0
47
42
  : 0;
48
43
 
49
44
  const bottomToolbarHeight =
50
45
  typeof document !== 'undefined'
51
- ? document?.getElementById(`mrt-${tableId}-toolbar-bottom`)
52
- ?.offsetHeight ?? 0
46
+ ? bottomToolbarRef?.current?.offsetHeight ?? 0
53
47
  : 0;
54
48
 
55
49
  setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
@@ -57,8 +51,14 @@ export const MRT_TableContainer: FC<Props> = ({ table }) => {
57
51
 
58
52
  return (
59
53
  <TableContainer
60
- ref={tableContainerRef}
61
54
  {...tableContainerProps}
55
+ ref={(ref: HTMLDivElement) => {
56
+ tableContainerRef.current = ref;
57
+ if (tableContainerProps?.ref) {
58
+ //@ts-ignore
59
+ tableContainerProps.ref.current = ref;
60
+ }
61
+ }}
62
62
  sx={(theme) => ({
63
63
  maxWidth: '100%',
64
64
  maxHeight:
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
1
+ import React, { useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  TableState,
4
4
  getCoreRowModel,
@@ -9,6 +9,7 @@ import {
9
9
  getPaginationRowModel,
10
10
  getSortedRowModel,
11
11
  useReactTable,
12
+ GroupingState,
12
13
  } from '@tanstack/react-table';
13
14
  import { Box, Dialog, Grow } from '@mui/material';
14
15
  import { MRT_ExpandAllButton } from '../buttons/MRT_ExpandAllButton';
@@ -22,6 +23,7 @@ import {
22
23
  getDefaultColumnOrderIds,
23
24
  getDefaultColumnFilterFn,
24
25
  defaultDisplayColumnDefOptions,
26
+ showExpandColumn,
25
27
  } from '../column.utils';
26
28
  import type {
27
29
  MRT_Cell,
@@ -33,16 +35,17 @@ import type {
33
35
  MRT_TableState,
34
36
  MaterialReactTableProps,
35
37
  } from '..';
38
+ import { MRT_EditRowModal } from '../body/MRT_EditRowModal';
36
39
 
37
40
  export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
38
41
  props: MaterialReactTableProps<TData>,
39
42
  ) => {
40
- const [tableId, setIdPrefix] = useState(props.tableId);
41
- useEffect(
42
- () =>
43
- setIdPrefix(props.tableId ?? Math.random().toString(36).substring(2, 9)),
44
- [props.tableId],
45
- );
43
+ const bottomToolbarRef = useRef<HTMLDivElement>(null);
44
+ const editInputRefs = useRef<Record<string, HTMLInputElement>>({});
45
+ const filterInputRefs = useRef<Record<string, HTMLInputElement>>({});
46
+ const searchInputRef = useRef<HTMLInputElement>(null);
47
+ const tableContainerRef = useRef<HTMLDivElement>(null);
48
+ const topToolbarRef = useRef<HTMLDivElement>(null);
46
49
 
47
50
  const initialState: Partial<MRT_TableState<TData>> = useMemo(() => {
48
51
  const initState = props.initialState ?? {};
@@ -94,6 +97,9 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
94
97
  const [globalFilterFn, setGlobalFilterFn] = useState<MRT_FilterOption>(
95
98
  initialState.globalFilterFn ?? 'fuzzy',
96
99
  );
100
+ const [grouping, setGrouping] = useState<GroupingState>(
101
+ initialState.grouping ?? [],
102
+ );
97
103
  const [hoveredColumn, setHoveredColumn] = useState<
98
104
  MRT_Column<TData> | { id: string } | null
99
105
  >(initialState.hoveredColumn ?? null);
@@ -125,11 +131,8 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
125
131
  id: 'mrt-row-drag',
126
132
  },
127
133
  columnOrder.includes('mrt-row-actions') && {
128
- Cell: ({ cell }) => (
129
- <MRT_ToggleRowActionMenuButton
130
- row={cell.row as any}
131
- table={table}
132
- />
134
+ Cell: ({ row }) => (
135
+ <MRT_ToggleRowActionMenuButton row={row as any} table={table} />
133
136
  ),
134
137
  header: props.localization?.actions,
135
138
  size: 70,
@@ -137,23 +140,24 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
137
140
  ...props.displayColumnDefOptions?.['mrt-row-actions'],
138
141
  id: 'mrt-row-actions',
139
142
  },
140
- columnOrder.includes('mrt-row-expand') && {
141
- Cell: ({ cell }) => (
142
- <MRT_ExpandButton row={cell.row as any} table={table} />
143
- ),
144
- Header: () =>
145
- props.enableExpandAll ? (
146
- <MRT_ExpandAllButton table={table} />
147
- ) : null,
148
- header: props.localization?.expand,
149
- size: 60,
150
- ...defaultDisplayColumnDefOptions,
151
- ...props.displayColumnDefOptions?.['mrt-row-expand'],
152
- id: 'mrt-row-expand',
153
- },
143
+ columnOrder.includes('mrt-row-expand') &&
144
+ showExpandColumn(props, grouping) && {
145
+ Cell: ({ row }) => (
146
+ <MRT_ExpandButton row={row as any} table={table} />
147
+ ),
148
+ Header: () =>
149
+ props.enableExpandAll ? (
150
+ <MRT_ExpandAllButton table={table} />
151
+ ) : null,
152
+ header: props.localization?.expand,
153
+ size: 60,
154
+ ...defaultDisplayColumnDefOptions,
155
+ ...props.displayColumnDefOptions?.['mrt-row-expand'],
156
+ id: 'mrt-row-expand',
157
+ },
154
158
  columnOrder.includes('mrt-row-select') && {
155
- Cell: ({ cell }) => (
156
- <MRT_SelectCheckbox row={cell.row as any} table={table} />
159
+ Cell: ({ row }) => (
160
+ <MRT_SelectCheckbox row={row as any} table={table} />
157
161
  ),
158
162
  Header: () =>
159
163
  props.enableSelectAll ? (
@@ -166,7 +170,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
166
170
  id: 'mrt-row-select',
167
171
  },
168
172
  columnOrder.includes('mrt-row-numbers') && {
169
- Cell: ({ cell }) => cell.row.index + 1,
173
+ Cell: ({ row }) => row.index + 1,
170
174
  Header: () => props.localization?.rowNumber,
171
175
  header: props.localization?.rowNumbers,
172
176
  size: 60,
@@ -178,6 +182,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
178
182
  ).filter(Boolean),
179
183
  [
180
184
  columnOrder,
185
+ grouping,
181
186
  props.displayColumnDefOptions,
182
187
  props.editingMode,
183
188
  props.enableColumnDragging,
@@ -194,6 +199,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
194
199
  props.enableSelectAll,
195
200
  props.localization,
196
201
  props.positionActionsColumn,
202
+ props.renderDetailPanel,
197
203
  ],
198
204
  );
199
205
 
@@ -243,6 +249,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
243
249
  getPaginationRowModel: getPaginationRowModel(),
244
250
  getSortedRowModel: getSortedRowModel(),
245
251
  onColumnOrderChange: setColumnOrder,
252
+ onGroupingChange: setGrouping,
246
253
  getSubRows: (row) => row?.subRows,
247
254
  ...props,
248
255
  //@ts-ignore
@@ -260,6 +267,7 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
260
267
  editingCell,
261
268
  editingRow,
262
269
  globalFilterFn,
270
+ grouping,
263
271
  hoveredColumn,
264
272
  hoveredRow,
265
273
  isFullScreen,
@@ -268,8 +276,15 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
268
276
  showGlobalFilter,
269
277
  ...props.state,
270
278
  } as TableState,
271
- tableId,
272
279
  }),
280
+ refs: {
281
+ bottomToolbarRef,
282
+ editInputRefs,
283
+ filterInputRefs,
284
+ searchInputRef,
285
+ tableContainerRef,
286
+ topToolbarRef,
287
+ },
273
288
  setColumnFilterFns: props.onFilterFnsChange ?? setColumnFilterFns,
274
289
  setDensity: props.onDensityChange ?? setDensity,
275
290
  setDraggingColumn: props.onDraggingColumnChange ?? setDraggingColumn,
@@ -300,6 +315,9 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
300
315
  <MRT_TablePaper table={table} />
301
316
  </Dialog>
302
317
  {!isFullScreen && <MRT_TablePaper table={table} />}
318
+ {editingRow && props.editingMode === 'modal' && (
319
+ <MRT_EditRowModal row={editingRow as any} table={table} open />
320
+ )}
303
321
  </>
304
322
  );
305
323
  };
@@ -21,8 +21,8 @@ export const MRT_BottomToolbar: FC<Props> = ({ table }) => {
21
21
  positionToolbarAlertBanner,
22
22
  positionToolbarDropZone,
23
23
  renderBottomToolbarCustomActions,
24
- tableId,
25
24
  },
25
+ refs: { bottomToolbarRef },
26
26
  } = table;
27
27
  const { isFullScreen } = getState();
28
28
 
@@ -37,9 +37,15 @@ export const MRT_BottomToolbar: FC<Props> = ({ table }) => {
37
37
 
38
38
  return (
39
39
  <Toolbar
40
- id={`mrt-${tableId}-toolbar-bottom`}
41
40
  variant="dense"
42
41
  {...toolbarProps}
42
+ ref={(ref: HTMLDivElement) => {
43
+ bottomToolbarRef.current = ref;
44
+ if (toolbarProps?.ref) {
45
+ // @ts-ignore
46
+ toolbarProps.ref.current = ref;
47
+ }
48
+ }}
43
49
  sx={(theme) =>
44
50
  ({
45
51
  ...commonToolbarStyles({ theme }),
@@ -37,8 +37,8 @@ export const MRT_TopToolbar: FC<Props> = ({ table }) => {
37
37
  positionToolbarAlertBanner,
38
38
  positionToolbarDropZone,
39
39
  renderTopToolbarCustomActions,
40
- tableId,
41
40
  },
41
+ refs: { topToolbarRef },
42
42
  } = table;
43
43
 
44
44
  const { isFullScreen, showGlobalFilter } = getState();
@@ -55,9 +55,15 @@ export const MRT_TopToolbar: FC<Props> = ({ table }) => {
55
55
 
56
56
  return (
57
57
  <Toolbar
58
- id={`mrt-${tableId}-toolbar-top`}
59
58
  variant="dense"
60
59
  {...toolbarProps}
60
+ ref={(ref: HTMLDivElement) => {
61
+ topToolbarRef.current = ref;
62
+ if (toolbarProps?.ref) {
63
+ // @ts-ignore
64
+ toolbarProps.ref.current = ref;
65
+ }
66
+ }}
61
67
  sx={(theme) =>
62
68
  ({
63
69
  position: isFullScreen ? 'sticky' : undefined,