@mui/x-data-grid 5.8.0 → 5.9.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 (242) hide show
  1. package/CHANGELOG.md +141 -63
  2. package/DataGrid/DataGrid.js +1 -1
  3. package/DataGrid/useDataGridComponent.js +3 -1
  4. package/LICENSE +21 -0
  5. package/README.md +1 -1
  6. package/components/GridRow.d.ts +4 -0
  7. package/components/GridRow.js +49 -23
  8. package/components/base/GridOverlays.js +4 -3
  9. package/components/cell/GridActionsCell.d.ts +5 -1
  10. package/components/cell/GridActionsCell.js +170 -21
  11. package/components/cell/GridActionsCellItem.d.ts +66 -4
  12. package/components/cell/GridActionsCellItem.js +7 -5
  13. package/components/cell/GridCell.d.ts +1 -0
  14. package/components/cell/GridCell.js +28 -7
  15. package/components/cell/GridEditInputCell.js +1 -1
  16. package/components/cell/GridEditSingleSelectCell.js +22 -13
  17. package/components/columnHeaders/GridColumnHeaderItem.js +4 -7
  18. package/components/columnHeaders/GridColumnHeaders.d.ts +0 -1
  19. package/components/columnHeaders/GridColumnHeaders.js +1 -1
  20. package/components/columnSelection/GridCellCheckboxRenderer.d.ts +3 -3
  21. package/components/columnSelection/GridCellCheckboxRenderer.js +20 -3
  22. package/components/panel/GridPanel.js +1 -0
  23. package/components/panel/filterPanel/GridFilterForm.js +14 -10
  24. package/components/panel/filterPanel/GridFilterInputBoolean.js +13 -8
  25. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +22 -15
  26. package/components/panel/filterPanel/GridFilterInputValue.js +22 -15
  27. package/components/toolbar/GridToolbarDensitySelector.js +1 -1
  28. package/components/toolbar/GridToolbarFilterButton.d.ts +1 -1
  29. package/components/virtualization/GridVirtualScroller.js +2 -0
  30. package/components/virtualization/GridVirtualScrollerContent.js +1 -3
  31. package/constants/gridDetailPanelToggleField.d.ts +1 -0
  32. package/constants/gridDetailPanelToggleField.js +2 -0
  33. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +32 -15
  34. package/hooks/core/pipeProcessing/index.d.ts +1 -0
  35. package/hooks/core/pipeProcessing/index.js +2 -1
  36. package/hooks/core/pipeProcessing/useGridPipeProcessing.d.ts +8 -3
  37. package/hooks/core/pipeProcessing/useGridPipeProcessing.js +53 -19
  38. package/hooks/core/pipeProcessing/useGridRegisterPipeApplier.d.ts +3 -0
  39. package/hooks/core/pipeProcessing/useGridRegisterPipeApplier.js +27 -0
  40. package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.d.ts +0 -3
  41. package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +0 -4
  42. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +0 -1
  43. package/hooks/features/columnHeaders/useGridColumnHeaders.js +76 -10
  44. package/hooks/features/columns/gridColumnsInterfaces.d.ts +3 -1
  45. package/hooks/features/columns/gridColumnsUtils.d.ts +19 -1
  46. package/hooks/features/columns/gridColumnsUtils.js +61 -8
  47. package/hooks/features/columns/useGridColumnSpanning.d.ts +7 -0
  48. package/hooks/features/columns/useGridColumnSpanning.js +109 -0
  49. package/hooks/features/columns/useGridColumns.js +24 -18
  50. package/hooks/features/dimensions/useGridDimensions.js +3 -3
  51. package/hooks/features/editRows/useGridCellEditing.new.js +18 -10
  52. package/hooks/features/editRows/useGridEditing.new.js +7 -3
  53. package/hooks/features/editRows/useGridRowEditing.new.js +23 -15
  54. package/hooks/features/filter/useGridFilter.js +14 -9
  55. package/hooks/features/focus/useGridFocus.js +19 -9
  56. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -0
  57. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +39 -7
  58. package/hooks/features/rows/gridRowsSelector.d.ts +1 -0
  59. package/hooks/features/rows/gridRowsSelector.js +1 -0
  60. package/hooks/features/rows/gridRowsState.d.ts +4 -0
  61. package/hooks/features/rows/useGridRows.d.ts +2 -2
  62. package/hooks/features/rows/useGridRows.js +5 -4
  63. package/hooks/features/rows/useGridRowsMeta.js +6 -13
  64. package/hooks/features/scroll/useGridScroll.d.ts +2 -0
  65. package/hooks/features/scroll/useGridScroll.js +25 -3
  66. package/hooks/features/selection/useGridSelection.js +3 -2
  67. package/hooks/features/sorting/useGridSorting.js +10 -10
  68. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +7 -0
  69. package/hooks/features/virtualization/useGridVirtualScroller.js +54 -27
  70. package/index.js +1 -1
  71. package/internals/index.d.ts +1 -0
  72. package/internals/index.js +1 -0
  73. package/legacy/DataGrid/DataGrid.js +1 -1
  74. package/legacy/DataGrid/useDataGridComponent.js +3 -1
  75. package/legacy/components/GridRow.js +47 -23
  76. package/legacy/components/base/GridOverlays.js +4 -3
  77. package/legacy/components/cell/GridActionsCell.js +188 -27
  78. package/legacy/components/cell/GridActionsCellItem.js +7 -5
  79. package/legacy/components/cell/GridCell.js +29 -7
  80. package/legacy/components/cell/GridEditInputCell.js +1 -1
  81. package/legacy/components/cell/GridEditSingleSelectCell.js +33 -24
  82. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +4 -7
  83. package/legacy/components/columnHeaders/GridColumnHeaders.js +2 -3
  84. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +21 -3
  85. package/legacy/components/panel/GridPanel.js +1 -0
  86. package/legacy/components/panel/filterPanel/GridFilterForm.js +14 -10
  87. package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +13 -8
  88. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +22 -17
  89. package/legacy/components/panel/filterPanel/GridFilterInputValue.js +22 -17
  90. package/legacy/components/toolbar/GridToolbarDensitySelector.js +1 -1
  91. package/legacy/components/virtualization/GridVirtualScroller.js +2 -0
  92. package/legacy/components/virtualization/GridVirtualScrollerContent.js +1 -3
  93. package/legacy/constants/gridDetailPanelToggleField.js +2 -0
  94. package/legacy/hooks/core/pipeProcessing/index.js +2 -1
  95. package/legacy/hooks/core/pipeProcessing/useGridPipeProcessing.js +60 -24
  96. package/legacy/hooks/core/pipeProcessing/useGridRegisterPipeApplier.js +27 -0
  97. package/legacy/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +0 -4
  98. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +89 -10
  99. package/legacy/hooks/features/columns/gridColumnsUtils.js +79 -22
  100. package/legacy/hooks/features/columns/useGridColumnSpanning.js +107 -0
  101. package/legacy/hooks/features/columns/useGridColumns.js +24 -18
  102. package/legacy/hooks/features/dimensions/useGridDimensions.js +3 -3
  103. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +14 -8
  104. package/legacy/hooks/features/editRows/useGridEditing.new.js +7 -3
  105. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +32 -24
  106. package/legacy/hooks/features/filter/useGridFilter.js +14 -9
  107. package/legacy/hooks/features/focus/useGridFocus.js +19 -9
  108. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +39 -6
  109. package/legacy/hooks/features/rows/gridRowsSelector.js +3 -0
  110. package/legacy/hooks/features/rows/useGridRows.js +5 -4
  111. package/legacy/hooks/features/rows/useGridRowsMeta.js +6 -13
  112. package/legacy/hooks/features/scroll/useGridScroll.js +25 -3
  113. package/legacy/hooks/features/selection/useGridSelection.js +3 -2
  114. package/legacy/hooks/features/sorting/useGridSorting.js +5 -7
  115. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +65 -37
  116. package/legacy/index.js +1 -1
  117. package/legacy/internals/index.js +1 -0
  118. package/legacy/locales/huHU.js +120 -0
  119. package/legacy/locales/index.js +1 -0
  120. package/legacy/models/api/gridColumnSpanning.js +1 -0
  121. package/legacy/models/events/gridEvents.js +2 -3
  122. package/legacy/models/gridColumnSpanning.js +1 -0
  123. package/locales/huHU.d.ts +2 -0
  124. package/locales/huHU.js +108 -0
  125. package/locales/index.d.ts +1 -0
  126. package/locales/index.js +1 -0
  127. package/models/api/gridApiCommon.d.ts +2 -1
  128. package/models/api/gridColumnSpanning.d.ts +28 -0
  129. package/models/api/gridColumnSpanning.js +1 -0
  130. package/models/api/gridEditingApi.d.ts +49 -3
  131. package/models/colDef/gridColDef.d.ts +5 -0
  132. package/models/events/gridEventLookup.d.ts +3 -8
  133. package/models/events/gridEvents.d.ts +9 -14
  134. package/models/events/gridEvents.js +2 -3
  135. package/models/gridColumnSpanning.d.ts +12 -0
  136. package/models/gridColumnSpanning.js +1 -0
  137. package/models/gridEditRowModel.d.ts +1 -1
  138. package/models/params/gridCellParams.d.ts +12 -2
  139. package/models/params/gridRowParams.d.ts +5 -0
  140. package/models/props/DataGridProps.d.ts +1 -1
  141. package/modern/DataGrid/DataGrid.js +1 -1
  142. package/modern/DataGrid/useDataGridComponent.js +3 -1
  143. package/modern/components/GridRow.js +47 -21
  144. package/modern/components/base/GridOverlays.js +4 -3
  145. package/modern/components/cell/GridActionsCell.js +168 -21
  146. package/modern/components/cell/GridActionsCellItem.js +7 -5
  147. package/modern/components/cell/GridCell.js +28 -7
  148. package/modern/components/cell/GridEditInputCell.js +1 -1
  149. package/modern/components/cell/GridEditSingleSelectCell.js +20 -11
  150. package/modern/components/columnHeaders/GridColumnHeaderItem.js +4 -7
  151. package/modern/components/columnHeaders/GridColumnHeaders.js +1 -1
  152. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +20 -3
  153. package/modern/components/panel/GridPanel.js +1 -0
  154. package/modern/components/panel/filterPanel/GridFilterForm.js +10 -6
  155. package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +11 -6
  156. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +20 -13
  157. package/modern/components/panel/filterPanel/GridFilterInputValue.js +20 -13
  158. package/modern/components/toolbar/GridToolbarDensitySelector.js +1 -1
  159. package/modern/components/virtualization/GridVirtualScroller.js +2 -0
  160. package/modern/components/virtualization/GridVirtualScrollerContent.js +1 -3
  161. package/modern/constants/gridDetailPanelToggleField.js +2 -0
  162. package/modern/hooks/core/pipeProcessing/index.js +2 -1
  163. package/modern/hooks/core/pipeProcessing/useGridPipeProcessing.js +53 -19
  164. package/modern/hooks/core/pipeProcessing/useGridRegisterPipeApplier.js +27 -0
  165. package/modern/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +0 -4
  166. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +76 -10
  167. package/modern/hooks/features/columns/gridColumnsUtils.js +61 -8
  168. package/modern/hooks/features/columns/useGridColumnSpanning.js +107 -0
  169. package/modern/hooks/features/columns/useGridColumns.js +24 -18
  170. package/modern/hooks/features/dimensions/useGridDimensions.js +3 -3
  171. package/modern/hooks/features/editRows/useGridCellEditing.new.js +18 -10
  172. package/modern/hooks/features/editRows/useGridEditing.new.js +7 -3
  173. package/modern/hooks/features/editRows/useGridRowEditing.new.js +23 -15
  174. package/modern/hooks/features/filter/useGridFilter.js +14 -9
  175. package/modern/hooks/features/focus/useGridFocus.js +19 -9
  176. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +37 -7
  177. package/modern/hooks/features/rows/gridRowsSelector.js +1 -0
  178. package/modern/hooks/features/rows/useGridRows.js +5 -4
  179. package/modern/hooks/features/rows/useGridRowsMeta.js +6 -13
  180. package/modern/hooks/features/scroll/useGridScroll.js +23 -3
  181. package/modern/hooks/features/selection/useGridSelection.js +3 -2
  182. package/modern/hooks/features/sorting/useGridSorting.js +10 -10
  183. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +54 -23
  184. package/modern/index.js +1 -1
  185. package/modern/internals/index.js +1 -0
  186. package/modern/locales/huHU.js +108 -0
  187. package/modern/locales/index.js +1 -0
  188. package/modern/models/api/gridColumnSpanning.js +1 -0
  189. package/modern/models/events/gridEvents.js +2 -3
  190. package/modern/models/gridColumnSpanning.js +1 -0
  191. package/node/DataGrid/DataGrid.js +1 -1
  192. package/node/DataGrid/useDataGridComponent.js +4 -1
  193. package/node/components/GridRow.js +50 -23
  194. package/node/components/base/GridOverlays.js +3 -2
  195. package/node/components/cell/GridActionsCell.js +172 -21
  196. package/node/components/cell/GridActionsCellItem.js +7 -4
  197. package/node/components/cell/GridCell.js +28 -7
  198. package/node/components/cell/GridEditInputCell.js +1 -1
  199. package/node/components/cell/GridEditSingleSelectCell.js +23 -13
  200. package/node/components/columnHeaders/GridColumnHeaderItem.js +4 -7
  201. package/node/components/columnHeaders/GridColumnHeaders.js +1 -1
  202. package/node/components/columnSelection/GridCellCheckboxRenderer.js +20 -3
  203. package/node/components/panel/GridPanel.js +1 -0
  204. package/node/components/panel/filterPanel/GridFilterForm.js +15 -10
  205. package/node/components/panel/filterPanel/GridFilterInputBoolean.js +14 -8
  206. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +23 -15
  207. package/node/components/panel/filterPanel/GridFilterInputValue.js +23 -15
  208. package/node/components/toolbar/GridToolbarDensitySelector.js +1 -1
  209. package/node/components/virtualization/GridVirtualScroller.js +2 -0
  210. package/node/components/virtualization/GridVirtualScrollerContent.js +1 -3
  211. package/node/constants/gridDetailPanelToggleField.js +9 -0
  212. package/node/hooks/core/pipeProcessing/index.js +13 -0
  213. package/node/hooks/core/pipeProcessing/useGridPipeProcessing.js +51 -20
  214. package/node/hooks/core/pipeProcessing/useGridRegisterPipeApplier.js +42 -0
  215. package/node/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +0 -3
  216. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +80 -10
  217. package/node/hooks/features/columns/gridColumnsUtils.js +65 -9
  218. package/node/hooks/features/columns/useGridColumnSpanning.js +130 -0
  219. package/node/hooks/features/columns/useGridColumns.js +23 -17
  220. package/node/hooks/features/dimensions/useGridDimensions.js +3 -3
  221. package/node/hooks/features/editRows/useGridCellEditing.new.js +18 -10
  222. package/node/hooks/features/editRows/useGridEditing.new.js +6 -2
  223. package/node/hooks/features/editRows/useGridRowEditing.new.js +21 -14
  224. package/node/hooks/features/filter/useGridFilter.js +14 -9
  225. package/node/hooks/features/focus/useGridFocus.js +19 -9
  226. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +40 -7
  227. package/node/hooks/features/rows/gridRowsSelector.js +3 -1
  228. package/node/hooks/features/rows/useGridRows.js +5 -4
  229. package/node/hooks/features/rows/useGridRowsMeta.js +6 -14
  230. package/node/hooks/features/scroll/useGridScroll.js +26 -2
  231. package/node/hooks/features/selection/useGridSelection.js +4 -2
  232. package/node/hooks/features/sorting/useGridSorting.js +10 -10
  233. package/node/hooks/features/virtualization/useGridVirtualScroller.js +59 -27
  234. package/node/index.js +1 -1
  235. package/node/internals/index.js +8 -0
  236. package/node/locales/huHU.js +118 -0
  237. package/node/locales/index.js +13 -0
  238. package/node/models/api/gridColumnSpanning.js +5 -0
  239. package/node/models/events/gridEvents.js +2 -3
  240. package/node/models/gridColumnSpanning.js +5 -0
  241. package/package.json +4 -4
  242. package/utils/domUtils.d.ts +2 -2
