@mui/x-data-grid 5.16.0 → 5.17.2

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 (141) hide show
  1. package/CHANGELOG.md +138 -1
  2. package/components/GridRow.d.ts +2 -1
  3. package/components/GridRow.js +132 -83
  4. package/components/cell/GridBooleanCell.js +2 -1
  5. package/components/cell/GridCell.js +9 -1
  6. package/components/cell/GridEditBooleanCell.js +2 -1
  7. package/components/cell/GridEditDateCell.js +2 -1
  8. package/components/cell/GridEditInputCell.js +2 -1
  9. package/components/cell/GridEditSingleSelectCell.js +2 -1
  10. package/components/cell/GridSkeletonCell.d.ts +12 -0
  11. package/components/cell/GridSkeletonCell.js +60 -0
  12. package/components/cell/index.d.ts +1 -0
  13. package/components/cell/index.js +2 -1
  14. package/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  15. package/components/containers/GridRootStyles.js +2 -0
  16. package/components/panel/GridColumnsPanel.d.ts +6 -1
  17. package/components/panel/GridColumnsPanel.js +38 -6
  18. package/constants/defaultGridSlotsComponents.js +2 -1
  19. package/constants/gridClasses.d.ts +8 -0
  20. package/constants/gridClasses.js +1 -1
  21. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -1
  22. package/hooks/features/editRows/useGridCellEditing.new.js +8 -2
  23. package/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  24. package/hooks/features/filter/gridFilterUtils.d.ts +1 -1
  25. package/hooks/features/filter/gridFilterUtils.js +55 -54
  26. package/hooks/features/filter/useGridFilter.js +1 -1
  27. package/hooks/features/focus/useGridFocus.js +13 -3
  28. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  29. package/hooks/features/rows/useGridParamsApi.js +1 -1
  30. package/hooks/features/rows/useGridRows.js +65 -8
  31. package/hooks/features/rows/useGridRowsMeta.js +36 -16
  32. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
  33. package/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  34. package/index.js +1 -1
  35. package/internals/index.d.ts +1 -1
  36. package/internals/index.js +1 -1
  37. package/legacy/components/GridRow.js +135 -83
  38. package/legacy/components/cell/GridBooleanCell.js +2 -1
  39. package/legacy/components/cell/GridCell.js +11 -1
  40. package/legacy/components/cell/GridEditBooleanCell.js +2 -1
  41. package/legacy/components/cell/GridEditDateCell.js +2 -1
  42. package/legacy/components/cell/GridEditInputCell.js +2 -1
  43. package/legacy/components/cell/GridEditSingleSelectCell.js +2 -1
  44. package/legacy/components/cell/GridSkeletonCell.js +57 -0
  45. package/legacy/components/cell/index.js +2 -1
  46. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  47. package/legacy/components/containers/GridRootStyles.js +3 -3
  48. package/legacy/components/panel/GridColumnsPanel.js +41 -6
  49. package/legacy/constants/defaultGridSlotsComponents.js +2 -1
  50. package/legacy/constants/gridClasses.js +1 -1
  51. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +11 -5
  52. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  53. package/legacy/hooks/features/filter/gridFilterUtils.js +61 -56
  54. package/legacy/hooks/features/filter/useGridFilter.js +1 -1
  55. package/legacy/hooks/features/focus/useGridFocus.js +13 -3
  56. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  57. package/legacy/hooks/features/rows/useGridParamsApi.js +1 -1
  58. package/legacy/hooks/features/rows/useGridRows.js +73 -8
  59. package/legacy/hooks/features/rows/useGridRowsMeta.js +45 -18
  60. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +31 -13
  61. package/legacy/index.js +1 -1
  62. package/legacy/internals/index.js +1 -1
  63. package/legacy/models/events/gridEvents.js +2 -0
  64. package/legacy/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  65. package/legacy/models/params/index.js +2 -1
  66. package/legacy/utils/utils.js +25 -0
  67. package/models/api/gridParamsApi.d.ts +1 -1
  68. package/models/api/gridRowApi.d.ts +6 -0
  69. package/models/api/gridRowsMetaApi.d.ts +6 -1
  70. package/models/events/gridEventLookup.d.ts +7 -1
  71. package/models/events/gridEvents.d.ts +3 -1
  72. package/models/events/gridEvents.js +2 -0
  73. package/models/gridSlotsComponent.d.ts +5 -0
  74. package/models/params/gridCellParams.d.ts +7 -2
  75. package/models/params/gridRenderedRowsIntervalChangeParams.d.ts +10 -0
  76. package/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  77. package/models/params/index.d.ts +1 -0
  78. package/models/params/index.js +2 -1
  79. package/modern/components/GridRow.js +129 -82
  80. package/modern/components/cell/GridBooleanCell.js +2 -1
  81. package/modern/components/cell/GridCell.js +9 -1
  82. package/modern/components/cell/GridEditBooleanCell.js +2 -1
  83. package/modern/components/cell/GridEditDateCell.js +2 -1
  84. package/modern/components/cell/GridEditInputCell.js +2 -1
  85. package/modern/components/cell/GridEditSingleSelectCell.js +2 -1
  86. package/modern/components/cell/GridSkeletonCell.js +60 -0
  87. package/modern/components/cell/index.js +2 -1
  88. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  89. package/modern/components/containers/GridRootStyles.js +2 -0
  90. package/modern/components/panel/GridColumnsPanel.js +38 -6
  91. package/modern/constants/defaultGridSlotsComponents.js +2 -1
  92. package/modern/constants/gridClasses.js +1 -1
  93. package/modern/hooks/features/editRows/useGridCellEditing.new.js +8 -2
  94. package/modern/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  95. package/modern/hooks/features/filter/gridFilterUtils.js +54 -53
  96. package/modern/hooks/features/filter/useGridFilter.js +1 -1
  97. package/modern/hooks/features/focus/useGridFocus.js +13 -3
  98. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  99. package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
  100. package/modern/hooks/features/rows/useGridRows.js +65 -8
  101. package/modern/hooks/features/rows/useGridRowsMeta.js +36 -16
  102. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  103. package/modern/index.js +1 -1
  104. package/modern/internals/index.js +1 -1
  105. package/modern/models/events/gridEvents.js +2 -0
  106. package/modern/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  107. package/modern/models/params/index.js +2 -1
  108. package/modern/utils/utils.js +23 -0
  109. package/node/components/GridRow.js +131 -75
  110. package/node/components/cell/GridBooleanCell.js +2 -1
  111. package/node/components/cell/GridCell.js +9 -1
  112. package/node/components/cell/GridEditBooleanCell.js +2 -1
  113. package/node/components/cell/GridEditDateCell.js +2 -1
  114. package/node/components/cell/GridEditInputCell.js +2 -1
  115. package/node/components/cell/GridEditSingleSelectCell.js +2 -1
  116. package/node/components/cell/GridSkeletonCell.js +81 -0
  117. package/node/components/cell/index.js +13 -0
  118. package/node/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  119. package/node/components/containers/GridRootStyles.js +2 -0
  120. package/node/components/panel/GridColumnsPanel.js +36 -5
  121. package/node/constants/defaultGridSlotsComponents.js +1 -0
  122. package/node/constants/gridClasses.js +1 -1
  123. package/node/hooks/features/editRows/useGridCellEditing.new.js +9 -2
  124. package/node/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  125. package/node/hooks/features/filter/gridFilterUtils.js +55 -55
  126. package/node/hooks/features/filter/useGridFilter.js +1 -1
  127. package/node/hooks/features/focus/useGridFocus.js +13 -3
  128. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  129. package/node/hooks/features/rows/useGridParamsApi.js +1 -1
  130. package/node/hooks/features/rows/useGridRows.js +60 -7
  131. package/node/hooks/features/rows/useGridRowsMeta.js +35 -15
  132. package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  133. package/node/index.js +1 -1
  134. package/node/internals/index.js +6 -0
  135. package/node/models/events/gridEvents.js +2 -0
  136. package/node/models/params/gridRenderedRowsIntervalChangeParams.js +5 -0
  137. package/node/models/params/index.js +13 -0
  138. package/node/utils/utils.js +27 -0
  139. package/package.json +1 -1
  140. package/utils/utils.d.ts +2 -0
  141. package/utils/utils.js +23 -0
