@mui/x-data-grid 6.0.0-alpha.0 → 6.0.0-alpha.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 (161) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/DataGrid/useDataGridProps.js +4 -4
  3. package/components/DataGridVirtualScroller.js +5 -3
  4. package/components/GridPagination.d.ts +43 -1
  5. package/components/GridPagination.js +1 -2
  6. package/components/GridRow.d.ts +1 -4
  7. package/components/GridRow.js +9 -8
  8. package/components/base/GridBody.js +1 -2
  9. package/components/base/GridOverlays.js +52 -12
  10. package/components/cell/GridBooleanCell.js +2 -1
  11. package/components/columnSelection/GridCellCheckboxRenderer.d.ts +2 -2
  12. package/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  13. package/components/containers/GridOverlay.js +0 -5
  14. package/components/panel/filterPanel/GridFilterForm.js +2 -1
  15. package/components/toolbar/GridToolbarFilterButton.js +8 -4
  16. package/constants/gridClasses.d.ts +8 -0
  17. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +1 -1
  18. package/hooks/core/strategyProcessing/gridStrategyProcessingApi.d.ts +1 -1
  19. package/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  20. package/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  21. package/hooks/features/editRows/useGridEditing.new.js +3 -2
  22. package/hooks/features/editRows/useGridEditing.old.js +2 -1
  23. package/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  24. package/hooks/features/export/useGridPrintExport.js +31 -17
  25. package/hooks/features/export/utils.js +1 -5
  26. package/hooks/features/filter/gridFilterSelector.js +2 -2
  27. package/hooks/features/filter/useGridFilter.js +6 -6
  28. package/hooks/features/pagination/gridPaginationSelector.js +2 -2
  29. package/hooks/features/rows/gridRowsInterfaces.d.ts +106 -0
  30. package/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  31. package/hooks/features/rows/gridRowsSelector.d.ts +17 -7
  32. package/hooks/features/rows/gridRowsSelector.js +38 -6
  33. package/hooks/features/rows/gridRowsUtils.d.ts +16 -4
  34. package/hooks/features/rows/gridRowsUtils.js +222 -39
  35. package/hooks/features/rows/index.d.ts +3 -3
  36. package/hooks/features/rows/index.js +2 -2
  37. package/hooks/features/rows/useGridRows.js +161 -124
  38. package/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
  39. package/hooks/features/selection/useGridSelection.js +2 -2
  40. package/hooks/features/sorting/gridSortingSelector.js +9 -4
  41. package/hooks/features/sorting/gridSortingState.d.ts +2 -2
  42. package/hooks/features/sorting/useGridSorting.js +9 -33
  43. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +4 -7
  44. package/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  45. package/index.js +1 -1
  46. package/internals/index.d.ts +2 -1
  47. package/internals/index.js +1 -0
  48. package/legacy/DataGrid/useDataGridProps.js +4 -4
  49. package/legacy/components/DataGridVirtualScroller.js +5 -3
  50. package/legacy/components/GridPagination.js +1 -2
  51. package/legacy/components/GridRow.js +9 -8
  52. package/legacy/components/base/GridBody.js +1 -2
  53. package/legacy/components/base/GridOverlays.js +54 -12
  54. package/legacy/components/cell/GridBooleanCell.js +2 -1
  55. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  56. package/legacy/components/containers/GridOverlay.js +0 -5
  57. package/legacy/components/panel/filterPanel/GridFilterForm.js +2 -1
  58. package/legacy/components/toolbar/GridToolbarFilterButton.js +3 -1
  59. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  60. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  61. package/legacy/hooks/features/editRows/useGridEditing.new.js +3 -2
  62. package/legacy/hooks/features/editRows/useGridEditing.old.js +2 -1
  63. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  64. package/legacy/hooks/features/export/useGridPrintExport.js +33 -20
  65. package/legacy/hooks/features/export/utils.js +1 -3
  66. package/legacy/hooks/features/filter/gridFilterSelector.js +2 -2
  67. package/legacy/hooks/features/filter/useGridFilter.js +6 -6
  68. package/legacy/hooks/features/pagination/gridPaginationSelector.js +2 -2
  69. package/legacy/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  70. package/legacy/hooks/features/rows/gridRowsSelector.js +52 -9
  71. package/legacy/hooks/features/rows/gridRowsUtils.js +238 -46
  72. package/legacy/hooks/features/rows/index.js +2 -2
  73. package/legacy/hooks/features/rows/useGridRows.js +163 -134
  74. package/legacy/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
  75. package/legacy/hooks/features/selection/useGridSelection.js +2 -2
  76. package/legacy/hooks/features/sorting/gridSortingSelector.js +5 -2
  77. package/legacy/hooks/features/sorting/useGridSorting.js +11 -33
  78. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  79. package/legacy/index.js +1 -1
  80. package/legacy/internals/index.js +1 -0
  81. package/legacy/models/gridFeatureMode.js +1 -4
  82. package/models/api/gridParamsApi.d.ts +2 -2
  83. package/models/api/gridRowApi.d.ts +7 -5
  84. package/models/events/gridEventLookup.d.ts +3 -3
  85. package/models/gridApiCaches.d.ts +1 -1
  86. package/models/gridFeatureMode.d.ts +0 -4
  87. package/models/gridFeatureMode.js +1 -4
  88. package/models/gridRows.d.ts +100 -30
  89. package/models/gridSortModel.d.ts +2 -2
  90. package/models/params/gridCellParams.d.ts +7 -11
  91. package/modern/DataGrid/useDataGridProps.js +4 -4
  92. package/modern/components/DataGridVirtualScroller.js +5 -3
  93. package/modern/components/GridPagination.js +1 -2
  94. package/modern/components/GridRow.js +9 -8
  95. package/modern/components/base/GridBody.js +1 -2
  96. package/modern/components/base/GridOverlays.js +52 -12
  97. package/modern/components/cell/GridBooleanCell.js +2 -1
  98. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  99. package/modern/components/containers/GridOverlay.js +0 -5
  100. package/modern/components/panel/filterPanel/GridFilterForm.js +2 -1
  101. package/modern/components/toolbar/GridToolbarFilterButton.js +1 -1
  102. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  103. package/modern/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  104. package/modern/hooks/features/editRows/useGridEditing.new.js +3 -2
  105. package/modern/hooks/features/editRows/useGridEditing.old.js +2 -1
  106. package/modern/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  107. package/modern/hooks/features/export/useGridPrintExport.js +30 -16
  108. package/modern/hooks/features/export/utils.js +1 -1
  109. package/modern/hooks/features/filter/gridFilterSelector.js +2 -2
  110. package/modern/hooks/features/filter/useGridFilter.js +6 -6
  111. package/modern/hooks/features/pagination/gridPaginationSelector.js +2 -2
  112. package/modern/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  113. package/modern/hooks/features/rows/gridRowsSelector.js +28 -6
  114. package/modern/hooks/features/rows/gridRowsUtils.js +220 -37
  115. package/modern/hooks/features/rows/index.js +2 -2
  116. package/modern/hooks/features/rows/useGridRows.js +158 -121
  117. package/modern/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
  118. package/modern/hooks/features/selection/useGridSelection.js +2 -2
  119. package/modern/hooks/features/sorting/gridSortingSelector.js +3 -2
  120. package/modern/hooks/features/sorting/useGridSorting.js +9 -33
  121. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +10 -16
  122. package/modern/index.js +1 -1
  123. package/modern/internals/index.js +1 -0
  124. package/modern/models/gridFeatureMode.js +1 -4
  125. package/node/DataGrid/useDataGridProps.js +3 -3
  126. package/node/components/DataGridVirtualScroller.js +5 -3
  127. package/node/components/GridPagination.js +1 -2
  128. package/node/components/GridRow.js +9 -7
  129. package/node/components/base/GridBody.js +1 -3
  130. package/node/components/base/GridOverlays.js +57 -12
  131. package/node/components/cell/GridBooleanCell.js +3 -1
  132. package/node/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  133. package/node/components/containers/GridOverlay.js +0 -5
  134. package/node/components/panel/filterPanel/GridFilterForm.js +2 -1
  135. package/node/components/toolbar/GridToolbarFilterButton.js +8 -4
  136. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  137. package/node/hooks/features/editRows/useGridCellEditing.new.js +20 -10
  138. package/node/hooks/features/editRows/useGridEditing.new.js +4 -2
  139. package/node/hooks/features/editRows/useGridEditing.old.js +3 -1
  140. package/node/hooks/features/editRows/useGridRowEditing.new.js +20 -10
  141. package/node/hooks/features/export/useGridPrintExport.js +31 -17
  142. package/node/hooks/features/export/utils.js +1 -5
  143. package/node/hooks/features/filter/gridFilterSelector.js +1 -1
  144. package/node/hooks/features/filter/useGridFilter.js +5 -6
  145. package/node/hooks/features/pagination/gridPaginationSelector.js +1 -1
  146. package/node/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  147. package/node/hooks/features/rows/gridRowsSelector.js +43 -10
  148. package/node/hooks/features/rows/gridRowsUtils.js +239 -40
  149. package/node/hooks/features/rows/index.js +23 -9
  150. package/node/hooks/features/rows/useGridRows.js +161 -122
  151. package/node/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
  152. package/node/hooks/features/selection/useGridSelection.js +2 -2
  153. package/node/hooks/features/sorting/gridSortingSelector.js +9 -4
  154. package/node/hooks/features/sorting/useGridSorting.js +9 -33
  155. package/node/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  156. package/node/index.js +1 -1
  157. package/node/internals/index.js +14 -2
  158. package/node/models/gridFeatureMode.js +1 -7
  159. package/package.json +1 -1
  160. package/themeAugmentation/props.d.ts +2 -2
  161. package/hooks/features/rows/gridRowsState.d.ts +0 -60
