material-react-table 2.9.1 → 2.10.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 (151) hide show
  1. package/dist/index.d.ts +162 -111
  2. package/dist/index.esm.js +739 -639
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +741 -639
  5. package/dist/index.js.map +1 -1
  6. package/locales/ar/index.esm.js +1 -0
  7. package/locales/ar/index.js +1 -0
  8. package/locales/az/index.esm.js +1 -0
  9. package/locales/az/index.js +1 -0
  10. package/locales/bg/index.esm.js +1 -0
  11. package/locales/bg/index.js +1 -0
  12. package/locales/cs/index.esm.js +1 -0
  13. package/locales/cs/index.js +1 -0
  14. package/locales/da/index.esm.js +1 -0
  15. package/locales/da/index.js +1 -0
  16. package/locales/de/index.esm.js +1 -0
  17. package/locales/de/index.js +1 -0
  18. package/locales/en/index.esm.js +1 -0
  19. package/locales/en/index.js +1 -0
  20. package/locales/es/index.esm.js +1 -0
  21. package/locales/es/index.js +1 -0
  22. package/locales/et/index.esm.js +1 -0
  23. package/locales/et/index.js +1 -0
  24. package/locales/fa/index.esm.js +1 -0
  25. package/locales/fa/index.js +1 -0
  26. package/locales/fi/index.esm.js +1 -0
  27. package/locales/fi/index.js +1 -0
  28. package/locales/fr/index.esm.js +1 -0
  29. package/locales/fr/index.js +1 -0
  30. package/locales/he/index.esm.js +1 -0
  31. package/locales/he/index.js +1 -0
  32. package/locales/hu/index.esm.js +1 -0
  33. package/locales/hu/index.js +1 -0
  34. package/locales/hy/index.esm.js +1 -0
  35. package/locales/hy/index.js +1 -0
  36. package/locales/id/index.esm.js +1 -0
  37. package/locales/id/index.js +1 -0
  38. package/locales/it/index.esm.js +1 -0
  39. package/locales/it/index.js +1 -0
  40. package/locales/ja/index.esm.js +1 -0
  41. package/locales/ja/index.js +1 -0
  42. package/locales/ko/index.esm.js +1 -0
  43. package/locales/ko/index.js +1 -0
  44. package/locales/nl/index.esm.js +1 -0
  45. package/locales/nl/index.js +1 -0
  46. package/locales/no/index.esm.js +1 -0
  47. package/locales/no/index.js +1 -0
  48. package/locales/np/index.esm.js +1 -0
  49. package/locales/np/index.js +1 -0
  50. package/locales/pl/index.esm.js +1 -0
  51. package/locales/pl/index.js +1 -0
  52. package/locales/pt/index.esm.js +1 -0
  53. package/locales/pt/index.js +1 -0
  54. package/locales/pt-BR/index.esm.js +1 -0
  55. package/locales/pt-BR/index.js +1 -0
  56. package/locales/ro/index.esm.js +1 -0
  57. package/locales/ro/index.js +1 -0
  58. package/locales/ru/index.esm.js +1 -0
  59. package/locales/ru/index.js +1 -0
  60. package/locales/sk/index.esm.js +1 -0
  61. package/locales/sk/index.js +1 -0
  62. package/locales/sr-Cyrl-RS/index.esm.js +1 -0
  63. package/locales/sr-Cyrl-RS/index.js +1 -0
  64. package/locales/sr-Latn-RS/index.esm.js +1 -0
  65. package/locales/sr-Latn-RS/index.js +1 -0
  66. package/locales/sv/index.esm.js +1 -0
  67. package/locales/sv/index.js +1 -0
  68. package/locales/tr/index.esm.js +1 -0
  69. package/locales/tr/index.js +1 -0
  70. package/locales/uk/index.esm.js +1 -0
  71. package/locales/uk/index.js +1 -0
  72. package/locales/vi/index.esm.js +1 -0
  73. package/locales/vi/index.js +1 -0
  74. package/locales/zh-Hans/index.esm.js +1 -0
  75. package/locales/zh-Hans/index.js +1 -0
  76. package/locales/zh-Hant/index.esm.js +1 -0
  77. package/locales/zh-Hant/index.js +1 -0
  78. package/package.json +11 -11
  79. package/src/components/body/MRT_TableBodyCell.tsx +41 -37
  80. package/src/components/body/MRT_TableBodyRow.tsx +15 -21
  81. package/src/components/buttons/MRT_CopyButton.tsx +1 -0
  82. package/src/components/footer/MRT_TableFooter.tsx +1 -1
  83. package/src/components/footer/MRT_TableFooterCell.tsx +2 -4
  84. package/src/components/footer/MRT_TableFooterRow.tsx +1 -0
  85. package/src/components/head/MRT_TableHeadCell.tsx +6 -6
  86. package/src/components/head/MRT_TableHeadCellFilterLabel.tsx +1 -0
  87. package/src/components/head/MRT_TableHeadRow.tsx +6 -1
  88. package/src/components/inputs/MRT_EditCellTextField.tsx +4 -1
  89. package/src/components/inputs/MRT_FilterTextField.tsx +1 -0
  90. package/src/components/menus/MRT_ActionMenuItem.tsx +60 -0
  91. package/src/components/menus/MRT_CellActionMenu.tsx +108 -0
  92. package/src/components/menus/MRT_ColumnActionMenu.tsx +90 -170
  93. package/src/components/menus/MRT_FilterOptionMenu.tsx +7 -14
  94. package/src/components/menus/MRT_RowActionMenu.tsx +8 -15
  95. package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +4 -1
  96. package/src/components/table/MRT_Table.tsx +1 -0
  97. package/src/components/table/MRT_TableContainer.tsx +4 -0
  98. package/src/components/toolbar/MRT_TablePagination.tsx +14 -5
  99. package/src/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +1 -8
  100. package/src/hooks/display-columns/getMRT_RowDragColumnDef.tsx +1 -8
  101. package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +1 -8
  102. package/src/hooks/display-columns/getMRT_RowNumbersColumnDef.tsx +1 -8
  103. package/src/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +1 -8
  104. package/src/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +1 -8
  105. package/src/hooks/display-columns/getMRT_RowSpacerColumnDef.tsx +1 -8
  106. package/src/hooks/useMRT_Effects.ts +10 -0
  107. package/src/hooks/useMRT_TableInstance.ts +112 -59
  108. package/src/icons.ts +2 -0
  109. package/src/index.ts +2 -0
  110. package/src/locales/ar.ts +1 -0
  111. package/src/locales/az.ts +1 -0
  112. package/src/locales/bg.ts +1 -0
  113. package/src/locales/cs.ts +1 -0
  114. package/src/locales/da.ts +1 -0
  115. package/src/locales/de.ts +1 -0
  116. package/src/locales/en.ts +1 -0
  117. package/src/locales/es.ts +1 -0
  118. package/src/locales/et.ts +1 -0
  119. package/src/locales/fa.ts +1 -0
  120. package/src/locales/fi.ts +1 -0
  121. package/src/locales/fr.ts +1 -0
  122. package/src/locales/he.ts +1 -0
  123. package/src/locales/hu.ts +1 -0
  124. package/src/locales/hy.ts +1 -0
  125. package/src/locales/id.ts +1 -0
  126. package/src/locales/it.ts +1 -0
  127. package/src/locales/ja.ts +1 -0
  128. package/src/locales/ko.ts +1 -0
  129. package/src/locales/nl.ts +1 -0
  130. package/src/locales/no.ts +1 -0
  131. package/src/locales/np.ts +1 -0
  132. package/src/locales/pl.ts +1 -0
  133. package/src/locales/pt-BR.ts +1 -0
  134. package/src/locales/pt.ts +1 -0
  135. package/src/locales/ro.ts +1 -0
  136. package/src/locales/ru.ts +1 -0
  137. package/src/locales/sk.ts +1 -0
  138. package/src/locales/sr-Cyrl-RS.ts +1 -0
  139. package/src/locales/sr-Latn-RS.ts +1 -0
  140. package/src/locales/sv.ts +1 -0
  141. package/src/locales/tr.ts +1 -0
  142. package/src/locales/uk.ts +1 -0
  143. package/src/locales/vi.ts +1 -0
  144. package/src/locales/zh-Hans.ts +1 -0
  145. package/src/locales/zh-Hant.ts +1 -0
  146. package/src/types.ts +41 -9
  147. package/src/utils/cell.utils.ts +50 -0
  148. package/src/utils/displayColumn.utils.ts +38 -20
  149. package/src/utils/style.utils.ts +17 -4
  150. package/src/hooks/display-columns/getMRT_DisplayColumns.tsx +0 -26
  151. package/src/locales/am.ts +0 -94