@@ -11,8 +11,12 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
11
11
 
12
12
  var React = _interopRequireWildcard(require("react"));
13
13
 
14
+ var ReactDOM = _interopRequireWildcard(require("react-dom"));
15
+
14
16
  var _utils = require("@mui/material/utils");
15
17
 
18
+ var _reselect = require("reselect");
19
+
16
20
  var _useGridApiContext = require("../../utils/useGridApiContext");
17
21
 
18
22
  var _useGridSelector = require("../../utils/useGridSelector");
@@ -37,12 +41,22 @@ var _events = require("../../../models/events");
37
41
 
38
42
  var _GridColumnHeaderItem = require("../../../components/columnHeaders/GridColumnHeaderItem");
39
43
 
44
+ var _gridColumnsUtils = require("../columns/gridColumnsUtils");
45
+
46
+ var _useGridVisibleRows = require("../../utils/useGridVisibleRows");
47
+
48
+ var _useGridVirtualScroller = require("../virtualization/useGridVirtualScroller");
49
+
40
50
  var _jsxRuntime = require("react/jsx-runtime");
41
51
 
42
52
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
43
53
 
44
54
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
45
55
 
56
+ function isUIEvent(event) {
57
+ return !!event.target;
58
+ }
59
+
46
60
  const useGridColumnHeaders = props => {
47
61
  const {
48
62
  innerRef: innerRefProp,
@@ -66,18 +80,43 @@ const useGridColumnHeaders = props => {
66
80
  const [renderContext, setRenderContext] = React.useState(null);
67
81
  const prevRenderContext = React.useRef(renderContext);
68
82
  const prevScrollLeft = React.useRef(0);
83
+ const currentPage = (0, _useGridVisibleRows.useGridVisibleRows)(apiRef, rootProps);
69
84
  React.useEffect(() => {
70
85
  apiRef.current.columnHeadersContainerElementRef.current.scrollLeft = 0;
71
- }, [apiRef]);
86
+ }, [apiRef]); // memoize `getFirstColumnIndexToRender`, since it's called on scroll
87
+
88
+ const getFirstColumnIndexToRenderRef = React.useRef((0, _reselect.defaultMemoize)(_gridColumnsUtils.getFirstColumnIndexToRender, {
89
+ equalityCheck: (a, b) => ['firstColumnIndex', 'minColumnIndex', 'columnBuffer'].every(key => a[key] === b[key])
90
+ }));
72
91
  const updateInnerPosition = React.useCallback(nextRenderContext => {
73
- const firstColumnToRender = Math.max(nextRenderContext.firstColumnIndex - rootProps.columnBuffer, minColumnIndex);
92
+ const [firstRowToRender, lastRowToRender] = (0, _useGridVirtualScroller.getRenderableIndexes)({
93
+ firstIndex: nextRenderContext.firstRowIndex,
94
+ lastIndex: nextRenderContext.lastRowIndex,
95
+ minFirstIndex: 0,
96
+ maxLastIndex: currentPage.rows.length,
97
+ buffer: rootProps.rowBuffer
98
+ });
99
+ const firstColumnToRender = getFirstColumnIndexToRenderRef.current({
100
+ firstColumnIndex: nextRenderContext.firstColumnIndex,
101
+ minColumnIndex,
102
+ columnBuffer: rootProps.columnBuffer,
103
+ firstRowToRender,
104
+ lastRowToRender,
105
+ apiRef,
106
+ visibleRows: currentPage.rows
107
+ });
74
108
  const offset = firstColumnToRender > 0 ? prevScrollLeft.current - columnPositions[firstColumnToRender] : prevScrollLeft.current;
75
109
  innerRef.current.style.transform = `translate3d(${-offset}px, 0px, 0px)`;
76
- }, [columnPositions, minColumnIndex, rootProps.columnBuffer]);
110
+ }, [columnPositions, minColumnIndex, rootProps.columnBuffer, apiRef, currentPage.rows, rootProps.rowBuffer]);
111
+ React.useLayoutEffect(() => {
112
+ if (renderContext) {
113
+ updateInnerPosition(renderContext);
114
+ }
115
+ }, [renderContext, updateInnerPosition]);
77
116
  const handleScroll = React.useCallback(({
78
117
  left,
79
118
  renderContext: nextRenderContext = null
80
- }) => {
119
+ }, event) => {
81
120
  var _prevRenderContext$cu, _prevRenderContext$cu2;
82
121
 
83
122
  if (!innerRef.current) {
@@ -90,15 +129,32 @@ const useGridColumnHeaders = props => {
90
129
  return;
91
130
  }
92
131
 
93
- prevScrollLeft.current = left;
132
+ prevScrollLeft.current = left; // We can only update the position when we guarantee that the render context has been
133
+ // rendered. This is achieved using ReactDOM.flushSync or when the context doesn't change.
134
+
135
+ let canUpdateInnerPosition = false;
94
136
 
95
137
  if (nextRenderContext !== prevRenderContext.current || !prevRenderContext.current) {
96
- setRenderContext(nextRenderContext);
138
+ // ReactDOM.flushSync cannot be called on `scroll` events fired inside effects
139
+ if (isUIEvent(event)) {
140
+ // To prevent flickering, the inner position can only be updated after the new context has
141
+ // been rendered. ReactDOM.flushSync ensures that the state changes will happen before
142
+ // updating the position.
143
+ ReactDOM.flushSync(() => {
144
+ setRenderContext(nextRenderContext);
145
+ });
146
+ canUpdateInnerPosition = true;
147
+ } else {
148
+ setRenderContext(nextRenderContext);
149
+ }
150
+
97
151
  prevRenderContext.current = nextRenderContext;
152
+ } else {
153
+ canUpdateInnerPosition = true;
98
154
  } // Pass directly the render context to avoid waiting for the next render
99
155
 
100
156
 
101
- if (nextRenderContext) {
157
+ if (nextRenderContext && canUpdateInnerPosition) {
102
158
  updateInnerPosition(nextRenderContext);
103
159
  }
104
160
  }, [updateInnerPosition]);
@@ -124,7 +180,22 @@ const useGridColumnHeaders = props => {
124
180
  }
125
181
 
126
182
  const columns = [];
127
- const firstColumnToRender = Math.max(nextRenderContext.firstColumnIndex - rootProps.columnBuffer, minFirstColumn);
183
+ const [firstRowToRender, lastRowToRender] = (0, _useGridVirtualScroller.getRenderableIndexes)({
184
+ firstIndex: nextRenderContext.firstRowIndex,
185
+ lastIndex: nextRenderContext.lastRowIndex,
186
+ minFirstIndex: 0,
187
+ maxLastIndex: currentPage.rows.length,
188
+ buffer: rootProps.rowBuffer
189
+ });
190
+ const firstColumnToRender = getFirstColumnIndexToRenderRef.current({
191
+ firstColumnIndex: nextRenderContext.firstColumnIndex,
192
+ minColumnIndex: minFirstColumn,
193
+ columnBuffer: rootProps.columnBuffer,
194
+ apiRef,
195
+ firstRowToRender,
196
+ lastRowToRender,
197
+ visibleRows: currentPage.rows
198
+ });
128
199
  const lastColumnToRender = Math.min(nextRenderContext.lastColumnIndex + rootProps.columnBuffer, maxLastColumn);
129
200
  const renderedColumns = visibleColumns.slice(firstColumnToRender, lastColumnToRender);
130
201
 
@@ -148,7 +219,7 @@ const useGridColumnHeaders = props => {
148
219
  extendRowFullWidth: !rootProps.disableExtendRowFullWidth,
149
220
  hasFocus: hasFocus,
150
221
  tabIndex: tabIndex
151
- }, other), i));
222
+ }, other), column.field));
152
223
  }