@@ -1,10 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["selected", "rowId", "row", "index", "style", "rowHeight", "className", "visibleColumns", "renderedColumns", "containerWidth", "firstColumnToRender", "lastColumnToRender", "cellFocus", "cellTabIndex", "editRowsState", "isLastVisible", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave"];
4
-
5
- /* eslint-disable jsx-a11y/click-events-have-key-events */
6
-
7
- /* eslint-disable jsx-a11y/interactive-supports-focus */
3
+ const _excluded = ["selected", "rowId", "row", "index", "style", "position", "rowHeight", "className", "visibleColumns", "renderedColumns", "containerWidth", "firstColumnToRender", "lastColumnToRender", "cellFocus", "cellTabIndex", "editRowsState", "isLastVisible", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave"];
8
4
  import * as React from 'react';
9
5
  import PropTypes from 'prop-types';
10
6
  import clsx from 'clsx';
@@ -23,6 +19,7 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../constants/gridDetailPanelTogg
23
19
  import { gridSortModelSelector } from '../hooks/features/sorting/gridSortingSelector';
24
20
  import { gridRowTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
25
21
  import { gridDensityHeaderGroupingMaxDepthSelector } from '../hooks/features/density/densitySelector';
22
+ import { randomNumberBetween } from '../utils/utils';
26
23
  import { jsx as _jsx } from "react/jsx-runtime";
27
24
  import { jsxs as _jsxs } from "react/jsx-runtime";
28
25
 
@@ -64,6 +61,7 @@ function GridRow(props) {
64
61
  row,
65
62
  index,
66
63
  style: styleProp,
64
+ position,
67
65
  rowHeight,
68
66
  className,
69
67
  visibleColumns,
@@ -110,9 +108,9 @@ function GridRow(props) {
110
108
  React.useLayoutEffect(() => {
111
109
  if (rowHeight === 'auto' && ref.current && typeof ResizeObserver === 'undefined') {
112
110
  // Fallback for IE
113
- apiRef.current.unstable_storeRowHeightMeasurement(rowId, ref.current.clientHeight);
111
+ apiRef.current.unstable_storeRowHeightMeasurement(rowId, ref.current.clientHeight, position);
114
112
  }
115
- }, [apiRef, rowHeight, rowId]);
113
+ }, [apiRef, rowHeight, rowId, position]);
116
114
  React.useLayoutEffect(() => {
117
115
  if (currentPage.range) {
118
116
  // The index prop is relative to the rows from all pages. As example, the index prop of the
@@ -137,11 +135,11 @@ function GridRow(props) {
137
135
  const resizeObserver = new ResizeObserver(entries => {
138
136
  const [entry] = entries;
139
137
  const height = entry.borderBoxSize && entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.contentRect.height;
140
- apiRef.current.unstable_storeRowHeightMeasurement(rowId, height);
138
+ apiRef.current.unstable_storeRowHeightMeasurement(rowId, height, position);
141
139
  });
142
140
  resizeObserver.observe(rootElement);
143
141
  return () => resizeObserver.disconnect();
144
- }, [apiRef, currentPage.range, index, rowHeight, rowId]);
142
+ }, [apiRef, currentPage.range, index, rowHeight, rowId, position]);
145
143
  const publish = React.useCallback((eventName, propHandler) => event => {
146
144
  // Ignore portal
147
145
  // The target is not an element when triggered by a Select inside the cell
@@ -197,47 +195,7 @@ function GridRow(props) {
197
195
 
198
196
  publish('rowClick', onClick)(event);
199
197
  }, [apiRef, onClick, publish, rowId]);
200
-
201
- const style = _extends({}, styleProp, {
202
- maxHeight: rowHeight === 'auto' ? 'none' : rowHeight,
203
- // max-height doesn't support "auto"
204
- minHeight: rowHeight
205
- });
206
-
207
- const sizes = apiRef.current.unstable_getRowInternalSizes(rowId);
208
-
209
- if (sizes?.spacingTop) {
210
- const property = rootProps.rowSpacingType === 'border' ? 'borderTopWidth' : 'marginTop';
211
- style[property] = sizes.spacingTop;
212
- }
213
-
214
- if (sizes?.spacingBottom) {
215
- const property = rootProps.rowSpacingType === 'border' ? 'borderBottomWidth' : 'marginBottom';
216
- style[property] = sizes.spacingBottom;
217
- }
218
-
219
- let rowClassName = null;
220
-
221
- if (typeof rootProps.getRowClassName === 'function') {
222
- const indexRelativeToCurrentPage = index - currentPage.range.firstRowIndex;
223
-
224
- const rowParams = _extends({}, apiRef.current.getRowParams(rowId), {
225
- isFirstVisible: indexRelativeToCurrentPage === 0,
226
- isLastVisible: indexRelativeToCurrentPage === currentPage.rows.length - 1,
227
- indexRelativeToCurrentPage
228
- });
229
-
230
- rowClassName = rootProps.getRowClassName(rowParams);
231
- }
232
-
233
- const cells = [];
234
-
235
- for (let i = 0; i < renderedColumns.length; i += 1) {
236
- const column = renderedColumns[i];
237
- const indexRelativeToAllColumns = firstColumnToRender + i;
238
- const isLastColumn = indexRelativeToAllColumns === visibleColumns.length - 1;
239
- const removeLastBorderRight = isLastColumn && hasScrollX && !hasScrollY;
240
- const showRightBorder = !isLastColumn ? rootProps.showCellRightBorder : !removeLastBorderRight && rootProps.disableExtendRowFullWidth;
198
+ const getCell = React.useCallback((column, cellProps) => {
241
199
  const cellParams = apiRef.current.getCellParams(rowId, column.field);
242
200
  const classNames = [];
243
201
  const disableDragEvents = rootProps.disableColumnReorder && column.disableReorder || !rootProps.rowReordering && !!sortModel.length && treeDepth > 1 && Object.keys(editRowsState).length > 0;
@@ -283,51 +241,139 @@ function GridRow(props) {
283
241
 
284
242
  const hasFocus = cellFocus !== null && cellFocus.id === rowId && cellFocus.field === column.field;
285
243
  const tabIndex = cellTabIndex !== null && cellTabIndex.id === rowId && cellTabIndex.field === column.field && cellParams.cellMode === 'view' ? 0 : -1;
244
+ return /*#__PURE__*/_jsx(rootProps.components.Cell, _extends({
245
+ value: cellParams.value,
246
+ field: column.field,
247
+ width: cellProps.width,
248
+ rowId: rowId,
249
+ height: rowHeight,
250
+ showRightBorder: cellProps.showRightBorder,
251
+ formattedValue: cellParams.formattedValue,
252
+ align: column.align || 'left',
253
+ cellMode: cellParams.cellMode,
254
+ colIndex: cellProps.indexRelativeToAllColumns,
255
+ isEditable: cellParams.isEditable,
256
+ hasFocus: hasFocus,
257
+ tabIndex: tabIndex,
258
+ className: clsx(classNames),
259
+ colSpan: cellProps.colSpan,
260
+ disableDragEvents: disableDragEvents
261
+ }, rootProps.componentsProps?.cell, {
262
+ children: content
263
+ }), column.field);
264
+ }, [apiRef, cellTabIndex, editRowsState, cellFocus, rootProps, row, rowHeight, rowId, treeDepth, sortModel.length]);
265
+ const sizes = apiRef.current.unstable_getRowInternalSizes(rowId);
266
+ let minHeight = rowHeight;
267
+
268
+ if (minHeight === 'auto' && sizes) {
269
+ let numberOfBaseSizes = 0;
270
+ const maximumSize = Object.entries(sizes).reduce((acc, [key, size]) => {
271
+ const isBaseHeight = /^base[A-Z]/.test(key);
272
+
273
+ if (!isBaseHeight) {
274
+ return acc;
275
+ }
276
+
277
+ numberOfBaseSizes += 1;
278
+
279
+ if (size > acc) {
280
+ return size;
281
+ }
282
+
283
+ return acc;
284
+ }, 0);
285
+
286
+ if (maximumSize > 0 && numberOfBaseSizes > 1) {
287
+ minHeight = maximumSize;
288
+ }
289
+ }
290
+
291
+ const style = _extends({}, styleProp, {
292
+ maxHeight: rowHeight === 'auto' ? 'none' : rowHeight,
293
+ // max-height doesn't support "auto"
294
+ minHeight
295
+ });
296
+
297
+ if (sizes?.spacingTop) {
298
+ const property = rootProps.rowSpacingType === 'border' ? 'borderTopWidth' : 'marginTop';
299
+ style[property] = sizes.spacingTop;
300
+ }
301
+
302
+ if (sizes?.spacingBottom) {
303
+ const property = rootProps.rowSpacingType === 'border' ? 'borderBottomWidth' : 'marginBottom';
304
+ style[property] = sizes.spacingBottom;
305
+ }
306
+
307
+ const rowClassNames = apiRef.current.unstable_applyPipeProcessors('rowClassName', [], rowId);
308
+
309
+ if (typeof rootProps.getRowClassName === 'function') {
310
+ const indexRelativeToCurrentPage = index - (currentPage.range?.firstRowIndex || 0);
311
+
312
+ const rowParams = _extends({}, apiRef.current.getRowParams(rowId), {
313
+ isFirstVisible: indexRelativeToCurrentPage === 0,
314
+ isLastVisible: indexRelativeToCurrentPage === currentPage.rows.length - 1,
315
+ indexRelativeToCurrentPage
316
+ });
317
+
318
+ rowClassNames.push(rootProps.getRowClassName(rowParams));
319
+ }
320
+
321
+ const randomNumber = randomNumberBetween(10000, 20, 80);
322
+ const cells = [];
323
+
324
+ for (let i = 0; i < renderedColumns.length; i += 1) {
325
+ const column = renderedColumns[i];
326
+ const indexRelativeToAllColumns = firstColumnToRender + i;
327
+ const isLastColumn = indexRelativeToAllColumns === visibleColumns.length - 1;
328
+ const removeLastBorderRight = isLastColumn && hasScrollX && !hasScrollY;
329
+ const showRightBorder = !isLastColumn ? rootProps.showCellRightBorder : !removeLastBorderRight && rootProps.disableExtendRowFullWidth;
286
330
  const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, indexRelativeToAllColumns);
287
331
 
288
332
  if (cellColSpanInfo && !cellColSpanInfo.spannedByColSpan) {
289
- const {
290
- colSpan,
291
- width
292
- } = cellColSpanInfo.cellProps;
293
- cells.push( /*#__PURE__*/_jsx(rootProps.components.Cell, _extends({
294
- value: cellParams.value,
295
- field: column.field,
296
- width: width,
297
- rowId: rowId,
298
- height: rowHeight,
299
- showRightBorder: showRightBorder,
300
- formattedValue: cellParams.formattedValue,
301
- align: column.align || 'left',
302
- cellMode: cellParams.cellMode,
303
- colIndex: indexRelativeToAllColumns,
304
- isEditable: cellParams.isEditable,
305
- hasFocus: hasFocus,
306
- tabIndex: tabIndex,
307
- className: clsx(classNames),
308
- colSpan: colSpan,
309
- disableDragEvents: disableDragEvents
310
- }, rootProps.componentsProps?.cell, {
311
- children: content
312
- }), column.field));
333
+ if (row) {
334
+ const {
335
+ colSpan,
336
+ width
337
+ } = cellColSpanInfo.cellProps;
338
+ const cellProps = {
339
+ width,
340
+ colSpan,
341
+ showRightBorder,
342
+ indexRelativeToAllColumns
343
+ };
344
+ cells.push(getCell(column, cellProps));
345
+ } else {
346
+ const {
347
+ width
348
+ } = cellColSpanInfo.cellProps;
349
+ const contentWidth = Math.round(randomNumber());
350
+ cells.push( /*#__PURE__*/_jsx(rootProps.components.SkeletonCell, {
351
+ width: width,
352
+ contentWidth: contentWidth,
353
+ field: column.field,
354
+ align: column.align
355
+ }, column.field));
356
+ }
313
357
  }
314
358
  }
315
359
 
316
360
  const emptyCellWidth = containerWidth - columnsTotalWidth;
361
+ const eventHandlers = row ? {
362
+ onClick: publishClick,
363
+ onDoubleClick: publish('rowDoubleClick', onDoubleClick),
364
+ onMouseEnter: publish('rowMouseEnter', onMouseEnter),
365
+ onMouseLeave: publish('rowMouseLeave', onMouseLeave)
366
+ } : null;
317
367
  return /*#__PURE__*/_jsxs("div", _extends({
318
368
  ref: ref,
319
369
  "data-id": rowId,
320
370
  "data-rowindex": index,
321
371
  role: "row",
322
- className: clsx(rowClassName, classes.root, className),
372
+ className: clsx(...rowClassNames, classes.root, className),
323
373
  "aria-rowindex": ariaRowIndex,
324
374
  "aria-selected": selected,
325
- style: style,
326
- onClick: publishClick,
327
- onDoubleClick: publish('rowDoubleClick', onDoubleClick),
328
- onMouseEnter: publish('rowMouseEnter', onMouseEnter),
329
- onMouseLeave: publish('rowMouseLeave', onMouseLeave)
330
- }, other, {
375
+ style: style
376
+ }, eventHandlers, other, {
331
377
  children: [cells, emptyCellWidth > 0 && /*#__PURE__*/_jsx(EmptyCell, {
332
378
  width: emptyCellWidth
333
379
  })]
@@ -352,8 +398,9 @@ process.env.NODE_ENV !== "production" ? GridRow.propTypes = {
352
398
  index: PropTypes.number.isRequired,
353
399
  isLastVisible: PropTypes.bool,
354
400
  lastColumnToRender: PropTypes.number.isRequired,
401
+ position: PropTypes.oneOf(['center', 'left', 'right']).isRequired,
355
402
  renderedColumns: PropTypes.arrayOf(PropTypes.object).isRequired,
356
- row: PropTypes.object.isRequired,
403
+ row: PropTypes.object,
357
404
  rowHeight: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]).isRequired,
358
405
  rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
359
406
  selected: PropTypes.bool.isRequired,
@@ -123,7 +123,8 @@ process.env.NODE_ENV !== "production" ? GridBooleanCellRaw.propTypes = {
123
123
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
124
124
 
125
125
  /**
126
- * The cell value, but if the column has valueGetter, use getValue.
126
+ * The cell value.
127
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
127
128
  */
128
129
  value: PropTypes.any
129
130
  } : void 0;
@@ -96,6 +96,14 @@ function GridCell(props) {
96
96
  onMouseUp(event);
97
97
  }
98
98
  }, [apiRef, field, onMouseUp, rowId]);
99
+ const publishMouseDown = React.useCallback(eventName => event => {
100
+ const params = apiRef.current.getCellParams(rowId, field || '');
101
+ apiRef.current.publishEvent(eventName, params, event);
102
+
103
+ if (onMouseDown) {
104
+ onMouseDown(event);
105
+ }
106
+ }, [apiRef, field, onMouseDown, rowId]);
99
107
  const publish = React.useCallback((eventName, propHandler) => event => {
100
108
  // Ignore portal
101
109
  if (!event.currentTarget.contains(event.target)) {
@@ -200,7 +208,7 @@ function GridCell(props) {
200
208
  tabIndex: (cellMode === 'view' || !isEditable) && !managesOwnFocus ? tabIndex : -1,
201
209
  onClick: publish('cellClick', onClick),
202
210
  onDoubleClick: publish('cellDoubleClick', onDoubleClick),
203
- onMouseDown: publish('cellMouseDown', onMouseDown),
211
+ onMouseDown: publishMouseDown('cellMouseDown'),
204
212
  onMouseUp: publishMouseUp('cellMouseUp'),
205
213
  onKeyDown: publish('cellKeyDown', onKeyDown)
206
214
  }, draggableEventHandlers, other, {
@@ -159,7 +159,8 @@ process.env.NODE_ENV !== "production" ? GridEditBooleanCell.propTypes = {
159
159
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
160
160
 
161
161
  /**
162
- * The cell value, but if the column has valueGetter, use getValue.
162
+ * The cell value.
163
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
163
164
  */
164
165
  value: PropTypes.any
165
166
  } : void 0;
@@ -213,7 +213,8 @@ process.env.NODE_ENV !== "production" ? GridEditDateCell.propTypes = {
213
213
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
214
214
 
215
215
  /**
216
- * The cell value, but if the column has valueGetter, use getValue.
216
+ * The cell value.
217
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
217
218
  */
218
219
  value: PropTypes.any
219
220
  } : void 0;
@@ -176,7 +176,8 @@ process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
176
176
  tabIndex: PropTypes.oneOf([-1, 0]),
177
177
 
178
178
  /**
179
- * The cell value, but if the column has valueGetter, use getValue.
179
+ * The cell value.
180
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
180
181
  */
181
182
  value: PropTypes.any
182
183
  } : void 0;
@@ -258,7 +258,8 @@ process.env.NODE_ENV !== "production" ? GridEditSingleSelectCell.propTypes = {
258
258
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
259
259
 
260
260
  /**
261
- * The cell value, but if the column has valueGetter, use getValue.
261
+ * The cell value.
262
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
262
263
  */
263
264
  value: PropTypes.any
264
265
  } : void 0;
@@ -0,0 +1,60 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["field", "align", "width", "contentWidth"];
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import Skeleton from '@mui/material/Skeleton';
7
+ import { capitalize } from '@mui/material/utils';
8
+ import { unstable_composeClasses as composeClasses } from '@mui/material';
9
+ import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
10
+ import { getDataGridUtilityClass } from '../../constants/gridClasses';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+
13
+ const useUtilityClasses = ownerState => {
14
+ const {
15
+ align,
16
+ classes
17
+ } = ownerState;
18
+ const slots = {
19
+ root: ['cell', 'cellSkeleton', `cell--text${capitalize(align)}`]
20
+ };
21
+ return composeClasses(slots, getDataGridUtilityClass, classes);
22
+ };
23
+
24
+ function GridSkeletonCell(props) {
25
+ const {
26
+ align,
27
+ width,
28
+ contentWidth
29
+ } = props,
30
+ other = _objectWithoutPropertiesLoose(props, _excluded);
31
+
32
+ const rootProps = useGridRootProps();
33
+ const ownerState = {
34
+ classes: rootProps.classes,
35
+ align
36
+ };
37
+ const classes = useUtilityClasses(ownerState);
38
+ return /*#__PURE__*/_jsx("div", _extends({
39
+ className: classes.root,
40
+ style: {
41
+ width
42
+ }
43
+ }, other, {
44
+ children: /*#__PURE__*/_jsx(Skeleton, {
45
+ width: `${contentWidth}%`
46
+ })
47
+ }));
48
+ }
49
+
50
+ process.env.NODE_ENV !== "production" ? GridSkeletonCell.propTypes = {
51
+ // ----------------------------- Warning --------------------------------
52
+ // | These PropTypes are generated from the TypeScript type definitions |
53
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
54
+ // ----------------------------------------------------------------------
55
+ align: PropTypes.string.isRequired,
56
+ contentWidth: PropTypes.number.isRequired,
57
+ field: PropTypes.string.isRequired,
58
+ width: PropTypes.number.isRequired
59
+ } : void 0;
60
+ export { GridSkeletonCell };
@@ -5,4 +5,5 @@ export * from './GridEditDateCell';
5
5
  export * from './GridEditInputCell';
6
6
  export * from './GridEditSingleSelectCell';
7
7
  export * from './GridActionsCell';
8
- export * from './GridActionsCellItem';
8
+ export * from './GridActionsCellItem';
9
+ export * from './GridSkeletonCell';
@@ -183,7 +183,8 @@ process.env.NODE_ENV !== "production" ? GridCellCheckboxForwardRef.propTypes = {
183
183
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
184
184
 
185
185
  /**
186
- * The cell value, but if the column has valueGetter, use getValue.
186
+ * The cell value.
187
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
187
188
  */
188
189
  value: PropTypes.any
189
190
  } : void 0;
@@ -35,6 +35,8 @@ export const GridRootStyles = styled('div', {
35
35
  [`& .${gridClasses.cellContent}`]: styles.cellContent
36
36
  }, {
37
37
  [`& .${gridClasses.cellCheckbox}`]: styles.cellCheckbox
38
+ }, {
39
+ [`& .${gridClasses.cellSkeleton}`]: styles.cellSkeleton
38
40
  }, {
39
41
  [`& .${gridClasses.checkboxInput}`]: styles.checkboxInput
40
42
  }, {
@@ -1,5 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["sort"];
2
4
  import * as React from 'react';
5
+ import PropTypes from 'prop-types';
3
6
  import { unstable_composeClasses as composeClasses } from '@mui/material';
4
7
  import IconButton from '@mui/material/IconButton';
5
8
  import { switchClasses } from '@mui/material/Switch';
@@ -54,7 +57,9 @@ const GridColumnsPanelRowRoot = styled('div', {
54
57
  const GridIconButtonRoot = styled(IconButton)({
55
58
  justifyContent: 'flex-end'
56
59
  });
57
- export function GridColumnsPanel(props) {
60
+ const collator = new Intl.Collator();
61
+
62
+ function GridColumnsPanel(props) {
58
63
  const apiRef = useGridApiContext();
59
64
  const searchInputRef = React.useRef(null);
60
65
  const columns = useGridSelector(apiRef, gridColumnDefinitionsSelector);
@@ -66,6 +71,24 @@ export function GridColumnsPanel(props) {
66
71
  };
67
72
  const classes = useUtilityClasses(ownerState);
68
73
 
74
+ const {
75
+ sort
76
+ } = props,
77
+ other = _objectWithoutPropertiesLoose(props, _excluded);
78
+
79
+ const sortedColumns = React.useMemo(() => {
80
+ switch (sort) {
81
+ case 'asc':
82
+ return [...columns].sort((a, b) => collator.compare(a.headerName || a.field, b.headerName || b.field));
83
+
84
+ case 'desc':
85
+ return [...columns].sort((a, b) => -collator.compare(a.headerName || a.field, b.headerName || b.field));
86
+
87
+ default:
88
+ return columns;
89
+ }
90
+ }, [columns, sort]);
91
+
69
92
  const toggleColumn = event => {
70
93
  const {
71
94
  name: field
@@ -99,16 +122,16 @@ export function GridColumnsPanel(props) {
99
122
  }, []);
100
123
  const currentColumns = React.useMemo(() => {
101
124
  if (!searchValue) {
102
- return columns;
125
+ return sortedColumns;
103
126
  }
104
127
 
105
128
  const searchValueToCheck = searchValue.toLowerCase();
106
- return columns.filter(column => (column.headerName || column.field).toLowerCase().indexOf(searchValueToCheck) > -1);
107
- }, [columns, searchValue]);
129
+ return sortedColumns.filter(column => (column.headerName || column.field).toLowerCase().indexOf(searchValueToCheck) > -1);
130
+ }, [sortedColumns, searchValue]);
108
131
  React.useEffect(() => {
109
132
  searchInputRef.current.focus();
110
133
  }, []);
111
- return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({}, props, {
134
+ return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({}, other, {
112
135
  children: [/*#__PURE__*/_jsx(GridPanelHeader, {
113
136
  children: /*#__PURE__*/_jsx(rootProps.components.BaseTextField, _extends({
114
137
  label: apiRef.current.getLocaleText('columnsPanelTextFieldLabel'),
@@ -155,4 +178,13 @@ export function GridColumnsPanel(props) {
155
178
  }))]
156
179
  })]
157
180
  }));
158
- }
181
+ }
182
+
183
+ process.env.NODE_ENV !== "production" ? GridColumnsPanel.propTypes = {
184
+ // ----------------------------- Warning --------------------------------
185
+ // | These PropTypes are generated from the TypeScript type definitions |
186
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
187
+ // ----------------------------------------------------------------------
188
+ sort: PropTypes.oneOf(['asc', 'desc'])
189
+ } : void 0;
190
+ export { GridColumnsPanel };
@@ -7,7 +7,7 @@ import MUISwitch from '@mui/material/Switch';
7
7
  import MUIButton from '@mui/material/Button';
8
8
  import MUITooltip from '@mui/material/Tooltip';
9
9
  import MUIPopper from '@mui/material/Popper';
10
- import { GridArrowDownwardIcon, GridArrowUpwardIcon, GridCell, GridCheckIcon, GridCloseIcon, GridColumnIcon, GridColumnMenu, GridColumnsPanel, GridFilterAltIcon, GridFilterListIcon, GridFilterPanel, GridFooter, GridHeader, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridSaveAltIcon, GridSeparatorIcon, GridTableRowsIcon, GridTripleDotsVerticalIcon, GridViewHeadlineIcon, GridViewStreamIcon, GridMoreVertIcon, GridExpandMoreIcon, GridKeyboardArrowRight, GridAddIcon, GridRemoveIcon, GridDragIcon, GridColumnHeaderFilterIconButton, GridSearchIcon } from '../components';
10
+ import { GridArrowDownwardIcon, GridArrowUpwardIcon, GridCell, GridSkeletonCell, GridCheckIcon, GridCloseIcon, GridColumnIcon, GridColumnMenu, GridColumnsPanel, GridFilterAltIcon, GridFilterListIcon, GridFilterPanel, GridFooter, GridHeader, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridSaveAltIcon, GridSeparatorIcon, GridTableRowsIcon, GridTripleDotsVerticalIcon, GridViewHeadlineIcon, GridViewStreamIcon, GridMoreVertIcon, GridExpandMoreIcon, GridKeyboardArrowRight, GridAddIcon, GridRemoveIcon, GridDragIcon, GridColumnHeaderFilterIconButton, GridSearchIcon } from '../components';
11
11
  import { GridColumnUnsortedIcon } from '../components/columnHeaders/GridColumnUnsortedIcon';
12
12
  import { ErrorOverlay } from '../components/ErrorOverlay';
13
13
  import { GridNoResultsOverlay } from '../components/GridNoResultsOverlay';
@@ -52,6 +52,7 @@ export const DATA_GRID_DEFAULT_SLOTS_COMPONENTS = _extends({}, DEFAULT_GRID_ICON
52
52
  BaseTooltip: MUITooltip,
53
53
  BasePopper: MUIPopper,
54
54
  Cell: GridCell,
55
+ SkeletonCell: GridSkeletonCell,
55
56
  ColumnHeaderFilterIconButton: GridColumnHeaderFilterIconButton,
56
57
  ColumnMenu: GridColumnMenu,
57
58
  ErrorOverlay,
@@ -2,4 +2,4 @@ import { generateUtilityClasses, generateUtilityClass } from '@mui/material';
2
2
  export function getDataGridUtilityClass(slot) {
3
3
  return generateUtilityClass('MuiDataGrid', slot);
4
4
  }
5
- export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
5
+ export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'cellSkeleton', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'row--detailPanelExpanded', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
@@ -11,6 +11,7 @@ import { gridEditRowsStateSelector } from './gridEditRowsSelector';
11
11
  import { isPrintableKey } from '../../../utils/keyboardUtils';
12
12
  import { buildWarning } from '../../../utils/warning';
13
13
  import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
14
+ import { deepClone } from '../../../utils/utils';
14
15
  import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../models/params/gridEditCellParams';
15
16
  const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
16
17
  export const useGridCellEditing = (apiRef, props) => {
@@ -319,7 +320,11 @@ export const useGridCellEditing = (apiRef, props) => {
319
320
  if (error || isProcessingProps) {
320
321
  // Attempt to change cell mode to "view" was not successful
321
322
  // Update previous mode to allow another attempt
322
- prevCellModesModel.current[id][field].mode = GridCellModes.Edit;
323
+ prevCellModesModel.current[id][field].mode = GridCellModes.Edit; // Revert the mode in the cellModesModel prop back to "edit"
324
+
325
+ updateFieldInCellModesModel(id, field, {
326
+ mode: GridCellModes.Edit
327
+ });
323
328
  return;
324
329
  }
325
330
 
@@ -435,7 +440,8 @@ export const useGridCellEditing = (apiRef, props) => {
435
440
  const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopCellEditMode may change it later
436
441
 
437
442
  const copyOfPrevCellModes = prevCellModesModel.current;
438
- prevCellModesModel.current = cellModesModel;
443
+ prevCellModesModel.current = deepClone(cellModesModel); // Do a deep-clone because the attributes might be changed later
444
+
439
445
  Object.entries(cellModesModel).forEach(([id, fields]) => {
440
446
  Object.entries(fields).forEach(([field, params]) => {
441
447
  const prevMode = copyOfPrevCellModes[id]?.[field]?.mode || GridCellModes.View;
@@ -12,6 +12,7 @@ import { isPrintableKey } from '../../../utils/keyboardUtils';
12
12
  import { gridColumnFieldsSelector } from '../columns/gridColumnsSelector';
13
13
  import { buildWarning } from '../../../utils/warning';
14
14
  import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
15
+ import { deepClone } from '../../../utils/utils';
15
16
  import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models/params/gridRowParams';
16
17
  const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
17
18
  export const useGridRowEditing = (apiRef, props) => {
@@ -401,7 +402,11 @@ export const useGridRowEditing = (apiRef, props) => {
401
402
  const hasSomeFieldWithError = Object.values(editingState[id]).some(fieldProps => fieldProps.error);
402
403
 
403
404
  if (hasSomeFieldWithError) {
404
- prevRowModesModel.current[id].mode = GridRowModes.Edit;
405
+ prevRowModesModel.current[id].mode = GridRowModes.Edit; // Revert the mode in the rowModesModel prop back to "edit"
406
+
407
+ updateRowInRowModesModel(id, {
408
+ mode: GridRowModes.Edit
409
+ });
405
410
  return;
406
411
  }
407
412
 
@@ -584,7 +589,8 @@ export const useGridRowEditing = (apiRef, props) => {
584
589
  const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopRowEditMode may change it later
585
590
 
586
591
  const copyOfPrevRowModesModel = prevRowModesModel.current;
587
- prevRowModesModel.current = rowModesModel;
592
+ prevRowModesModel.current = deepClone(rowModesModel); // Do a deep-clone because the attributes might be changed later
593
+
588
594
  Object.entries(rowModesModel).forEach(([id, params]) => {
589
595
  const prevMode = copyOfPrevRowModesModel[id]?.mode || GridRowModes.View;
590
596
  const originalId = idToIdLookup[id] ?? id;