@@ -8,6 +8,7 @@ const MRT_Localization_ZH_HANS = {
8
8
  clearSearch: '清除搜索',
9
9
  clearSort: '清除排序',
10
10
  clickToCopy: '点击以复制',
11
+ copy: '复制',
11
12
  collapse: '折叠',
12
13
  collapseAll: '全部折叠',
13
14
  columnActions: '列操作',
@@ -12,6 +12,7 @@ const MRT_Localization_ZH_HANS = {
12
12
  clearSearch: '清除搜索',
13
13
  clearSort: '清除排序',
14
14
  clickToCopy: '点击以复制',
15
+ copy: '复制',
15
16
  collapse: '折叠',
16
17
  collapseAll: '全部折叠',
17
18
  columnActions: '列操作',
@@ -8,6 +8,7 @@ const MRT_Localization_ZH_HANT = {
8
8
  clearSearch: '清除搜尋',
9
9
  clearSort: '清除排序',
10
10
  clickToCopy: '點擊以複製',
11
+ copy: '複製',
11
12
  collapse: '折疊',
12
13
  collapseAll: '全部折疊',
13
14
  columnActions: '欄位動作',
@@ -12,6 +12,7 @@ const MRT_Localization_ZH_HANT = {
12
12
  clearSearch: '清除搜尋',
13
13
  clearSort: '清除排序',
14
14
  clickToCopy: '點擊以複製',
15
+ copy: '複製',
15
16
  collapse: '折疊',
16
17
  collapseAll: '全部折疊',
17
18
  columnActions: '欄位動作',
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.9.1",
2
+ "version": "2.10.0",
3
3
  "license": "MIT",
4
4
  "name": "material-react-table",
5
5
  "description": "A fully featured Material UI V5 implementation of TanStack React Table V8, written from the ground up in TypeScript.",
@@ -61,14 +61,14 @@
61
61
  "storybook:dev": "storybook dev -p 6006"
62
62
  },
63
63
  "devDependencies": {
64
- "@babel/core": "^7.23.7",
64
+ "@babel/core": "^7.23.9",
65
65
  "@babel/preset-react": "^7.23.3",
66
66
  "@emotion/react": "^11.11.3",
67
67
  "@emotion/styled": "^11.11.0",
68
- "@faker-js/faker": "^8.3.1",
69
- "@mui/icons-material": "^5.15.5",
70
- "@mui/material": "^5.15.5",
71
- "@mui/x-date-pickers": "^6.19.0",
68
+ "@faker-js/faker": "^8.4.0",
69
+ "@mui/icons-material": "^5.15.6",
70
+ "@mui/material": "^5.15.6",
71
+ "@mui/x-date-pickers": "^6.19.2",
72
72
  "@rollup/plugin-typescript": "^11.1.6",
73
73
  "@size-limit/preset-small-lib": "^11.0.2",
74
74
  "@storybook/addon-a11y": "^7.6.10",
@@ -80,11 +80,11 @@
80
80
  "@storybook/react": "^7.6.10",
81
81
  "@storybook/react-vite": "^7.6.10",
82
82
  "@storybook/testing-library": "^0.2.2",
83
- "@types/node": "^20.11.5",
83
+ "@types/node": "^20.11.10",
84
84
  "@types/react": "^18.2.48",
85
85
  "@types/react-dom": "^18.2.18",
86
- "@typescript-eslint/eslint-plugin": "^6.19.0",
87
- "@typescript-eslint/parser": "^6.19.0",
86
+ "@typescript-eslint/eslint-plugin": "^6.20.0",
87
+ "@typescript-eslint/parser": "^6.20.0",
88
88
  "@vitejs/plugin-react": "^4.2.1",
89
89
  "eslint": "^8.56.0",
90
90
  "eslint-plugin-mui-path-imports": "^0.0.15",
@@ -115,8 +115,8 @@
115
115
  "react-dom": ">=18.0"
116
116
  },
117
117
  "dependencies": {
118
- "@tanstack/match-sorter-utils": "8.11.3",
119
- "@tanstack/react-table": "8.11.6",
118
+ "@tanstack/match-sorter-utils": "8.11.7",
119
+ "@tanstack/react-table": "8.11.7",
120
120
  "@tanstack/react-virtual": "3.0.2",
121
121
  "highlight-words": "1.2.2"
122
122
  }
@@ -16,6 +16,7 @@ import {
16
16
  type MRT_RowData,
17
17
  type MRT_TableInstance,
18
18
  } from '../../types';
19
+ import { isCellEditable, openEditingCell } from '../../utils/cell.utils';
19
20
  import { getIsFirstColumn, getIsLastColumn } from '../../utils/column.utils';
20
21
  import { getCommonMRTCellStyles, getMRTTheme } from '../../utils/style.utils';
21
22
  import { parseFromValuesOrFunc } from '../../utils/utils';
@@ -24,7 +25,6 @@ import { MRT_EditCellTextField } from '../inputs/MRT_EditCellTextField';
24
25
 
25
26
  interface Props<TData extends MRT_RowData> extends TableCellProps {
26
27
  cell: MRT_Cell<TData>;
27
- measureElement?: (element: HTMLTableCellElement) => void;
28
28
  numRows?: number;
29
29
  rowRef: RefObject<HTMLTableRowElement>;
30
30
  staticColumnIndex?: number;
@@ -34,7 +34,6 @@ interface Props<TData extends MRT_RowData> extends TableCellProps {
34
34
 
35
35
  export const MRT_TableBodyCell = <TData extends MRT_RowData>({
36
36
  cell,
37
- measureElement,
38
37
  numRows,
39
38
  rowRef,
40
39
  staticColumnIndex,
@@ -50,20 +49,19 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
50
49
  columnResizeMode,
51
50
  createDisplayMode,
52
51
  editDisplayMode,
52
+ enableCellActions,
53
53
  enableClickToCopy,
54
54
  enableColumnOrdering,
55
55
  enableColumnPinning,
56
- enableEditing,
57
56
  enableGrouping,
58
57
  layoutMode,
59
58
  muiSkeletonProps,
60
59
  muiTableBodyCellProps,
61
60
  },
62
- refs: { editInputRefs },
63
- setEditingCell,
64
61
  setHoveredColumn,
65
62
  } = table;
66
63
  const {
64
+ actionCell,
67
65
  columnSizingInfo,
68
66
  creatingRow,
69
67
  density,
@@ -168,10 +166,7 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
168
166
  columnDef.columnDefType !== 'group' &&
169
167
  column.getIsPinned();
170
168
 
171
- const isEditable =
172
- !cell.getIsPlaceholder() &&
173
- parseFromValuesOrFunc(enableEditing, row) &&
174
- parseFromValuesOrFunc(columnDef.enableEditing, row) !== false;
169
+ const isEditable = isCellEditable({ cell, table });
175
170
 
176
171
  const isEditing =
177
172
  isEditable &&
@@ -184,18 +179,24 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
184
179
  const isCreating =
185
180
  isEditable && createDisplayMode === 'row' && creatingRow?.id === row.id;
186
181
 
182
+ const showClickToCopyButton =
183
+ (parseFromValuesOrFunc(enableClickToCopy, cell) === true ||
184
+ parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === true) &&
185
+ !['context-menu', false].includes(
186
+ // @ts-ignore
187
+ parseFromValuesOrFunc(columnDef.enableClickToCopy, cell),
188
+ );
189
+
190
+ const isRightClickable = parseFromValuesOrFunc(enableCellActions, cell);
191
+
192
+ const cellValueProps = {
193
+ cell,
194
+ table,
195
+ };
196
+
187
197
  const handleDoubleClick = (event: MouseEvent<HTMLTableCellElement>) => {
188
198
  tableCellProps?.onDoubleClick?.(event);
189
- if (isEditable && editDisplayMode === 'cell') {
190
- setEditingCell(cell);
191
- queueMicrotask(() => {
192
- const textField = editInputRefs.current[column.id];
193
- if (textField) {
194
- textField.focus();
195
- textField.select?.();
196
- }
197
- });
198
- }
199
+ openEditingCell({ cell, table });
199
200
  };
200
201
 
201
202
  const handleDragEnter = (e: DragEvent<HTMLTableCellElement>) => {
@@ -210,9 +211,13 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
210
211
  }
211
212
  };
212
213
 
213
- const cellValueProps = {
214
- cell,
215
- table,
214
+ const handleContextMenu = (e: MouseEvent<HTMLTableCellElement>) => {
215
+ tableCellProps?.onContextMenu?.(e);
216
+ if (isRightClickable) {
217
+ e.preventDefault();
218
+ table.setActionCell(cell);
219
+ table.refs.actionCellRef.current = e.currentTarget;
220
+ }
216
221
  };
217
222
 
218
223
  return (
@@ -220,30 +225,31 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
220
225
  align={theme.direction === 'rtl' ? 'right' : 'left'}
221
226
  data-index={staticColumnIndex}
222
227
  data-pinned={!!isColumnPinned || undefined}
223
- ref={(node: HTMLTableCellElement) => {
224
- if (node) {
225
- measureElement?.(node);
226
- }
227
- }}
228
228
  {...tableCellProps}
229
+ onContextMenu={handleContextMenu}
229
230
  onDoubleClick={handleDoubleClick}
230
231
  onDragEnter={handleDragEnter}
231
232
  sx={(theme) => ({
232
233
  '&:hover': {
233
234
  outline:
235
+ actionCell?.id === cell.id ||
234
236
  (editDisplayMode === 'cell' && isEditable) ||
235
237
  (editDisplayMode === 'table' && (isCreating || isEditing))
236
238
  ? `1px solid ${theme.palette.grey[500]}`
237
239
  : undefined,
238
- outlineOffset: '-1px',
239
240
  textOverflow: 'clip',
240
241
  },
241
242
  alignItems: layoutMode?.startsWith('grid') ? 'center' : undefined,
242
- cursor:
243
- isEditable && editDisplayMode === 'cell' ? 'pointer' : 'inherit',
244
- justifyContent: layoutMode?.startsWith('grid')
245
- ? tableCellProps.align
246
- : undefined,
243
+ cursor: isRightClickable
244
+ ? 'context-menu'
245
+ : isEditable && editDisplayMode === 'cell'
246
+ ? 'pointer'
247
+ : 'inherit',
248
+ outline:
249
+ actionCell?.id === cell.id
250
+ ? `1px solid ${theme.palette.grey[500]}`
251
+ : undefined,
252
+ outlineOffset: '-1px',
247
253
  overflow: 'hidden',
248
254
  p:
249
255
  density === 'compact'
@@ -257,11 +263,10 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
257
263
  : columnDefType === 'display'
258
264
  ? '1rem 1.25rem'
259
265
  : '1.5rem',
266
+
260
267
  textOverflow: columnDefType !== 'display' ? 'ellipsis' : undefined,
261
268
  whiteSpace:
262
269
  row.getIsPinned() || density === 'compact' ? 'nowrap' : 'normal',
263
- zIndex:
264
- draggingColumn?.id === column.id ? 2 : column.getIsPinned() ? 1 : 0,
265
270
  ...getCommonMRTCellStyles({
266
271
  column,
267
272
  table,
@@ -298,8 +303,7 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
298
303
  })
299
304
  ) : isCreating || isEditing ? (
300
305
  <MRT_EditCellTextField cell={cell} table={table} />
301
- ) : (enableClickToCopy || columnDef.enableClickToCopy) &&
302
- columnDef.enableClickToCopy !== false ? (
306
+ ) : showClickToCopyButton && columnDef.enableClickToCopy !== false ? (
303
307
  <MRT_CopyButton cell={cell} table={table}>
304
308
  <MRT_TableBodyCellValue {...cellValueProps} />
305
309
  </MRT_CopyButton>
@@ -21,9 +21,9 @@ import {
21
21
  } from '../../types';
22
22
  import { getIsRowSelected } from '../../utils/row.utils';
23
23
  import {
24
+ commonCellBeforeAfterStyles,
24
25
  getCommonPinnedCellStyles,
25
26
  getMRTTheme,
26
- pinnedBeforeAfterStyles,
27
27
  } from '../../utils/style.utils';
28
28
  import { parseFromValuesOrFunc } from '../../utils/utils';
29
29
 
@@ -176,14 +176,12 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
176
176
  ...tableRowProps?.style,
177
177
  }}
178
178
  sx={(theme: Theme) => ({
179
- '&:hover td': {
180
- '&:after': {
181
- backgroundColor: cellHighlightColorHover
182
- ? alpha(cellHighlightColorHover, 0.3)
183
- : undefined,
184
- ...pinnedBeforeAfterStyles,
185
- },
186
- },
179
+ '&:hover td:after': cellHighlightColorHover
180
+ ? {
181
+ backgroundColor: alpha(cellHighlightColorHover, 0.3),
182
+ ...commonCellBeforeAfterStyles,
183
+ }
184
+ : undefined,
187
185
  backgroundColor: `${baseBackgroundColor} !important`,
188
186
  bottom:
189
187
  !virtualRow && bottomPinnedIndex !== undefined && isRowPinned
@@ -199,14 +197,16 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
199
197
  ? 'absolute'
200
198
  : rowPinningDisplayMode?.includes('sticky') && isRowPinned
201
199
  ? 'sticky'
202
- : undefined,
200
+ : 'relative',
203
201
  td: {
204
- '&:after': {
205
- backgroundColor: cellHighlightColor,
206
- ...pinnedBeforeAfterStyles,
207
- },
208
202
  ...getCommonPinnedCellStyles({ table, theme }),
209
203
  },
204
+ 'td:after': cellHighlightColor
205
+ ? {
206
+ backgroundColor: cellHighlightColor,
207
+ ...commonCellBeforeAfterStyles,
208
+ }
209
+ : undefined,
210
210
  top: virtualRow
211
211
  ? 0
212
212
  : topPinnedIndex !== undefined && isRowPinned
@@ -218,9 +218,7 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
218
218
  transition: virtualRow ? 'none' : 'all 150ms ease-in-out',
219
219
  width: '100%',
220
220
  zIndex:
221
- rowPinningDisplayMode?.includes('sticky') && isRowPinned
222
- ? 2
223
- : undefined,
221
+ rowPinningDisplayMode?.includes('sticky') && isRowPinned ? 2 : 0,
224
222
  ...(sx as any),
225
223
  })}
226
224
  >
@@ -236,10 +234,6 @@ export const MRT_TableBodyRow = <TData extends MRT_RowData>({
236
234
  }
237
235
  const props = {
238
236
  cell,
239
- measureElement:
240
- !isDraggingRow && !isHoveredRow
241
- ? columnVirtualizer?.measureElement
242
- : undefined,
243
237
  numRows,
244
238
  rowRef,
245
239
  staticColumnIndex,
@@ -74,6 +74,7 @@ export const MRT_CopyButton = <TData extends MRT_RowData>({
74
74
  letterSpacing: 'inherit',
75
75
  m: '-0.25rem',
76
76
  minWidth: 'unset',
77
+ py: 0,
77
78
  textAlign: 'inherit',
78
79
  textTransform: 'inherit',
79
80
  ...(parseFromValuesOrFunc(buttonProps?.sx, theme) as any),
@@ -54,7 +54,7 @@ export const MRT_TableFooter = <TData extends MRT_RowData>({
54
54
  ? `1px solid ${theme.palette.grey[300]}`
55
55
  : `1px solid ${theme.palette.grey[700]}`
56
56
  : undefined,
57
- position: stickFooter ? 'sticky' : undefined,
57
+ position: stickFooter ? 'sticky' : 'relative',
58
58
  zIndex: stickFooter ? 1 : undefined,
59
59
  ...(parseFromValuesOrFunc(tableFooterProps?.sx, theme) as any),
60
60
  })}
@@ -23,7 +23,7 @@ export const MRT_TableFooterCell = <TData extends MRT_RowData>({
23
23
  const theme = useTheme();
24
24
  const {
25
25
  getState,
26
- options: { enableColumnPinning, layoutMode, muiTableFooterCellProps },
26
+ options: { enableColumnPinning, muiTableFooterCellProps },
27
27
  } = table;
28
28
  const { density } = getState();
29
29
  const { column } = footer;
@@ -57,9 +57,7 @@ export const MRT_TableFooterCell = <TData extends MRT_RowData>({
57
57
  variant="footer"
58
58
  {...tableCellProps}
59
59
  sx={(theme) => ({
60
- display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
61
60
  fontWeight: 'bold',
62
- justifyContent: columnDefType === 'group' ? 'center' : undefined,
63
61
  p:
64
62
  density === 'compact'
65
63
  ? '0.5rem'
@@ -67,9 +65,9 @@ export const MRT_TableFooterCell = <TData extends MRT_RowData>({
67
65
  ? '1rem'
68
66
  : '1.5rem',
69
67
  verticalAlign: 'top',
70
- zIndex: column.getIsPinned() && columnDefType !== 'group' ? 2 : 1,
71
68
  ...getCommonMRTCellStyles({
72
69
  column,
70
+ header: footer,
73
71
  table,
74
72
  tableCellProps,
75
73
  theme,
@@ -55,6 +55,7 @@ export const MRT_TableFooterRow = <TData extends MRT_RowData>({
55
55
  sx={(theme) => ({
56
56
  backgroundColor: getMRTTheme(table, theme).baseBackgroundColor,
57
57
  display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
58
+ position: 'relative',
58
59
  width: '100%',
59
60
  ...(parseFromValuesOrFunc(tableRowProps?.sx, theme) as any),
60
61
  })}
@@ -10,6 +10,7 @@ import { MRT_TableHeadCellGrabHandle } from './MRT_TableHeadCellGrabHandle';
10
10
  import { MRT_TableHeadCellResizeHandle } from './MRT_TableHeadCellResizeHandle';
11
11
  import { MRT_TableHeadCellSortLabel } from './MRT_TableHeadCellSortLabel';
12
12
  import {
13
+ type MRT_ColumnVirtualizer,
13
14
  type MRT_Header,
14
15
  type MRT_RowData,
15
16
  type MRT_TableInstance,
@@ -18,12 +19,14 @@ import { getCommonMRTCellStyles, getMRTTheme } from '../../utils/style.utils';
18
19
  import { parseFromValuesOrFunc } from '../../utils/utils';
19
20
 
20
21
  interface Props<TData extends MRT_RowData> extends TableCellProps {
22
+ columnVirtualizer?: MRT_ColumnVirtualizer;
21
23
  header: MRT_Header<TData>;
22
24
  staticColumnIndex?: number;
23
25
  table: MRT_TableInstance<TData>;
24
26
  }
25
27
 
26
28
  export const MRT_TableHeadCell = <TData extends MRT_RowData>({
29
+ columnVirtualizer,
27
30
  header,
28
31
  staticColumnIndex,
29
32
  table,
@@ -161,6 +164,9 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
161
164
  ref={(node: HTMLTableCellElement) => {
162
165
  if (node) {
163
166
  tableHeadCellRefs.current[column.id] = node;
167
+ if (columnDefType !== 'group') {
168
+ columnVirtualizer?.measureElement?.(node);
169
+ }
164
170
  }
165
171
  }}
166
172
  {...tableCellProps}
@@ -197,12 +203,6 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
197
203
  : '1.25rem',
198
204
  userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined,
199
205
  verticalAlign: 'top',
200
- zIndex:
201
- column.getIsResizing() || draggingColumn?.id === column.id
202
- ? 3
203
- : column.getIsPinned() && columnDefType !== 'group'
204
- ? 2
205
- : 1,
206
206
  ...getCommonMRTCellStyles({
207
207
  column,
208
208
  header,
@@ -131,6 +131,7 @@ export const MRT_TableHeadCellFilterLabel = <TData extends MRT_RowData = {}>({
131
131
  horizontal: 'center',
132
132
  vertical: 'top',
133
133
  }}
134
+ disableScrollLock
134
135
  onClick={(event) => event.stopPropagation()}
135
136
  onClose={(event) => {
136
137
  //@ts-ignore
@@ -25,7 +25,7 @@ export const MRT_TableHeadRow = <TData extends MRT_RowData>({
25
25
  ...rest
26
26
  }: Props<TData>) => {
27
27
  const {
28
- options: { layoutMode, muiTableHeadRowProps },
28
+ options: { enableStickyHeader, layoutMode, muiTableHeadRowProps },
29
29
  } = table;
30
30
 
31
31
  const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } =
@@ -46,6 +46,10 @@ export const MRT_TableHeadRow = <TData extends MRT_RowData>({
46
46
  backgroundColor: getMRTTheme(table, theme).baseBackgroundColor,
47
47
  boxShadow: `4px 0 8px ${alpha(theme.palette.common.black, 0.1)}`,
48
48
  display: layoutMode?.startsWith('grid') ? 'flex' : undefined,
49
+ position:
50
+ enableStickyHeader && layoutMode === 'semantic'
51
+ ? 'sticky'
52
+ : 'relative',
49
53
  top: 0,
50
54
  ...(parseFromValuesOrFunc(tableRowProps?.sx, theme) as any),
51
55
  })}
@@ -64,6 +68,7 @@ export const MRT_TableHeadRow = <TData extends MRT_RowData>({
64
68
 
65
69
  return header ? (
66
70
  <MRT_TableHeadCell
71
+ columnVirtualizer={columnVirtualizer}
67
72
  header={header}
68
73
  key={header.id}
69
74
  staticColumnIndex={staticColumnIndex}
@@ -148,8 +148,11 @@ export const MRT_EditCellTextField = <TData extends MRT_RowData>({
148
148
  ) as any),
149
149
  }),
150
150
  }}
151
+ SelectProps={{
152
+ MenuProps: { disableScrollLock: true },
153
+ }}
151
154
  inputProps={{
152
- autoComplete: 'new-password', // disable autocomplete and autofill
155
+ autoComplete: 'new-password', //disable autocomplete and autofill
153
156
  ...textFieldProps.inputProps,
154
157
  }}
155
158
  onBlur={handleBlur}
@@ -468,6 +468,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
468
468
  select={isSelectFilter || isMultiSelectFilter}
469
469
  {...commonTextFieldProps}
470
470
  SelectProps={{
471
+ MenuProps: { disableScrollLock: true },
471
472
  displayEmpty: true,
472
473
  multiple: isMultiSelectFilter,
473
474
  renderValue: isMultiSelectFilter
@@ -0,0 +1,60 @@
1
+ import { type ReactNode } from 'react';
2
+ import Box from '@mui/material/Box';
3
+ import IconButton from '@mui/material/IconButton';
4
+ import ListItemIcon from '@mui/material/ListItemIcon';
5
+ import MenuItem, { type MenuItemProps } from '@mui/material/MenuItem';
6
+ import { type MRT_RowData, type MRT_TableInstance } from '../../types';
7
+
8
+ interface Props<TData extends MRT_RowData> extends MenuItemProps {
9
+ icon: ReactNode;
10
+ label: string;
11
+ onOpenSubMenu?: MenuItemProps['onClick'] | MenuItemProps['onMouseEnter'];
12
+ table: MRT_TableInstance<TData>;
13
+ }
14
+
15
+ export const MRT_ActionMenuItem = <TData extends MRT_RowData>({
16
+ icon,
17
+ label,
18
+ onOpenSubMenu,
19
+ table,
20
+ ...rest
21
+ }: Props<TData>) => {
22
+ const {
23
+ options: {
24
+ icons: { ArrowRightIcon },
25
+ },
26
+ } = table;
27
+
28
+ return (
29
+ <MenuItem
30
+ sx={{
31
+ alignItems: 'center',
32
+ justifyContent: 'space-between',
33
+ minWidth: '120px',
34
+ my: 0,
35
+ py: '6px',
36
+ }}
37
+ {...rest}
38
+ >
39
+ <Box
40
+ sx={{
41
+ alignItems: 'center',
42
+ display: 'flex',
43
+ }}
44
+ >
45
+ <ListItemIcon>{icon}</ListItemIcon>
46
+ {label}
47
+ </Box>
48
+ {onOpenSubMenu && (
49
+ <IconButton
50
+ onClick={onOpenSubMenu as any}
51
+ onMouseEnter={onOpenSubMenu as any}
52
+ size="small"
53
+ sx={{ p: 0 }}
54
+ >
55
+ <ArrowRightIcon />
56
+ </IconButton>
57
+ )}
58
+ </MenuItem>
59
+ );
60
+ };
@@ -0,0 +1,108 @@
1
+ import Menu, { type MenuProps } from '@mui/material/Menu';
2
+ import { useTheme } from '@mui/material/styles';
3
+ import { MRT_ActionMenuItem } from './MRT_ActionMenuItem';
4
+ import { type MRT_RowData, type MRT_TableInstance } from '../../types';
5
+ import { openEditingCell } from '../../utils/cell.utils';
6
+ import { getMRTTheme } from '../../utils/style.utils';
7
+ import { parseFromValuesOrFunc } from '../../utils/utils';
8
+
9
+ interface Props<TData extends MRT_RowData> extends Partial<MenuProps> {
10
+ table: MRT_TableInstance<TData>;
11
+ }
12
+
13
+ export const MRT_CellActionMenu = <TData extends MRT_RowData>({
14
+ table,
15
+ ...rest
16
+ }: Props<TData>) => {
17
+ const {
18
+ getState,
19
+ options: {
20
+ editDisplayMode,
21
+ enableClickToCopy,
22
+ enableEditing,
23
+ icons: { ContentCopy, EditIcon },
24
+ localization,
25
+ renderCellActionMenuItems,
26
+ },
27
+ refs: { actionCellRef },
28
+ } = table;
29
+ const { actionCell, density } = getState();
30
+ const cell = actionCell!;
31
+ const { row } = cell;
32
+ const { column } = cell;
33
+ const { columnDef } = column;
34
+
35
+ const theme = useTheme();
36
+ const { menuBackgroundColor } = getMRTTheme(table, theme);
37
+
38
+ const handleClose = (event?: any) => {
39
+ event?.stopPropagation();
40
+ table.setActionCell(null);
41
+ actionCellRef.current = null;
42
+ };
43
+
44
+ const internalMenuItems = [
45
+ (parseFromValuesOrFunc(enableClickToCopy, cell) === 'context-menu' ||
46
+ parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) ===
47
+ 'context-menu') && (
48
+ <MRT_ActionMenuItem
49
+ key={'mrt-copy'}
50
+ icon={<ContentCopy />}
51
+ label={localization.copy}
52
+ onClick={(event) => {
53
+ event.stopPropagation();
54
+ navigator.clipboard.writeText(cell.getValue() as string);
55
+ handleClose();
56
+ }}
57
+ table={table}
58
+ />
59
+ ),
60
+ parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === 'cell' && (
61
+ <MRT_ActionMenuItem
62
+ key={'mrt-edit'}
63
+ icon={<EditIcon />}
64
+ label={localization.edit}
65
+ onClick={() => {
66
+ openEditingCell({ cell, table });
67
+ handleClose();
68
+ }}
69
+ table={table}
70
+ />
71
+ ),
72
+ ].filter(Boolean);
73
+
74
+ const renderActionProps = {
75
+ cell,
76
+ closeMenu: handleClose,
77
+ column,
78
+ internalMenuItems,
79
+ row,
80
+ table,
81
+ };
82
+
83
+ const menuItems =
84
+ columnDef.renderCellActionMenuItems?.(renderActionProps) ??
85
+ renderCellActionMenuItems?.(renderActionProps);
86
+
87
+ return (
88
+ (!!menuItems?.length || !!internalMenuItems?.length) && (
89
+ <Menu
90
+ MenuListProps={{
91
+ dense: density === 'compact',
92
+ sx: {
93
+ backgroundColor: menuBackgroundColor,
94
+ },
95
+ }}
96
+ anchorEl={actionCellRef.current}
97
+ disableScrollLock
98
+ onClick={(event) => event.stopPropagation()}
99
+ onClose={handleClose}
100
+ open={!!cell}
101
+ transformOrigin={{ horizontal: -100, vertical: 8 }}
102
+ {...rest}
103
+ >
104
+ {menuItems ?? internalMenuItems}
105
+ </Menu>
106
+ )
107
+ );
108
+ };