@@ -5,7 +5,7 @@ const _excluded = ["selected", "rowId", "row", "index", "style", "position", "ro
5
5
  import * as React from 'react';
6
6
  import PropTypes from 'prop-types';
7
7
  import clsx from 'clsx';
8
- import { unstable_composeClasses as composeClasses } from '@mui/material';
8
+ import { unstable_composeClasses as composeClasses, useForkRef } from '@mui/material';
9
9
  import { GridEditModes, GridRowModes, GridCellModes } from '../models/gridEditRowModel';
10
10
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
11
11
  import { getDataGridUtilityClass, gridClasses } from '../constants/gridClasses';
@@ -18,7 +18,7 @@ import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../colDef/gridCheckboxSelection
18
18
  import { GRID_ACTIONS_COLUMN_TYPE } from '../colDef/gridActionsColDef';
19
19
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../constants/gridDetailPanelToggleField';
20
20
  import { gridSortModelSelector } from '../hooks/features/sorting/gridSortingSelector';
21
- import { gridRowTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
21
+ import { gridRowMaximumTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
22
22
  import { gridDensityHeaderGroupingMaxDepthSelector } from '../hooks/features/density/densitySelector';
23
23
  import { randomNumberBetween } from '../utils/utils';
24
24
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -55,7 +55,7 @@ const EmptyCell = ({
55
55
  }); // TODO change to .MuiDataGrid-emptyCell or .MuiDataGrid-rowFiller
56
56
  };
57
57
 
58
- function GridRow(props) {
58
+ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
59
59
  const {
60
60
  selected,
61
61
  rowId,
@@ -86,8 +86,9 @@ function GridRow(props) {
86
86
  const currentPage = useGridVisibleRows(apiRef, rootProps);
87
87
  const columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
88
88
  const sortModel = useGridSelector(apiRef, gridSortModelSelector);
89
- const treeDepth = useGridSelector(apiRef, gridRowTreeDepthSelector);
89
+ const treeDepth = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector);
90
90
  const headerGroupingMaxDepth = useGridSelector(apiRef, gridDensityHeaderGroupingMaxDepthSelector);
91
+ const handleRef = useForkRef(ref, refProp);
91
92
  const ariaRowIndex = index + headerGroupingMaxDepth + 2; // 1 for the header row and 1 as it's 1-based
92
93
 
93
94
  const {
@@ -322,6 +323,7 @@ function GridRow(props) {
322
323
  }
323
324
 
324
325
  const randomNumber = randomNumberBetween(10000, 20, 80);
326
+ const rowType = apiRef.current.getRowNode(rowId).type;
325
327
  const cells = [];
326
328
 
327
329
  for (let i = 0; i < renderedColumns.length; i += 1) {
@@ -333,7 +335,7 @@ function GridRow(props) {
333
335
  const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, indexRelativeToAllColumns);
334
336
 
335
337
  if (cellColSpanInfo && !cellColSpanInfo.spannedByColSpan) {
336
- if (row) {
338
+ if (rowType !== 'skeletonRow') {
337
339
  const {
338
340
  colSpan,
339
341
  width
@@ -368,7 +370,7 @@ function GridRow(props) {
368
370
  onMouseLeave: publish('rowMouseLeave', onMouseLeave)
369
371
  } : null;
370
372
  return /*#__PURE__*/_jsxs("div", _extends({
371
- ref: ref,
373
+ ref: handleRef,
372
374
  "data-id": rowId,
373
375
  "data-rowindex": index,
374
376
  role: "row",
@@ -381,8 +383,7 @@ function GridRow(props) {
381
383
  width: emptyCellWidth
382
384
  })]
383
385
  }));
384
- }
385
-
386
+ });
386
387
  process.env.NODE_ENV !== "production" ? GridRow.propTypes = {
387
388
  // ----------------------------- Warning --------------------------------
388
389
  // | These PropTypes are generated from the TypeScript type definitions |
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
3
3
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
4
4
  import { GridMainContainer } from '../containers/GridMainContainer';
5
5
  import { GridAutoSizer } from '../GridAutoSizer';
6
- import { GridOverlays } from './GridOverlays';
7
6
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
8
7
  import { useGridSelector } from '../../hooks/utils/useGridSelector';
9
8
  import { gridDensityTotalHeaderHeightSelector } from '../../hooks/features/density/densitySelector';
@@ -51,7 +50,7 @@ function GridBody(props) {
51
50
  apiRef.current.publishEvent('resize', size);
52
51
  }, [apiRef]);
53
52
  return /*#__PURE__*/_jsxs(GridMainContainer, {
54
- children: [/*#__PURE__*/_jsx(GridOverlays, {}), /*#__PURE__*/_jsx(ColumnHeadersComponent, {
53
+ children: [/*#__PURE__*/_jsx(ColumnHeadersComponent, {
55
54
  ref: columnsContainerRef,
56
55
  innerRef: columnHeadersRef
57
56
  }), /*#__PURE__*/_jsx(GridAutoSizer, {
@@ -1,18 +1,53 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/material/utils';
4
+ import { styled } from '@mui/material/styles';
5
+ import { unstable_composeClasses as composeClasses } from '@mui/material';
6
+ import clsx from 'clsx';
4
7
  import { useGridSelector } from '../../hooks/utils/useGridSelector';
5
8
  import { gridVisibleRowCountSelector } from '../../hooks/features/filter/gridFilterSelector';
6
9
  import { gridRowCountSelector, gridRowsLoadingSelector } from '../../hooks/features/rows/gridRowsSelector';
7
10
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
8
11
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
9
- import { gridDensityTotalHeaderHeightSelector } from '../../hooks/features/density/densitySelector';
12
+ import { getMinimalContentHeight } from '../../hooks/features/rows/gridRowsUtils';
13
+ import { getDataGridUtilityClass } from '../../constants/gridClasses';
10
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
+ const GridOverlayWrapperRoot = styled('div', {
16
+ name: 'MuiDataGrid',
17
+ slot: 'OverlayWrapper',
18
+ overridesResolver: (props, styles) => styles.overlayWrapper
19
+ })({
20
+ position: 'sticky',
21
+ // To stay in place while scrolling
22
+ top: 0,
23
+ left: 0,
24
+ width: 0,
25
+ // To stay above the content instead of shifting it down
26
+ height: 0,
27
+ // To stay above the content instead of shifting it down
28
+ zIndex: 4 // Should be above pinned columns, pinned rows and detail panel
29
+
30
+ });
31
+ const GridOverlayWrapperInner = styled('div', {
32
+ name: 'MuiDataGrid',
33
+ slot: 'OverlayWrapperInner',
34
+ overridesResolver: (props, styles) => styles.overlayWrapperInner
35
+ })({});
36
+
37
+ const useUtilityClasses = ownerState => {
38
+ const {
39
+ classes
40
+ } = ownerState;
41
+ const slots = {
42
+ root: ['overlayWrapper'],
43
+ inner: ['overlayWrapperInner']
44
+ };
45
+ return composeClasses(slots, getDataGridUtilityClass, classes);
46
+ };
11
47
 
12
48
  function GridOverlayWrapper(props) {
13
49
  const apiRef = useGridApiContext();
14
50
  const rootProps = useGridRootProps();
15
- const totalHeaderHeight = useGridSelector(apiRef, gridDensityTotalHeaderHeightSelector);
16
51
  const [viewportInnerSize, setViewportInnerSize] = React.useState(() => apiRef.current.getRootDimensions()?.viewportInnerSize ?? null);
17
52
  const handleViewportSizeChange = React.useCallback(() => {
18
53
  setViewportInnerSize(apiRef.current.getRootDimensions()?.viewportInnerSize ?? null);
@@ -23,22 +58,27 @@ function GridOverlayWrapper(props) {
23
58
  let height = viewportInnerSize?.height ?? 0;
24
59
 
25
60
  if (rootProps.autoHeight && height === 0) {
26
- height = 'auto';
61
+ height = getMinimalContentHeight(apiRef); // Give room to show the overlay when there no rows.
27
62
  }
28
63
 
64
+ const classes = useUtilityClasses(_extends({}, props, {
65
+ classes: rootProps.classes
66
+ }));
67
+
29
68
  if (!viewportInnerSize) {
30
69
  return null;
31
70
  }
32
71
 
33
- return /*#__PURE__*/_jsx("div", _extends({
34
- style: {
35
- height,
36
- width: viewportInnerSize?.width ?? 0,
37
- position: 'absolute',
38
- top: totalHeaderHeight,
39
- bottom: height === 'auto' ? 0 : undefined
40
- }
41
- }, props));
72
+ return /*#__PURE__*/_jsx(GridOverlayWrapperRoot, {
73
+ className: clsx(classes.root),
74
+ children: /*#__PURE__*/_jsx(GridOverlayWrapperInner, _extends({
75
+ className: clsx(classes.inner),
76
+ style: {
77
+ height,
78
+ width: viewportInnerSize?.width ?? 0
79
+ }
80
+ }, props))
81
+ });
42
82
  }
43
83
 
44
84
  export function GridOverlays() {
@@ -7,6 +7,7 @@ import { unstable_composeClasses as composeClasses } from '@mui/material';
7
7
  import { getDataGridUtilityClass } from '../../constants/gridClasses';
8
8
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
9
9
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
10
+ import { isAutoGeneratedRow } from '../../hooks/features/rows/gridRowsUtils';
10
11
  import { jsx as _jsx } from "react/jsx-runtime";
11
12
 
12
13
  const useUtilityClasses = ownerState => {
@@ -131,7 +132,7 @@ process.env.NODE_ENV !== "production" ? GridBooleanCellRaw.propTypes = {
131
132
  const GridBooleanCell = /*#__PURE__*/React.memo(GridBooleanCellRaw);
132
133
  export { GridBooleanCell };
133
134
  export const renderBooleanCell = params => {
134
- if (params.rowNode.isAutoGenerated) {
135
+ if (isAutoGeneratedRow(params.rowNode)) {
135
136
  return '';
136
137
  }
137
138
 
@@ -75,17 +75,12 @@ const GridCellCheckboxForwardRef = /*#__PURE__*/React.forwardRef(function GridCe
75
75
  }
76
76
  }, [apiRef, props]);
77
77
 
78
- if (rowNode.position === 'footer') {
78
+ if (rowNode.type === 'footer' || rowNode.type === 'pinnedRow') {
79
79
  return null;
80
80
  }
81
81
 
82
82
  const isSelectable = apiRef.current.isRowSelectable(id);
83
83
  const label = apiRef.current.getLocaleText(isChecked ? 'checkboxSelectionUnselectRow' : 'checkboxSelectionSelectRow');
84
-
85
- if (rowNode.isPinned) {
86
- return null;
87
- }
88
-
89
84
  return /*#__PURE__*/_jsx(rootProps.components.BaseCheckbox, _extends({
90
85
  ref: handleRef,
91
86
  tabIndex: tabIndex,
@@ -27,13 +27,8 @@ const GridOverlayRoot = styled('div', {
27
27
  })(({
28
28
  theme
29
29
  }) => ({
30
- position: 'absolute',
31
- top: 0,
32
- zIndex: 4,
33
- // should be above pinned columns, pinned rows and detail panel
34
30
  width: '100%',
35
31
  height: '100%',
36
- pointerEvents: 'none',
37
32
  display: 'flex',
38
33
  alignSelf: 'center',
39
34
  alignItems: 'center',
@@ -229,7 +229,8 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
229
229
  }), [currentOperator]);
230
230
  return /*#__PURE__*/_jsxs(GridFilterFormRoot, _extends({
231
231
  ref: ref,
232
- className: classes.root
232
+ className: classes.root,
233
+ "data-id": item.id
233
234
  }, other, {
234
235
  children: [/*#__PURE__*/_jsx(FilterFormDeleteIcon, _extends({
235
236
  variant: "standard",
@@ -71,7 +71,7 @@ const GridToolbarFilterButton = /*#__PURE__*/React.forwardRef(function GridToolb
71
71
  children: activeFilters.map((item, index) => _extends({}, lookup[item.columnField] && /*#__PURE__*/_jsx("li", {
72
72
  children: `${lookup[item.columnField].headerName || item.columnField}
73
73
  ${getOperatorLabel(item)}
74
- ${item.value}`
74
+ ${item.value ?? ''}`
75
75
  }, index)))
76
76
  })]
77
77
  });
@@ -236,7 +236,7 @@ export const useGridColumnHeaders = props => {
236
236
 
237
237
  const columnsToRender = getColumnsToRender(params);
238
238
 
239
- if (columnsToRender == null) {
239
+ if (columnsToRender == null || columnsToRender.renderedColumns.length === 0) {
240
240
  return null;
241
241
  }
242
242
 
@@ -4,13 +4,14 @@ import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  const _excluded = ["id", "field"],
5
5
  _excluded2 = ["id", "field"];
6
6
  import * as React from 'react';
7
+ import { unstable_useEventCallback as useEventCallback } from '@mui/utils';
7
8
  import { useGridApiEventHandler, useGridApiOptionHandler, GridSignature } from '../../utils/useGridApiEventHandler';
8
9
  import { GridEditModes, GridCellModes } from '../../../models/gridEditRowModel';
9
10
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
10
11
  import { gridEditRowsStateSelector } from './gridEditRowsSelector';
11
12
  import { isPrintableKey } from '../../../utils/keyboardUtils';
12
13
  import { buildWarning } from '../../../utils/warning';
13
- import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
14
+ import { gridRowsDataRowIdToIdLookupSelector } from '../rows/gridRowsSelector';
14
15
  import { deepClone } from '../../../utils/utils';
15
16
  import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../models/params/gridEditCellParams';
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');
@@ -103,6 +104,10 @@ export const useGridCellEditing = (apiRef, props) => {
103
104
  } else if (params.isEditable) {
104
105
  let reason;
105
106
 
107
+ if (event.key === ' ' && event.shiftKey) {
108
+ return; // Shift + Space is used to select the row
109
+ }
110
+
106
111
  if (isPrintableKey(event)) {
107
112
  reason = GridCellEditStartReasons.printableKeyDown;
108
113
  } else if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
@@ -185,7 +190,7 @@ export const useGridCellEditing = (apiRef, props) => {
185
190
  const isEditing = editingState[id] && editingState[id][field];
186
191
  return isEditing ? GridCellModes.Edit : GridCellModes.View;
187
192
  }, [apiRef]);
188
- const updateCellModesModel = React.useCallback(newModel => {
193
+ const updateCellModesModel = useEventCallback(newModel => {
189
194
  const isNewModelDifferentFromProp = newModel !== props.cellModesModel;
190
195
 
191
196
  if (onCellModesModelChange && isNewModelDifferentFromProp) {
@@ -202,7 +207,7 @@ export const useGridCellEditing = (apiRef, props) => {
202
207
  setCellModesModel(newModel);
203
208
  cellModesModelRef.current = newModel;
204
209
  apiRef.current.publishEvent('cellModesModelChange', newModel);
205
- }, [apiRef, onCellModesModelChange, props.cellModesModel, signature]);
210
+ });
206
211
  const updateFieldInCellModesModel = React.useCallback((id, field, newProps) => {
207
212
  // We use the ref because it always contain the up-to-date value, different from the state
208
213
  // that needs a rerender to reflect the new value
@@ -261,7 +266,7 @@ export const useGridCellEditing = (apiRef, props) => {
261
266
  mode: GridCellModes.Edit
262
267
  }, other));
263
268
  }, [throwIfNotEditable, throwIfNotInMode, updateFieldInCellModesModel]);
264
- const updateStateToStartCellEditMode = React.useCallback(params => {
269
+ const updateStateToStartCellEditMode = useEventCallback(params => {
265
270
  const {
266
271
  id,
267
272
  field,
@@ -274,7 +279,7 @@ export const useGridCellEditing = (apiRef, props) => {
274
279
  };
275
280
  updateOrDeleteFieldState(id, field, newProps);
276
281
  apiRef.current.setCellFocus(id, field);
277
- }, [apiRef, updateOrDeleteFieldState]);
282
+ });
278
283
  const stopCellEditMode = React.useCallback(params => {
279
284
  const {
280
285
  id,
@@ -287,7 +292,7 @@ export const useGridCellEditing = (apiRef, props) => {
287
292
  mode: GridCellModes.View
288
293
  }, other));
289
294
  }, [throwIfNotInMode, updateFieldInCellModesModel]);
290
- const updateStateToStopCellEditMode = React.useCallback(async params => {
295
+ const updateStateToStopCellEditMode = useEventCallback(async params => {
291
296
  const {
292
297
  id,
293
298
  field,
@@ -332,7 +337,11 @@ export const useGridCellEditing = (apiRef, props) => {
332
337
 
333
338
  if (processRowUpdate) {
334
339
  const handleError = errorThrown => {
335
- prevCellModesModel.current[id][field].mode = GridCellModes.Edit;
340
+ prevCellModesModel.current[id][field].mode = GridCellModes.Edit; // Revert the mode in the cellModesModel prop back to "edit"
341
+
342
+ updateFieldInCellModesModel(id, field, {
343
+ mode: GridCellModes.Edit
344
+ });
336
345
 
337
346
  if (onProcessRowUpdateError) {
338
347
  onProcessRowUpdateError(errorThrown);
@@ -354,7 +363,7 @@ export const useGridCellEditing = (apiRef, props) => {
354
363
  apiRef.current.updateRows([rowUpdate]);
355
364
  finishCellEditMode();
356
365
  }
357
- }, [apiRef, onProcessRowUpdateError, processRowUpdate, throwIfNotInMode, updateFieldInCellModesModel, updateOrDeleteFieldState]);
366
+ });
358
367
  const setCellEditingEditCellValue = React.useCallback(async params => {
359
368
  const {
360
369
  id,
@@ -440,7 +449,7 @@ export const useGridCellEditing = (apiRef, props) => {
440
449
  }
441
450
  }, [cellModesModelProp, updateCellModesModel]);
442
451
  React.useEffect(() => {
443
- const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopCellEditMode may change it later
452
+ const idToIdLookup = gridRowsDataRowIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopCellEditMode may change it later
444
453
 
445
454
  const copyOfPrevCellModes = prevCellModesModel.current;
446
455
  prevCellModesModel.current = deepClone(cellModesModel); // Do a deep-clone because the attributes might be changed later
@@ -5,6 +5,7 @@ import { useGridCellEditing } from './useGridCellEditing.new';
5
5
  import { GridCellModes, GridEditModes } from '../../../models/gridEditRowModel';
6
6
  import { useGridRowEditing } from './useGridRowEditing.new';
7
7
  import { gridEditRowsStateSelector } from './gridEditRowsSelector';
8
+ import { isAutoGeneratedRow } from '../rows/gridRowsUtils';
8
9
  export const editingStateInitializer = state => _extends({}, state, {
9
10
  editRows: {}
10
11
  });
@@ -16,7 +17,7 @@ export const useGridEditing = (apiRef, props) => {
16
17
  isCellEditable: isCellEditableProp
17
18
  } = props;
18
19
  const isCellEditable = React.useCallback(params => {
19
- if (params.rowNode.isAutoGenerated) {
20
+ if (isAutoGeneratedRow(params.rowNode)) {
20
21
  return false;
21
22
  }
22
23
 
@@ -32,7 +33,7 @@ export const useGridEditing = (apiRef, props) => {
32
33
  return isCellEditableProp(params);
33
34
  }
34
35
 
35
- if (params.rowNode.isPinned) {
36
+ if (params.rowNode.type === 'pinnedRow') {
36
37
  return false;
37
38
  }
38
39
 
@@ -7,6 +7,7 @@ import { useGridLogger } from '../../utils/useGridLogger';
7
7
  import { gridEditRowsStateSelector } from './gridEditRowsSelector';
8
8
  import { useCellEditing } from './useGridCellEditing.old';
9
9
  import { useGridRowEditing } from './useGridRowEditing.old';
10
+ import { isAutoGeneratedRow } from '../rows/gridRowsUtils';
10
11
  export const editingStateInitializer = state => _extends({}, state, {
11
12
  editRows: {}
12
13
  });
@@ -28,7 +29,7 @@ export function useGridEditing(apiRef, props) {
28
29
  stateSelector: gridEditRowsStateSelector,
29
30
  changeEvent: 'editRowsModelChange'
30
31
  });
31
- const isCellEditable = React.useCallback(params => !params.rowNode.isAutoGenerated && !params.rowNode.isPinned && !!params.colDef.editable && !!params.colDef.renderEditCell && (!props.isCellEditable || props.isCellEditable(params)), // eslint-disable-next-line react-hooks/exhaustive-deps
32
+ const isCellEditable = React.useCallback(params => !isAutoGeneratedRow(params.rowNode) && params.rowNode.type !== 'pinnedRow' && !!params.colDef.editable && !!params.colDef.renderEditCell && (!props.isCellEditable || props.isCellEditable(params)), // eslint-disable-next-line react-hooks/exhaustive-deps
32
33
  [props.isCellEditable]);
33
34
 
34
35
  const maybeDebounce = (id, field, debounceMs, callback) => {
@@ -4,6 +4,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  const _excluded = ["id"],
5
5
  _excluded2 = ["id"];
6
6
  import * as React from 'react';
7
+ import { unstable_useEventCallback as useEventCallback } from '@mui/utils';
7
8
  import { useGridApiEventHandler, useGridApiOptionHandler, GridSignature } from '../../utils/useGridApiEventHandler';
8
9
  import { GridEditModes, GridRowModes } from '../../../models/gridEditRowModel';
9
10
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
@@ -11,7 +12,7 @@ import { gridEditRowsStateSelector } from './gridEditRowsSelector';
11
12
  import { isPrintableKey } from '../../../utils/keyboardUtils';
12
13
  import { gridColumnFieldsSelector } from '../columns/gridColumnsSelector';
13
14
  import { buildWarning } from '../../../utils/warning';
14
- import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
15
+ import { gridRowsDataRowIdToIdLookupSelector } from '../rows/gridRowsSelector';
15
16
  import { deepClone } from '../../../utils/utils';
16
17
  import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models/params/gridRowParams';
17
18
  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');
@@ -158,6 +159,10 @@ export const useGridRowEditing = (apiRef, props) => {
158
159
  } else if (params.isEditable) {
159
160
  let reason;
160
161
 
162
+ if (event.key === ' ' && event.shiftKey) {
163
+ return; // Shift + Space is used to select the row
164
+ }
165
+
161
166
  if (isPrintableKey(event)) {
162
167
  reason = GridRowEditStartReasons.printableKeyDown;
163
168
  } else if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
@@ -250,7 +255,7 @@ export const useGridRowEditing = (apiRef, props) => {
250
255
  const isEditing = editingState[id] && Object.keys(editingState[id]).length > 0;
251
256
  return isEditing ? GridRowModes.Edit : GridRowModes.View;
252
257
  }, [apiRef, props.editMode]);
253
- const updateRowModesModel = React.useCallback(newModel => {
258
+ const updateRowModesModel = useEventCallback(newModel => {
254
259
  const isNewModelDifferentFromProp = newModel !== props.rowModesModel;
255
260
 
256
261
  if (onRowModesModelChange && isNewModelDifferentFromProp) {
@@ -267,7 +272,7 @@ export const useGridRowEditing = (apiRef, props) => {
267
272
  setRowModesModel(newModel);
268
273
  rowModesModelRef.current = newModel;
269
274
  apiRef.current.publishEvent('rowModesModelChange', newModel);
270
- }, [apiRef, onRowModesModelChange, props.rowModesModel, signature]);
275
+ });
271
276
  const updateRowInRowModesModel = React.useCallback((id, newProps) => {
272
277
  const newModel = _extends({}, rowModesModelRef.current);
273
278
 
@@ -328,7 +333,7 @@ export const useGridRowEditing = (apiRef, props) => {
328
333
  mode: GridRowModes.Edit
329
334
  }, other));
330
335
  }, [throwIfNotInMode, updateRowInRowModesModel]);
331
- const updateStateToStartRowEditMode = React.useCallback(params => {
336
+ const updateStateToStartRowEditMode = useEventCallback(params => {
332
337
  const {
333
338
  id,
334
339
  fieldToFocus,
@@ -355,7 +360,7 @@ export const useGridRowEditing = (apiRef, props) => {
355
360
  if (fieldToFocus) {
356
361
  apiRef.current.setCellFocus(id, fieldToFocus);
357
362
  }
358
- }, [apiRef, updateOrDeleteRowState]);
363
+ });
359
364
  const stopRowEditMode = React.useCallback(params => {
360
365
  const {
361
366
  id
@@ -367,7 +372,7 @@ export const useGridRowEditing = (apiRef, props) => {
367
372
  mode: GridRowModes.View
368
373
  }, other));
369
374
  }, [throwIfNotInMode, updateRowInRowModesModel]);
370
- const updateStateToStopRowEditMode = React.useCallback(params => {
375
+ const updateStateToStopRowEditMode = useEventCallback(params => {
371
376
  const {
372
377
  id,
373
378
  ignoreModifications,
@@ -414,7 +419,11 @@ export const useGridRowEditing = (apiRef, props) => {
414
419
 
415
420
  if (processRowUpdate) {
416
421
  const handleError = errorThrown => {
417
- prevRowModesModel.current[id].mode = GridRowModes.Edit;
422
+ prevRowModesModel.current[id].mode = GridRowModes.Edit; // Revert the mode in the rowModesModel prop back to "edit"
423
+
424
+ updateRowInRowModesModel(id, {
425
+ mode: GridRowModes.Edit
426
+ });
418
427
 
419
428
  if (onProcessRowUpdateError) {
420
429
  onProcessRowUpdateError(errorThrown);
@@ -435,7 +444,7 @@ export const useGridRowEditing = (apiRef, props) => {
435
444
  apiRef.current.updateRows([rowUpdate]);
436
445
  finishRowEditMode();
437
446
  }
438
- }, [apiRef, onProcessRowUpdateError, processRowUpdate, updateOrDeleteRowState, updateRowInRowModesModel]);
447
+ });
439
448
  const setRowEditingEditCellValue = React.useCallback(params => {
440
449
  const {
441
450
  id,
@@ -589,7 +598,7 @@ export const useGridRowEditing = (apiRef, props) => {
589
598
  }
590
599
  }, [rowModesModelProp, updateRowModesModel]);
591
600
  React.useEffect(() => {
592
- const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopRowEditMode may change it later
601
+ const idToIdLookup = gridRowsDataRowIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopRowEditMode may change it later
593
602
 
594
603
  const copyOfPrevRowModesModel = prevRowModesModel.current;
595
604
  prevRowModesModel.current = deepClone(rowModesModel); // Do a deep-clone because the attributes might be changed later
@@ -13,6 +13,14 @@ import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
13
13
  import { GridPrintExportMenuItem } from '../../../components/toolbar/GridToolbarExport';
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
 
16
+ function raf() {
17
+ return new Promise(resolve => {
18
+ requestAnimationFrame(() => {
19
+ resolve();
20
+ });
21
+ });
22
+ }
23
+
16
24
  /**
17
25
  * @requires useGridColumns (state)
18
26
  * @requires useGridFilter (state)
@@ -30,6 +38,7 @@ export const useGridPrintExport = (apiRef, props) => {
30
38
  // the new state needs to be in place before the grid can be sized correctly
31
39
 
32
40
  const updateGridColumnsForPrint = React.useCallback((fields, allColumns) => new Promise(resolve => {
41
+ // TODO remove unused Promise
33
42
  if (!fields && !allColumns) {
34
43
  resolve();
35
44
  return;
@@ -49,12 +58,10 @@ export const useGridPrintExport = (apiRef, props) => {
49
58
  });
50
59
  apiRef.current.setColumnVisibilityModel(newColumnVisibilityModel);
51
60
  resolve();
52
- }), [apiRef]);
61
+ }), [apiRef]); // TODO move outside of this scope and remove React.useCallback
62
+
53
63
  const buildPrintWindow = React.useCallback(title => {
54
64
  const iframeEl = document.createElement('iframe');
55
- iframeEl.id = 'grid-print-window'; // Without this 'onload' event won't fire in some browsers
56
-
57
- iframeEl.src = window.location.href;
58
65
  iframeEl.style.position = 'absolute';
59
66
  iframeEl.style.width = '0px';
60
67
  iframeEl.style.height = '0px';
@@ -66,12 +73,9 @@ export const useGridPrintExport = (apiRef, props) => {
66
73
  copyStyles: true,
67
74
  hideToolbar: false,
68
75
  hideFooter: false
69
- }, options); // Some agents, such as IE11 and Enzyme (as of 2 Jun 2020) continuously call the
70
- // `onload` callback. This ensures that it is only called once.
76
+ }, options);
71
77
 
72
-
73
- printWindow.onload = null;
74
- const printDoc = printWindow.contentDocument || printWindow.contentWindow?.document;
78
+ const printDoc = printWindow.contentDocument;
75
79
 
76
80
  if (!printDoc) {
77
81
  return;
@@ -107,10 +111,12 @@ export const useGridPrintExport = (apiRef, props) => {
107
111
  } // Expand container height to accommodate all rows
108
112
 
109
113
 
110
- gridClone.style.height = `${rowsMeta.currentPageTotalHeight + totalHeaderHeight + gridToolbarElementHeight + gridFooterElementHeight}px`; // Remove all loaded elements from the current host
114
+ gridClone.style.height = `${rowsMeta.currentPageTotalHeight + totalHeaderHeight + gridToolbarElementHeight + gridFooterElementHeight}px`; // printDoc.body.appendChild(gridClone); should be enough but a clone isolation bug in Safari
115
+ // prevents us to do it
111
116
 
112
- printDoc.body.innerHTML = '';
113
- printDoc.body.appendChild(gridClone);
117
+ const container = document.createElement('div');
118
+ container.appendChild(gridClone);
119
+ printDoc.body.innerHTML = container.innerHTML;
114
120
  const defaultPageStyle = typeof normalizeOptions.pageStyle === 'function' ? normalizeOptions.pageStyle() : normalizeOptions.pageStyle;
115
121
 
116
122
  if (typeof defaultPageStyle === 'string') {
@@ -202,17 +208,25 @@ export const useGridPrintExport = (apiRef, props) => {
202
208
 
203
209
  await updateGridColumnsForPrint(options?.fields, options?.allColumns);
204
210
  apiRef.current.unstable_disableVirtualization();
211
+ await raf(); // wait for the state changes to take action
212
+
205
213
  const printWindow = buildPrintWindow(options?.fileName);
206
- doc.current.body.appendChild(printWindow);
207
214
 
208
215
  if (process.env.NODE_ENV === 'test') {
209
- // In test env, run the all pipeline without waiting for loading
216
+ doc.current.body.appendChild(printWindow); // In test env, run the all pipeline without waiting for loading
217
+
210
218
  handlePrintWindowLoad(printWindow, options);
211
219
  handlePrintWindowAfterPrint(printWindow);
212
220
  } else {
213
- printWindow.onload = () => handlePrintWindowLoad(printWindow, options);
221
+ printWindow.onload = () => {
222
+ handlePrintWindowLoad(printWindow, options);
223
+
224
+ printWindow.contentWindow.onafterprint = () => {
225
+ handlePrintWindowAfterPrint(printWindow);
226
+ };
227
+ };
214
228
 
215
- printWindow.contentWindow.onafterprint = () => handlePrintWindowAfterPrint(printWindow);
229
+ doc.current.body.appendChild(printWindow);
216
230
  }
217
231
  }, [props, logger, apiRef, buildPrintWindow, handlePrintWindowLoad, handlePrintWindowAfterPrint, updateGridColumnsForPrint]);
218
232
  const printExportApi = {
@@ -20,7 +20,7 @@ export const defaultGetRowsToExport = ({
20
20
  const filteredSortedRowIds = gridFilteredSortedRowIdsSelector(apiRef);
21
21
  const rowTree = gridRowTreeSelector(apiRef);
22
22
  const selectedRows = apiRef.current.getSelectedRows();
23
- const bodyRows = filteredSortedRowIds.filter(id => (rowTree[id].position ?? 'body') === 'body');
23
+ const bodyRows = filteredSortedRowIds.filter(id => rowTree[id].type !== 'footer');
24
24
  const pinnedRows = gridPinnedRowsSelector(apiRef);
25
25
  const topPinnedRowsIds = pinnedRows?.top?.map(row => row.id) || [];
26
26
  const bottomPinnedRowsIds = pinnedRows?.bottom?.map(row => row.id) || [];
@@ -1,7 +1,7 @@
1
1
  import { createSelector } from '../../../utils/createSelector';
2
2
  import { gridSortedRowEntriesSelector } from '../sorting/gridSortingSelector';
3
3
  import { gridColumnLookupSelector } from '../columns/gridColumnsSelector';
4
- import { gridRowTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
4
+ import { gridRowMaximumTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
5
5
  /**
6
6
  * @category Filtering
7
7
  */
@@ -78,7 +78,7 @@ export const gridVisibleRowsSelector = gridVisibleSortedRowIdsSelector;
78
78
  * @category Filtering
79
79
  */
80
80
 
81
- export const gridVisibleSortedTopLevelRowEntriesSelector = createSelector(gridVisibleSortedRowEntriesSelector, gridRowTreeSelector, gridRowTreeDepthSelector, (visibleSortedRows, rowTree, rowTreeDepth) => {
81
+ export const gridVisibleSortedTopLevelRowEntriesSelector = createSelector(gridVisibleSortedRowEntriesSelector, gridRowTreeSelector, gridRowMaximumTreeDepthSelector, (visibleSortedRows, rowTree, rowTreeDepth) => {
82
82
  if (rowTreeDepth < 2) {
83
83
  return visibleSortedRows;
84
84
  }