153
224
 
154
225
  return columns;
@@ -163,7 +234,6 @@ const useGridColumnHeaders = props => {
163
234
  renderContext,
164
235
  getColumns,
165
236
  isDragging: !!dragCol,
166
- updateInnerPosition,
167
237
  getRootProps: (other = {}) => (0, _extends2.default)({
168
238
  style: rootStyle
169
239
  }, other),
@@ -7,7 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.computeColumnTypes = exports.applyInitialState = exports.COLUMNS_DIMENSION_PROPERTIES = void 0;
9
9
  exports.computeFlexColumnsWidth = computeFlexColumnsWidth;
10
- exports.mergeColumnsState = exports.hydrateColumnsWidth = exports.getGridColDef = exports.createColumnsState = void 0;
10
+ exports.createColumnsState = void 0;
11
+ exports.getFirstColumnIndexToRender = getFirstColumnIndexToRender;
12
+ exports.getFirstNonSpannedColumnToRender = getFirstNonSpannedColumnToRender;
13
+ exports.mergeColumnsState = exports.hydrateColumnsWidth = exports.getGridColDef = void 0;
11
14
 
12
15
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
16
 
@@ -227,9 +230,13 @@ const applyInitialState = (columnsState, initialState) => {
227
230
 
228
231
  for (let i = 0; i < columnsWithUpdatedDimensions.length; i += 1) {
229
232
  const field = columnsWithUpdatedDimensions[i];
230
- newColumnLookup[field] = (0, _extends2.default)({}, newColumnLookup[field], dimensions[field], {
233
+ const newColDef = (0, _extends2.default)({}, newColumnLookup[field], {
231
234
  hasBeenResized: true
232
235
  });
236
+ Object.entries(dimensions[field]).forEach(([key, value]) => {
237
+ newColDef[key] = value === -1 ? Infinity : value;
238
+ });
239
+ newColumnLookup[field] = newColDef;
233
240
  }
234
241
 
235
242
  const newColumnsState = {
@@ -323,16 +330,20 @@ const createColumnsState = ({
323
330
  columnsStateWithoutColumnVisibilityModel.all.push(field);
324
331
  }
325
332
 
326
- let hasValidDimension = false;
327
-
328
- if (!existingState.hasBeenResized) {
329
- hasValidDimension = COLUMNS_DIMENSION_PROPERTIES.some(key => newColumn[key] !== undefined);
330
- }
333
+ let hasBeenResized = existingState.hasBeenResized;
334
+ COLUMNS_DIMENSION_PROPERTIES.forEach(key => {
335
+ if (newColumn[key] !== undefined) {
336
+ hasBeenResized = true;
331
337
 
338
+ if (newColumn[key] === -1) {
339
+ newColumn[key] = Infinity;
340
+ }
341
+ }
342
+ });
332
343
  columnsStateWithoutColumnVisibilityModel.lookup[field] = (0, _extends2.default)({}, existingState, {
333
344
  hide: newColumn.hide == null ? false : newColumn.hide
334
345
  }, newColumn, {
335
- hasBeenResized: existingState.hasBeenResized || hasValidDimension
346
+ hasBeenResized
336
347
  });
337
348
  });
338
349
 
@@ -422,4 +433,49 @@ const mergeColumnsState = columnsState => state => (0, _extends2.default)({}, st
422
433
  columns: columnsState
423
434
  });
424
435
 
425
- exports.mergeColumnsState = mergeColumnsState;
436
+ exports.mergeColumnsState = mergeColumnsState;
437
+
438
+ function getFirstNonSpannedColumnToRender({
439
+ firstColumnToRender,
440
+ apiRef,
441
+ firstRowToRender,
442
+ lastRowToRender,
443
+ visibleRows
444
+ }) {
445
+ let firstNonSpannedColumnToRender = firstColumnToRender;
446
+
447
+ for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
448
+ const row = visibleRows[i];
449
+
450
+ if (row) {
451
+ const rowId = visibleRows[i].id;
452
+ const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstColumnToRender);
453
+
454
+ if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan) {
455
+ firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
456
+ }
457
+ }
458
+ }
459
+
460
+ return firstNonSpannedColumnToRender;
461
+ }
462
+
463
+ function getFirstColumnIndexToRender({
464
+ firstColumnIndex,
465
+ minColumnIndex,
466
+ columnBuffer,
467
+ firstRowToRender,
468
+ lastRowToRender,
469
+ apiRef,
470
+ visibleRows
471
+ }) {
472
+ const initialFirstColumnToRender = Math.max(firstColumnIndex - columnBuffer, minColumnIndex);
473
+ const firstColumnToRender = getFirstNonSpannedColumnToRender({
474
+ firstColumnToRender: initialFirstColumnToRender,
475
+ apiRef,
476
+ firstRowToRender,
477
+ lastRowToRender,
478
+ visibleRows
479
+ });
480
+ return firstColumnToRender;
481
+ }
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useGridColumnSpanning = void 0;
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _useGridApiMethod = require("../../utils/useGridApiMethod");
13
+
14
+ var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler");
15
+
16
+ var _gridEvents = require("../../../models/events/gridEvents");
17
+
18
+ /**
19
+ * @requires useGridColumns (method, event)
20
+ * @requires useGridParamsApi (method)
21
+ */
22
+ const useGridColumnSpanning = apiRef => {
23
+ const lookup = _react.default.useRef({});
24
+
25
+ const setCellColSpanInfo = _react.default.useCallback((rowId, columnIndex, cellColSpanInfo) => {
26
+ const sizes = lookup.current;
27
+
28
+ if (!sizes[rowId]) {
29
+ sizes[rowId] = {};
30
+ }
31
+
32
+ sizes[rowId][columnIndex] = cellColSpanInfo;
33
+ }, []);
34
+
35
+ const getCellColSpanInfo = _react.default.useCallback((rowId, columnIndex) => {
36
+ var _lookup$current$rowId;
37
+
38
+ return (_lookup$current$rowId = lookup.current[rowId]) == null ? void 0 : _lookup$current$rowId[columnIndex];
39
+ }, []); // Calculate `colSpan` for the cell.
40
+
41
+
42
+ const calculateCellColSpan = _react.default.useCallback(params => {
43
+ const {
44
+ columnIndex,
45
+ rowId,
46
+ minFirstColumnIndex,
47
+ maxLastColumnIndex
48
+ } = params;
49
+ const visibleColumns = apiRef.current.getVisibleColumns();
50
+ const columnsLength = visibleColumns.length;
51
+ const column = visibleColumns[columnIndex];
52
+ const colSpan = typeof column.colSpan === 'function' ? column.colSpan(apiRef.current.getCellParams(rowId, column.field)) : column.colSpan;
53
+
54
+ if (!colSpan || colSpan === 1) {
55
+ setCellColSpanInfo(rowId, columnIndex, {
56
+ spannedByColSpan: false,
57
+ cellProps: {
58
+ colSpan: 1,
59
+ width: column.computedWidth
60
+ }
61
+ });
62
+ return {
63
+ colSpan: 1
64
+ };
65
+ }
66
+
67
+ let width = column.computedWidth;
68
+
69
+ for (let j = 1; j < colSpan; j += 1) {
70
+ const nextColumnIndex = columnIndex + j; // Cells should be spanned only within their column section (left-pinned, right-pinned and unpinned).
71
+
72
+ if (nextColumnIndex >= minFirstColumnIndex && nextColumnIndex < maxLastColumnIndex) {
73
+ const nextColumn = visibleColumns[nextColumnIndex];
74
+ width += nextColumn.computedWidth;
75
+ setCellColSpanInfo(rowId, columnIndex + j, {
76
+ spannedByColSpan: true,
77
+ rightVisibleCellIndex: Math.min(columnIndex + colSpan, columnsLength - 1),
78
+ leftVisibleCellIndex: columnIndex
79
+ });
80
+ }
81
+
82
+ setCellColSpanInfo(rowId, columnIndex, {
83
+ spannedByColSpan: false,
84
+ cellProps: {
85
+ colSpan,
86
+ width
87
+ }
88
+ });
89
+ }
90
+
91
+ return {
92
+ colSpan
93
+ };
94
+ }, [apiRef, setCellColSpanInfo]); // Calculate `colSpan` for each cell in the row
95
+
96
+
97
+ const calculateColSpan = _react.default.useCallback(({
98
+ rowId,
99
+ minFirstColumn,
100
+ maxLastColumn
101
+ }) => {
102
+ for (let i = minFirstColumn; i < maxLastColumn; i += 1) {
103
+ const cellProps = calculateCellColSpan({
104
+ columnIndex: i,
105
+ rowId,
106
+ minFirstColumnIndex: minFirstColumn,
107
+ maxLastColumnIndex: maxLastColumn
108
+ });
109
+
110
+ if (cellProps.colSpan > 1) {
111
+ i += cellProps.colSpan - 1;
112
+ }
113
+ }
114
+ }, [calculateCellColSpan]);
115
+
116
+ const columnSpanningApi = {
117
+ unstable_getCellColSpanInfo: getCellColSpanInfo,
118
+ unstable_calculateColSpan: calculateColSpan
119
+ };
120
+ (0, _useGridApiMethod.useGridApiMethod)(apiRef, columnSpanningApi, 'GridColumnSpanningAPI');
121
+
122
+ const handleColumnReorderChange = _react.default.useCallback(() => {
123
+ // `colSpan` needs to be recalculated after column reordering
124
+ lookup.current = {};
125
+ }, []);
126
+
127
+ (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _gridEvents.GridEvents.columnOrderChange, handleColumnReorderChange);
128
+ };
129
+
130
+ exports.useGridColumnSpanning = useGridColumnSpanning;
@@ -238,7 +238,13 @@ function useGridColumns(apiRef, props) {
238
238
  const colDefDimensions = {};
239
239
 
240
240
  _gridColumnsUtils.COLUMNS_DIMENSION_PROPERTIES.forEach(propertyName => {
241
- colDefDimensions[propertyName] = colDef[propertyName];
241
+ let propertyValue = colDef[propertyName];
242
+
243
+ if (propertyValue === Infinity) {
244
+ propertyValue = -1;
245
+ }
246
+
247
+ colDefDimensions[propertyName] = propertyValue;
242
248
  });
243
249
 
244
250
  dimensions[colDef.field] = colDefDimensions;
@@ -297,12 +303,23 @@ function useGridColumns(apiRef, props) {
297
303
  * EVENTS
298
304
  */
299
305
 
300
- const handlepipeProcessorRegister = React.useCallback(name => {
301
- if (name !== 'hydrateColumns') {
302
- return;
306
+ const prevInnerWidth = React.useRef(null);
307
+
308
+ const handleGridSizeChange = viewportInnerSize => {
309
+ if (prevInnerWidth.current !== viewportInnerSize.width) {
310
+ prevInnerWidth.current = viewportInnerSize.width;
311
+ setGridColumnsState((0, _gridColumnsUtils.hydrateColumnsWidth)((0, _gridColumnsSelector.gridColumnsSelector)(apiRef.current.state), viewportInnerSize.width));
303
312
  }
313
+ };
314
+
315
+ (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.viewportInnerSizeChange, handleGridSizeChange);
316
+ (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.columnVisibilityChange, props.onColumnVisibilityChange);
317
+ /**
318
+ * APPLIERS
319
+ */
304
320
 
305
- logger.info(`Columns pre-processing have changed, regenerating the columns`);
321
+ const hydrateColumns = React.useCallback(() => {
322
+ logger.info(`Columns pipe processing have changed, regenerating the columns`);
306
323
  const columnsState = (0, _gridColumnsUtils.createColumnsState)({
307
324
  apiRef,
308
325
  columnTypes,
@@ -313,18 +330,7 @@ function useGridColumns(apiRef, props) {
313
330
  });
314
331
  setGridColumnsState(columnsState);
315
332
  }, [apiRef, logger, setGridColumnsState, columnTypes]);
316
- const prevInnerWidth = React.useRef(null);
317
-
318
- const handleGridSizeChange = viewportInnerSize => {
319
- if (prevInnerWidth.current !== viewportInnerSize.width) {
320
- prevInnerWidth.current = viewportInnerSize.width;
321
- setGridColumnsState((0, _gridColumnsUtils.hydrateColumnsWidth)((0, _gridColumnsSelector.gridColumnsSelector)(apiRef.current.state), viewportInnerSize.width));
322
- }
323
- };
324
-
325
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.pipeProcessorRegister, handlepipeProcessorRegister);
326
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.viewportInnerSizeChange, handleGridSizeChange);
327
- (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.columnVisibilityChange, props.onColumnVisibilityChange);
333
+ (0, _pipeProcessing.useGridRegisterPipeApplier)(apiRef, 'hydrateColumns', hydrateColumns);
328
334
  /**
329
335
  * EFFECTS
330
336
  */
@@ -168,12 +168,12 @@ function useGridDimensions(apiRef, props) {
168
168
  const isJSDOM = /jsdom/.test(window.navigator.userAgent);
169
169
 
170
170
  if (size.height === 0 && !warningShown.current && !props.autoHeight && !isJSDOM) {
171
- logger.warn(['The parent of the grid has an empty height.', 'You need to make sure the container has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'You can find a solution in the docs:', 'https://mui.com/components/data-grid/layout/'].join('\n'));
171
+ logger.warn(['The parent of the grid has an empty height.', 'You need to make sure the container has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'You can find a solution in the docs:', 'https://mui.com/x/react-data-grid/layout/'].join('\n'));
172
172
  warningShown.current = true;
173
173
  }
174
174
 
175
175
  if (size.width === 0 && !warningShown.current && !isJSDOM) {
176
- logger.warn(['The parent of the grid has an empty width.', 'You need to make sure the container has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'You can find a solution in the docs:', 'https://mui.com/components/data-grid/layout/'].join('\n'));
176
+ logger.warn(['The parent of the grid has an empty width.', 'You need to make sure the container has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'You can find a solution in the docs:', 'https://mui.com/x/react-data-grid/layout/'].join('\n'));
177
177
  warningShown.current = true;
178
178
  }
179
179
 
@@ -194,7 +194,7 @@ function useGridDimensions(apiRef, props) {
194
194
  debounceResize();
195
195
  }, [props.autoHeight, debounceResize, logger, resize]);
196
196
  (0, _utils.unstable_useEnhancedEffect)(() => updateGridDimensionsRef(), [updateGridDimensionsRef]);
197
- (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.visibleRowsSet, updateGridDimensionsRef);
197
+ (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.sortedRowsSet, updateGridDimensionsRef);
198
198
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.pageChange, updateGridDimensionsRef);
199
199
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.pageSizeChange, updateGridDimensionsRef);
200
200
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, _events.GridEvents.columnsChange, updateGridDimensionsRef);
@@ -243,10 +243,7 @@ const useGridCellEditing = (apiRef, props) => {
243
243
  }
244
244
 
245
245
  const editingState = (0, _gridEditRowsSelector.gridEditRowsStateSelector)(apiRef.current.state);
246
- const row = apiRef.current.getRow(id);
247
- const column = apiRef.current.getColumn(field);
248
246
  const {
249
- value,
250
247
  error,
251
248
  isProcessingProps
252
249
  } = editingState[id][field];
@@ -255,12 +252,7 @@ const useGridCellEditing = (apiRef, props) => {
255
252
  return;
256
253
  }
257
254
 
258
- const rowUpdate = column.valueSetter ? column.valueSetter({
259
- value,
260
- row
261
- }) : (0, _extends2.default)({}, row, {
262
- [field]: value
263
- });
255
+ const rowUpdate = apiRef.current.unstable_getRowWithUpdatedValuesFromCellEditing(id, field);
264
256
 
265
257
  if (processRowUpdate) {
266
258
  const handleError = errorThrown => {
@@ -272,6 +264,7 @@ const useGridCellEditing = (apiRef, props) => {
272
264
  };
273
265
 
274
266
  try {
267
+ const row = apiRef.current.getRow(id);
275
268
  Promise.resolve(processRowUpdate(rowUpdate, row)).then(finalRowUpdate => {
276
269
  apiRef.current.updateRows([finalRowUpdate]);
277
270
  updateFocusedCellIfNeeded();
@@ -339,11 +332,26 @@ const useGridCellEditing = (apiRef, props) => {
339
332
  editingState = (0, _gridEditRowsSelector.gridEditRowsStateSelector)(apiRef.current.state);
340
333
  return !editingState[id][field].error;
341
334
  }, [apiRef, throwIfNotEditable, throwIfNotInMode, updateOrDeleteFieldState]);
335
+ const getRowWithUpdatedValuesFromCellEditing = React.useCallback((id, field) => {
336
+ const column = apiRef.current.getColumn(field);
337
+ const editingState = (0, _gridEditRowsSelector.gridEditRowsStateSelector)(apiRef.current.state);
338
+ const {
339
+ value
340
+ } = editingState[id][field];
341
+ const row = apiRef.current.getRow(id);
342
+ return column.valueSetter ? column.valueSetter({
343
+ value,
344
+ row
345
+ }) : (0, _extends2.default)({}, row, {
346
+ [field]: value
347
+ });
348
+ }, [apiRef]);
342
349
  const editingApi = {
343
350
  getCellMode,
344
351
  startCellEditMode,
345
352
  stopCellEditMode,
346
- unstable_setCellEditingEditCellValue: setCellEditingEditCellValue
353
+ unstable_setCellEditingEditCellValue: setCellEditingEditCellValue,
354
+ unstable_getRowWithUpdatedValuesFromCellEditing: getRowWithUpdatedValuesFromCellEditing
347
355
  };
348
356
  (0, _useGridApiMethod.useGridApiMethod)(apiRef, editingApi, 'EditingApi');
349
357
  };
@@ -121,7 +121,7 @@ const useGridEditing = (apiRef, props) => {
121
121
  } = params;
122
122
  return new Promise(resolve => {
123
123
  maybeDebounce(id, field, debounceMs, async () => {
124
- const setEditCellValueToCall = props.editMode === 'row' ? apiRef.current.unstable_setRowEditingEditCellValue : apiRef.current.unstable_setCellEditingEditCellValue; // Check if the cell is in edit mode
124
+ const setEditCellValueToCall = props.editMode === _gridEditRowModel.GridEditModes.Row ? apiRef.current.unstable_setRowEditingEditCellValue : apiRef.current.unstable_setCellEditingEditCellValue; // Check if the cell is in edit mode
125
125
  // By the time this callback runs the user may have cancelled the editing
126
126
 
127
127
  if (apiRef.current.getCellMode(id, field) === _gridEditRowModel.GridCellModes.Edit) {
@@ -131,10 +131,14 @@ const useGridEditing = (apiRef, props) => {
131
131
  });
132
132
  });
133
133
  }, [apiRef, props.editMode]);
134
+ const getRowWithUpdatedValues = React.useCallback((id, field) => {
135
+ return props.editMode === _gridEditRowModel.GridEditModes.Cell ? apiRef.current.unstable_getRowWithUpdatedValuesFromCellEditing(id, field) : apiRef.current.unstable_getRowWithUpdatedValuesFromRowEditing(id);
136
+ }, [apiRef, props.editMode]);
134
137
  const editingSharedApi = {
135
138
  isCellEditable,
136
139
  setEditCellValue,
137
- unstable_runPendingEditCellValueMutation: runPendingEditCellValueMutation
140
+ unstable_runPendingEditCellValueMutation: runPendingEditCellValueMutation,
141
+ unstable_getRowWithUpdatedValues: getRowWithUpdatedValues
138
142
  };
139
143
  (0, _useGridApiMethod.useGridApiMethod)(apiRef, editingSharedApi, 'EditingApi');
140
144
  };
@@ -355,19 +355,7 @@ const useGridRowEditing = (apiRef, props) => {
355
355
  return;
356
356
  }
357
357
 
358
- let rowUpdate = (0, _extends2.default)({}, row);
359
- Object.entries(editingState[id]).forEach(([field, fieldProps]) => {
360
- const column = apiRef.current.getColumn(field);
361
-
362
- if (column.valueSetter) {
363
- rowUpdate = column.valueSetter({
364
- value: fieldProps.value,
365
- row: rowUpdate
366
- });
367
- } else {
368
- rowUpdate[field] = fieldProps.value;
369
- }
370
- });
358
+ const rowUpdate = apiRef.current.unstable_getRowWithUpdatedValuesFromRowEditing(id);
371
359
 
372
360
  if (processRowUpdate) {
373
361
  const handleError = errorThrown => {
@@ -504,11 +492,30 @@ const useGridRowEditing = (apiRef, props) => {
504
492
  });
505
493
  });
506
494
  }, [apiRef, throwIfNotEditable, updateOrDeleteFieldState]);
495
+ const getRowWithUpdatedValuesFromRowEditing = React.useCallback(id => {
496
+ const editingState = (0, _gridEditRowsSelector.gridEditRowsStateSelector)(apiRef.current.state);
497
+ const row = apiRef.current.getRow(id);
498
+ let rowUpdate = (0, _extends2.default)({}, row);
499
+ Object.entries(editingState[id]).forEach(([field, fieldProps]) => {
500
+ const column = apiRef.current.getColumn(field);
501
+
502
+ if (column.valueSetter) {
503
+ rowUpdate = column.valueSetter({
504
+ value: fieldProps.value,
505
+ row: rowUpdate
506
+ });
507
+ } else {
508
+ rowUpdate[field] = fieldProps.value;
509
+ }
510
+ });
511
+ return rowUpdate;
512
+ }, [apiRef]);
507
513
  const editingApi = {
508
514
  getRowMode,
509
515
  startRowEditMode,
510
516
  stopRowEditMode,
511
- unstable_setRowEditingEditCellValue: setRowEditingEditCellValue
517
+ unstable_setRowEditingEditCellValue: setRowEditingEditCellValue,
518
+ unstable_getRowWithUpdatedValuesFromRowEditing: getRowWithUpdatedValuesFromRowEditing
512
519
  };
513
520
  (0, _useGridApiMethod.useGridApiMethod)(apiRef, editingApi, 'EditingApi');
514
521
  };
@@ -77,11 +77,7 @@ const useGridFilter = (apiRef, props) => {
77
77
  stateSelector: _gridFilterSelector.gridFilterModelSelector,
78
78
  changeEvent: _events.GridEvents.filterModelChange
79
79
  });
80
- /**
81
- * API METHODS
82
- */
83
-
84
- const applyFilters = React.useCallback(() => {
80
+ const updateFilteredRows = React.useCallback(() => {
85
81
  apiRef.current.setState(state => {
86
82
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(state, apiRef.current.instanceId);
87
83
  const isRowMatchingFilters = props.filterMode === _gridFeatureMode.GridFeatureModeConstant.client ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(filterModel, apiRef) : null;
@@ -92,9 +88,16 @@ const useGridFilter = (apiRef, props) => {
92
88
  filter: (0, _extends2.default)({}, state.filter, filteringResult)
93
89
  });
94
90
  });
95
- apiRef.current.publishEvent(_events.GridEvents.visibleRowsSet);
91
+ apiRef.current.publishEvent(_events.GridEvents.filteredRowsSet);
92
+ }, [props.filterMode, apiRef]);
93
+ /**
94
+ * API METHODS
95
+ */
96
+
97
+ const applyFilters = React.useCallback(() => {
98
+ updateFilteredRows();
96
99
  apiRef.current.forceUpdate();
97
- }, [apiRef, props.filterMode]);
100
+ }, [apiRef, updateFilteredRows]);
98
101
  const upsertFilterItem = React.useCallback(item => {
99
102
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
100
103
  const items = [...filterModel.items];
@@ -278,8 +281,10 @@ const useGridFilter = (apiRef, props) => {
278
281
  if (methodName === 'filtering') {
279
282
  apiRef.current.unstable_applyFilters();
280
283
  }
281
- }, [apiRef]);
282
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.rowsSet, apiRef.current.unstable_applyFilters);
284
+ }, [apiRef]); // Do not call `apiRef.current.forceUpdate` to avoid re-render before updating the sorted rows.
285
+ // Otherwise, the state is not consistent during the render
286
+
287
+ (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.rowsSet, updateFilteredRows);
283
288
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.rowExpansionChange, apiRef.current.unstable_applyFilters);
284
289
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.columnsChange, handleColumnsChange);
285
290
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, _events.GridEvents.activeStrategyProcessorChange, handleStrategyProcessorChange);