@mui/x-data-grid 5.14.0 → 5.15.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 (290) hide show
  1. package/CHANGELOG.md +147 -5
  2. package/DataGrid/DataGrid.js +7 -1
  3. package/DataGrid/useDataGridProps.js +1 -0
  4. package/colDef/gridStringColDef.js +1 -1
  5. package/components/GridRow.js +5 -1
  6. package/components/base/GridOverlays.js +2 -2
  7. package/components/cell/GridEditInputCell.d.ts +2 -5
  8. package/components/cell/GridEditInputCell.js +13 -14
  9. package/components/cell/GridEditSingleSelectCell.d.ts +4 -0
  10. package/components/cell/GridEditSingleSelectCell.js +11 -4
  11. package/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  12. package/components/containers/GridRoot.js +4 -2
  13. package/components/toolbar/GridToolbarDensitySelector.js +13 -4
  14. package/components/toolbar/GridToolbarExportContainer.js +13 -2
  15. package/constants/envConstants.d.ts +1 -1
  16. package/constants/envConstants.js +2 -11
  17. package/constants/gridClasses.d.ts +16 -0
  18. package/constants/gridClasses.js +1 -1
  19. package/constants/localeTextConstants.js +1 -1
  20. package/hooks/features/dimensions/useGridDimensions.js +6 -1
  21. package/hooks/features/editRows/useGridCellEditing.new.d.ts +1 -1
  22. package/hooks/features/editRows/useGridCellEditing.new.js +26 -16
  23. package/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  24. package/hooks/features/editRows/useGridEditing.new.d.ts +1 -1
  25. package/hooks/features/editRows/useGridEditing.new.js +4 -0
  26. package/hooks/features/editRows/useGridEditing.old.js +1 -1
  27. package/hooks/features/editRows/useGridRowEditing.new.d.ts +1 -1
  28. package/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  29. package/hooks/features/export/utils.js +8 -1
  30. package/hooks/features/filter/gridFilterState.d.ts +12 -1
  31. package/hooks/features/filter/gridFilterUtils.d.ts +8 -5
  32. package/hooks/features/filter/gridFilterUtils.js +74 -43
  33. package/hooks/features/filter/useGridFilter.js +16 -3
  34. package/hooks/features/focus/useGridFocus.js +11 -6
  35. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  36. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +42 -34
  37. package/hooks/features/pagination/useGridPageSize.js +3 -1
  38. package/hooks/features/rows/gridRowsSelector.d.ts +14 -0
  39. package/hooks/features/rows/gridRowsSelector.js +20 -1
  40. package/hooks/features/rows/gridRowsState.d.ts +8 -1
  41. package/hooks/features/rows/gridRowsUtils.d.ts +4 -0
  42. package/hooks/features/rows/gridRowsUtils.js +21 -3
  43. package/hooks/features/rows/index.d.ts +1 -1
  44. package/hooks/features/rows/index.js +1 -1
  45. package/hooks/features/rows/useGridRows.js +5 -2
  46. package/hooks/features/rows/useGridRowsMeta.js +19 -4
  47. package/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  48. package/hooks/features/scroll/useGridScroll.js +7 -2
  49. package/hooks/features/selection/useGridSelection.js +7 -3
  50. package/hooks/features/sorting/useGridSorting.js +8 -0
  51. package/hooks/features/statePersistence/gridStatePersistenceInterface.d.ts +3 -0
  52. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +3 -1
  53. package/hooks/features/virtualization/useGridVirtualScroller.js +31 -16
  54. package/index.js +1 -1
  55. package/internals/index.d.ts +5 -1
  56. package/internals/index.js +4 -0
  57. package/legacy/DataGrid/DataGrid.js +7 -1
  58. package/legacy/DataGrid/useDataGridProps.js +1 -0
  59. package/legacy/colDef/gridStringColDef.js +1 -1
  60. package/legacy/components/GridRow.js +5 -1
  61. package/legacy/components/base/GridOverlays.js +2 -2
  62. package/legacy/components/cell/GridEditInputCell.js +13 -14
  63. package/legacy/components/cell/GridEditSingleSelectCell.js +11 -3
  64. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  65. package/legacy/components/containers/GridRoot.js +4 -2
  66. package/legacy/components/toolbar/GridToolbarDensitySelector.js +14 -5
  67. package/legacy/components/toolbar/GridToolbarExportContainer.js +15 -2
  68. package/legacy/constants/envConstants.js +2 -11
  69. package/legacy/constants/gridClasses.js +1 -1
  70. package/legacy/constants/localeTextConstants.js +1 -1
  71. package/legacy/hooks/features/dimensions/useGridDimensions.js +6 -1
  72. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +27 -17
  73. package/legacy/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  74. package/legacy/hooks/features/editRows/useGridEditing.new.js +4 -0
  75. package/legacy/hooks/features/editRows/useGridEditing.old.js +1 -1
  76. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  77. package/legacy/hooks/features/export/utils.js +13 -1
  78. package/legacy/hooks/features/filter/gridFilterUtils.js +84 -55
  79. package/legacy/hooks/features/filter/useGridFilter.js +16 -3
  80. package/legacy/hooks/features/focus/useGridFocus.js +11 -6
  81. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +47 -34
  82. package/legacy/hooks/features/pagination/useGridPageSize.js +3 -1
  83. package/legacy/hooks/features/rows/gridRowsSelector.js +23 -0
  84. package/legacy/hooks/features/rows/gridRowsUtils.js +21 -3
  85. package/legacy/hooks/features/rows/index.js +1 -1
  86. package/legacy/hooks/features/rows/useGridRows.js +5 -2
  87. package/legacy/hooks/features/rows/useGridRowsMeta.js +19 -4
  88. package/legacy/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  89. package/legacy/hooks/features/scroll/useGridScroll.js +7 -2
  90. package/legacy/hooks/features/selection/useGridSelection.js +7 -3
  91. package/legacy/hooks/features/sorting/useGridSorting.js +8 -0
  92. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +32 -16
  93. package/legacy/index.js +1 -1
  94. package/legacy/internals/index.js +4 -0
  95. package/legacy/locales/arSD.js +1 -1
  96. package/legacy/locales/bgBG.js +1 -1
  97. package/legacy/locales/csCZ.js +1 -1
  98. package/legacy/locales/daDK.js +1 -1
  99. package/legacy/locales/deDE.js +9 -9
  100. package/legacy/locales/elGR.js +1 -1
  101. package/legacy/locales/esES.js +1 -1
  102. package/legacy/locales/faIR.js +1 -1
  103. package/legacy/locales/fiFI.js +1 -1
  104. package/legacy/locales/frFR.js +1 -1
  105. package/legacy/locales/heIL.js +1 -1
  106. package/legacy/locales/huHU.js +1 -1
  107. package/legacy/locales/itIT.js +15 -15
  108. package/legacy/locales/jaJP.js +3 -3
  109. package/legacy/locales/koKR.js +34 -30
  110. package/legacy/locales/nbNO.js +1 -1
  111. package/legacy/locales/nlNL.js +1 -1
  112. package/legacy/locales/plPL.js +1 -1
  113. package/legacy/locales/ptBR.js +1 -1
  114. package/legacy/locales/roRO.js +1 -1
  115. package/legacy/locales/ruRU.js +1 -1
  116. package/legacy/locales/skSK.js +1 -1
  117. package/legacy/locales/svSE.js +1 -1
  118. package/legacy/locales/trTR.js +1 -1
  119. package/legacy/locales/ukUA.js +1 -1
  120. package/legacy/locales/viVN.js +1 -1
  121. package/legacy/locales/zhCN.js +37 -33
  122. package/legacy/locales/zhTW.js +1 -1
  123. package/legacy/utils/keyboardUtils.js +8 -5
  124. package/locales/arSD.js +1 -1
  125. package/locales/bgBG.js +1 -1
  126. package/locales/csCZ.js +1 -1
  127. package/locales/daDK.js +1 -1
  128. package/locales/deDE.js +9 -9
  129. package/locales/elGR.js +1 -1
  130. package/locales/esES.js +1 -1
  131. package/locales/faIR.js +1 -1
  132. package/locales/fiFI.js +1 -1
  133. package/locales/frFR.js +1 -1
  134. package/locales/heIL.js +1 -1
  135. package/locales/huHU.js +1 -1
  136. package/locales/itIT.js +15 -15
  137. package/locales/jaJP.js +3 -3
  138. package/locales/koKR.js +30 -30
  139. package/locales/nbNO.js +1 -1
  140. package/locales/nlNL.js +1 -1
  141. package/locales/plPL.js +1 -1
  142. package/locales/ptBR.js +1 -1
  143. package/locales/roRO.js +1 -1
  144. package/locales/ruRU.js +1 -1
  145. package/locales/skSK.js +1 -1
  146. package/locales/svSE.js +1 -1
  147. package/locales/trTR.js +1 -1
  148. package/locales/ukUA.js +1 -1
  149. package/locales/viVN.js +1 -1
  150. package/locales/zhCN.js +33 -33
  151. package/locales/zhTW.js +1 -1
  152. package/models/gridRows.d.ts +5 -0
  153. package/models/props/DataGridProps.d.ts +8 -3
  154. package/modern/DataGrid/DataGrid.js +7 -1
  155. package/modern/DataGrid/useDataGridProps.js +1 -0
  156. package/modern/colDef/gridStringColDef.js +1 -1
  157. package/modern/components/GridRow.js +5 -1
  158. package/modern/components/base/GridOverlays.js +2 -2
  159. package/modern/components/cell/GridEditInputCell.js +13 -14
  160. package/modern/components/cell/GridEditSingleSelectCell.js +11 -4
  161. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  162. package/modern/components/containers/GridRoot.js +4 -2
  163. package/modern/components/toolbar/GridToolbarDensitySelector.js +11 -4
  164. package/modern/components/toolbar/GridToolbarExportContainer.js +11 -2
  165. package/modern/constants/envConstants.js +2 -11
  166. package/modern/constants/gridClasses.js +1 -1
  167. package/modern/constants/localeTextConstants.js +1 -1
  168. package/modern/hooks/features/dimensions/useGridDimensions.js +6 -1
  169. package/modern/hooks/features/editRows/useGridCellEditing.new.js +24 -16
  170. package/modern/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  171. package/modern/hooks/features/editRows/useGridEditing.new.js +4 -0
  172. package/modern/hooks/features/editRows/useGridEditing.old.js +1 -1
  173. package/modern/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  174. package/modern/hooks/features/export/utils.js +6 -1
  175. package/modern/hooks/features/filter/gridFilterUtils.js +73 -42
  176. package/modern/hooks/features/filter/useGridFilter.js +16 -3
  177. package/modern/hooks/features/focus/useGridFocus.js +11 -6
  178. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +42 -30
  179. package/modern/hooks/features/pagination/useGridPageSize.js +3 -1
  180. package/modern/hooks/features/rows/gridRowsSelector.js +18 -1
  181. package/modern/hooks/features/rows/gridRowsUtils.js +19 -3
  182. package/modern/hooks/features/rows/index.js +1 -1
  183. package/modern/hooks/features/rows/useGridRows.js +5 -2
  184. package/modern/hooks/features/rows/useGridRowsMeta.js +17 -4
  185. package/modern/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  186. package/modern/hooks/features/scroll/useGridScroll.js +5 -2
  187. package/modern/hooks/features/selection/useGridSelection.js +7 -1
  188. package/modern/hooks/features/sorting/useGridSorting.js +8 -0
  189. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +30 -15
  190. package/modern/index.js +1 -1
  191. package/modern/internals/index.js +4 -0
  192. package/modern/locales/arSD.js +1 -1
  193. package/modern/locales/bgBG.js +1 -1
  194. package/modern/locales/csCZ.js +1 -1
  195. package/modern/locales/daDK.js +1 -1
  196. package/modern/locales/deDE.js +9 -9
  197. package/modern/locales/elGR.js +1 -1
  198. package/modern/locales/esES.js +1 -1
  199. package/modern/locales/faIR.js +1 -1
  200. package/modern/locales/fiFI.js +1 -1
  201. package/modern/locales/frFR.js +1 -1
  202. package/modern/locales/heIL.js +1 -1
  203. package/modern/locales/huHU.js +1 -1
  204. package/modern/locales/itIT.js +15 -15
  205. package/modern/locales/jaJP.js +3 -3
  206. package/modern/locales/koKR.js +30 -30
  207. package/modern/locales/nbNO.js +1 -1
  208. package/modern/locales/nlNL.js +1 -1
  209. package/modern/locales/plPL.js +1 -1
  210. package/modern/locales/ptBR.js +1 -1
  211. package/modern/locales/roRO.js +1 -1
  212. package/modern/locales/ruRU.js +1 -1
  213. package/modern/locales/skSK.js +1 -1
  214. package/modern/locales/svSE.js +1 -1
  215. package/modern/locales/trTR.js +1 -1
  216. package/modern/locales/ukUA.js +1 -1
  217. package/modern/locales/viVN.js +1 -1
  218. package/modern/locales/zhCN.js +33 -33
  219. package/modern/locales/zhTW.js +1 -1
  220. package/modern/utils/keyboardUtils.js +7 -2
  221. package/node/DataGrid/DataGrid.js +7 -1
  222. package/node/DataGrid/useDataGridProps.js +1 -0
  223. package/node/colDef/gridStringColDef.js +1 -1
  224. package/node/components/GridRow.js +5 -1
  225. package/node/components/base/GridOverlays.js +2 -2
  226. package/node/components/cell/GridEditInputCell.js +15 -16
  227. package/node/components/cell/GridEditSingleSelectCell.js +10 -4
  228. package/node/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  229. package/node/components/containers/GridRoot.js +3 -1
  230. package/node/components/toolbar/GridToolbarDensitySelector.js +13 -4
  231. package/node/components/toolbar/GridToolbarExportContainer.js +13 -2
  232. package/node/constants/envConstants.js +2 -13
  233. package/node/constants/gridClasses.js +1 -1
  234. package/node/constants/localeTextConstants.js +1 -1
  235. package/node/hooks/features/dimensions/useGridDimensions.js +7 -1
  236. package/node/hooks/features/editRows/useGridCellEditing.new.js +26 -16
  237. package/node/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  238. package/node/hooks/features/editRows/useGridEditing.new.js +4 -0
  239. package/node/hooks/features/editRows/useGridEditing.old.js +1 -1
  240. package/node/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  241. package/node/hooks/features/export/utils.js +7 -0
  242. package/node/hooks/features/filter/gridFilterUtils.js +81 -47
  243. package/node/hooks/features/filter/useGridFilter.js +15 -2
  244. package/node/hooks/features/focus/useGridFocus.js +11 -6
  245. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +43 -34
  246. package/node/hooks/features/pagination/useGridPageSize.js +4 -1
  247. package/node/hooks/features/rows/gridRowsSelector.js +24 -2
  248. package/node/hooks/features/rows/gridRowsUtils.js +23 -2
  249. package/node/hooks/features/rows/index.js +70 -12
  250. package/node/hooks/features/rows/useGridRows.js +5 -2
  251. package/node/hooks/features/rows/useGridRowsMeta.js +20 -4
  252. package/node/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  253. package/node/hooks/features/scroll/useGridScroll.js +7 -1
  254. package/node/hooks/features/selection/useGridSelection.js +7 -3
  255. package/node/hooks/features/sorting/useGridSorting.js +8 -0
  256. package/node/hooks/features/virtualization/useGridVirtualScroller.js +31 -16
  257. package/node/index.js +1 -1
  258. package/node/internals/index.js +36 -0
  259. package/node/locales/arSD.js +1 -1
  260. package/node/locales/bgBG.js +1 -1
  261. package/node/locales/csCZ.js +1 -1
  262. package/node/locales/daDK.js +1 -1
  263. package/node/locales/deDE.js +9 -9
  264. package/node/locales/elGR.js +1 -1
  265. package/node/locales/esES.js +1 -1
  266. package/node/locales/faIR.js +1 -1
  267. package/node/locales/fiFI.js +1 -1
  268. package/node/locales/frFR.js +1 -1
  269. package/node/locales/heIL.js +1 -1
  270. package/node/locales/huHU.js +1 -1
  271. package/node/locales/itIT.js +15 -15
  272. package/node/locales/jaJP.js +3 -3
  273. package/node/locales/koKR.js +30 -30
  274. package/node/locales/nbNO.js +1 -1
  275. package/node/locales/nlNL.js +1 -1
  276. package/node/locales/plPL.js +1 -1
  277. package/node/locales/ptBR.js +1 -1
  278. package/node/locales/roRO.js +1 -1
  279. package/node/locales/ruRU.js +1 -1
  280. package/node/locales/skSK.js +1 -1
  281. package/node/locales/svSE.js +1 -1
  282. package/node/locales/trTR.js +1 -1
  283. package/node/locales/ukUA.js +1 -1
  284. package/node/locales/viVN.js +1 -1
  285. package/node/locales/zhCN.js +33 -33
  286. package/node/locales/zhTW.js +1 -1
  287. package/node/utils/keyboardUtils.js +10 -4
  288. package/package.json +1 -1
  289. package/utils/keyboardUtils.d.ts +2 -2
  290. package/utils/keyboardUtils.js +7 -2
@@ -37,8 +37,8 @@ function GridOverlayWrapper(props) {
37
37
  position: 'absolute',
38
38
  top: headerHeight,
39
39
  bottom: height === 'auto' ? 0 : undefined,
40
- zIndex: 3,
41
- // should be above pinned columns and detail panel
40
+ zIndex: 4,
41
+ // should be above pinned columns, pinned rows and detail panel
42
42
  pointerEvents: 'none'
43
43
  }
44
44
  }, props));
@@ -37,8 +37,7 @@ const GridEditInputCellRoot = styled(InputBase, {
37
37
  height: '100%'
38
38
  }
39
39
  }));
40
-
41
- function GridEditInputCell(props) {
40
+ const GridEditInputCell = /*#__PURE__*/React.forwardRef((props, ref) => {
42
41
  const rootProps = useGridRootProps();
43
42
 
44
43
  const {
@@ -84,6 +83,7 @@ function GridEditInputCell(props) {
84
83
  }
85
84
  }, [hasFocus]);
86
85
  return /*#__PURE__*/_jsx(GridEditInputCellRoot, _extends({
86
+ ref: ref,
87
87
  inputRef: inputRef,
88
88
  className: classes.root,
89
89
  fullWidth: true,
@@ -92,8 +92,7 @@ function GridEditInputCell(props) {
92
92
  onChange: handleChange,
93
93
  endAdornment: isProcessingProps ? /*#__PURE__*/_jsx(GridLoadIcon, {}) : undefined
94
94
  }, other));
95
- }
96
-
95
+ });
97
96
  process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
98
97
  // ----------------------------- Warning --------------------------------
99
98
  // | These PropTypes are generated from the TypeScript type definitions |
@@ -104,23 +103,23 @@ process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
104
103
  * GridApi that let you manipulate the grid.
105
104
  * @deprecated Use the `apiRef` returned by `useGridApiContext` or `useGridApiRef` (only available in `@mui/x-data-grid-pro`)
106
105
  */
107
- api: PropTypes.any.isRequired,
106
+ api: PropTypes.any,
108
107
 
109
108
  /**
110
109
  * The mode of the cell.
111
110
  */
112
- cellMode: PropTypes.oneOf(['edit', 'view']).isRequired,
111
+ cellMode: PropTypes.oneOf(['edit', 'view']),
113
112
 
114
113
  /**
115
114
  * The column of the row that the current cell belongs to.
116
115
  */
117
- colDef: PropTypes.object.isRequired,
116
+ colDef: PropTypes.object,
118
117
  debounceMs: PropTypes.number,
119
118
 
120
119
  /**
121
120
  * The column field of the cell that triggered the event.
122
121
  */
123
- field: PropTypes.string.isRequired,
122
+ field: PropTypes.string,
124
123
 
125
124
  /**
126
125
  * The cell value formatted with the column valueFormatter.
@@ -134,17 +133,17 @@ process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
134
133
  * @returns {any} The cell value.
135
134
  * @deprecated Use `params.row` to directly access the fields you want instead.
136
135
  */
137
- getValue: PropTypes.func.isRequired,
136
+ getValue: PropTypes.func,
138
137
 
139
138
  /**
140
139
  * If true, the cell is the active element.
141
140
  */
142
- hasFocus: PropTypes.bool.isRequired,
141
+ hasFocus: PropTypes.bool,
143
142
 
144
143
  /**
145
144
  * The grid row id.
146
145
  */
147
- id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
146
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
148
147
 
149
148
  /**
150
149
  * If true, the cell is editable.
@@ -164,17 +163,17 @@ process.env.NODE_ENV !== "production" ? GridEditInputCell.propTypes = {
164
163
  /**
165
164
  * The row model of the row that the current cell belongs to.
166
165
  */
167
- row: PropTypes.object.isRequired,
166
+ row: PropTypes.object,
168
167
 
169
168
  /**
170
169
  * The node of the row that the current cell belongs to.
171
170
  */
172
- rowNode: PropTypes.object.isRequired,
171
+ rowNode: PropTypes.object,
173
172
 
174
173
  /**
175
174
  * the tabIndex value.
176
175
  */
177
- tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
176
+ tabIndex: PropTypes.oneOf([-1, 0]),
178
177
 
179
178
  /**
180
179
  * The cell value, but if the column has valueGetter, use getValue.
@@ -1,6 +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 = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "getValue", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange"];
3
+ const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "getValue", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/material/utils';
@@ -24,6 +24,8 @@ const renderSingleSelectOptions = (option, OptionComponent) => {
24
24
  };
25
25
 
26
26
  function GridEditSingleSelectCell(props) {
27
+ const rootProps = useGridRootProps();
28
+
27
29
  const {
28
30
  id,
29
31
  value,
@@ -33,15 +35,15 @@ function GridEditSingleSelectCell(props) {
33
35
  colDef,
34
36
  hasFocus,
35
37
  error,
36
- onValueChange
38
+ onValueChange,
39
+ initialOpen = rootProps.editMode === GridEditModes.Cell
37
40
  } = props,
38
41
  other = _objectWithoutPropertiesLoose(props, _excluded);
39
42
 
40
43
  const apiRef = useGridApiContext();
41
44
  const ref = React.useRef();
42
45
  const inputRef = React.useRef();
43
- const rootProps = useGridRootProps();
44
- const [open, setOpen] = React.useState(rootProps.editMode === 'cell');
46
+ const [open, setOpen] = React.useState(initialOpen);
45
47
  const baseSelectProps = rootProps.componentsProps?.baseSelect || {};
46
48
  const isSelectNative = baseSelectProps.native ?? false;
47
49
  let valueOptionsFormatted;
@@ -212,6 +214,11 @@ process.env.NODE_ENV !== "production" ? GridEditSingleSelectCell.propTypes = {
212
214
  */
213
215
  id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
214
216
 
217
+ /**
218
+ * If true, the select opens by default.
219
+ */
220
+ initialOpen: PropTypes.bool,
221
+
215
222
  /**
216
223
  * If true, the cell is editable.
217
224
  */
@@ -81,6 +81,11 @@ const GridCellCheckboxForwardRef = /*#__PURE__*/React.forwardRef(function GridCe
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
+
84
89
  return /*#__PURE__*/_jsx(rootProps.components.BaseCheckbox, _extends({
85
90
  ref: handleRef,
86
91
  tabIndex: tabIndex,
@@ -12,7 +12,7 @@ import { useGridSelector } from '../../hooks/utils/useGridSelector';
12
12
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
13
13
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
14
14
  import { getDataGridUtilityClass } from '../../constants/gridClasses';
15
- import { gridRowCountSelector } from '../../hooks/features/rows/gridRowsSelector';
15
+ import { gridPinnedRowsCountSelector, gridRowCountSelector } from '../../hooks/features/rows/gridRowsSelector';
16
16
  import { gridDensityValueSelector } from '../../hooks/features/density/densitySelector';
17
17
  import { jsx as _jsx } from "react/jsx-runtime";
18
18
 
@@ -43,6 +43,7 @@ const GridRoot = /*#__PURE__*/React.forwardRef(function GridRoot(props, ref) {
43
43
  const densityValue = useGridSelector(apiRef, gridDensityValueSelector);
44
44
  const rootContainerRef = React.useRef(null);
45
45
  const handleRef = useForkRef(rootContainerRef, ref);
46
+ const pinnedRowsCount = useGridSelector(apiRef, gridPinnedRowsCountSelector);
46
47
  const ownerState = {
47
48
  density: densityValue,
48
49
  classes: rootProps.classes,
@@ -70,7 +71,8 @@ const GridRoot = /*#__PURE__*/React.forwardRef(function GridRoot(props, ref) {
70
71
  className: clsx(className, classes.root),
71
72
  role: "grid",
72
73
  "aria-colcount": visibleColumns.length,
73
- "aria-rowcount": totalRowCount,
74
+ "aria-rowcount": totalRowCount + pinnedRowsCount + 1 // +1 for the header row
75
+ ,
74
76
  "aria-multiselectable": !rootProps.disableMultipleSelection,
75
77
  "aria-label": rootProps['aria-label'],
76
78
  "aria-labelledby": rootProps['aria-labelledby']
@@ -57,11 +57,18 @@ export const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function
57
57
  }, [densityValue, rootProps]);
58
58
 
59
59
  const handleDensitySelectorOpen = event => {
60
- setOpen(true);
60
+ setOpen(prevOpen => !prevOpen);
61
61
  onClick?.(event);
62
62
  };
63
63
 
64
- const handleDensitySelectorClose = () => setOpen(false);
64
+ const handleDensitySelectorClickAway = event => {
65
+ if (buttonRef.current === event.target || // if user clicked on the icon
66
+ buttonRef.current?.contains(event.target)) {
67
+ return;
68
+ }
69
+
70
+ setOpen(false);
71
+ };
65
72
 
66
73
  const handleDensityUpdate = newDensity => {
67
74
  apiRef.current.setDensity(newDensity);
@@ -74,7 +81,7 @@ export const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function
74
81
  }
75
82
 
76
83
  if (isHideMenuKey(event.key)) {
77
- handleDensitySelectorClose();
84
+ setOpen(false);
78
85
  }
79
86
  }; // Disable the button if the corresponding is disabled
80
87
 
@@ -107,7 +114,7 @@ export const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function
107
114
  })), /*#__PURE__*/_jsx(GridMenu, {
108
115
  open: open,
109
116
  target: buttonRef.current,
110
- onClickAway: handleDensitySelectorClose,
117
+ onClickAway: handleDensitySelectorClickAway,
111
118
  position: "bottom-start",
112
119
  children: /*#__PURE__*/_jsx(MenuList, {
113
120
  id: densityMenuId,
@@ -27,7 +27,7 @@ export const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function
27
27
  const handleRef = useForkRef(ref, buttonRef);
28
28
 
29
29
  const handleMenuOpen = event => {
30
- setOpen(true);
30
+ setOpen(prevOpen => !prevOpen);
31
31
  onClick?.(event);
32
32
  };
33
33
 
@@ -43,6 +43,15 @@ export const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function
43
43
  }
44
44
  };
45
45
 
46
+ const handleMenuClickAway = event => {
47
+ if (buttonRef.current === event.target || // if user clicked on the icon
48
+ buttonRef.current?.contains(event.target)) {
49
+ return;
50
+ }
51
+
52
+ setOpen(false);
53
+ };
54
+
46
55
  if (children == null) {
47
56
  return null;
48
57
  }
@@ -64,7 +73,7 @@ export const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function
64
73
  })), /*#__PURE__*/_jsx(GridMenu, {
65
74
  open: open,
66
75
  target: buttonRef.current,
67
- onClickAway: handleMenuClose,
76
+ onClickAway: handleMenuClickAway,
68
77
  position: "bottom-start",
69
78
  children: /*#__PURE__*/_jsx(MenuList, {
70
79
  id: menuId,
@@ -1,4 +1,4 @@
1
- import { localStorageAvailable } from '../utils/utils'; // A guide to feature toggling.
1
+ // A guide to feature toggling (deprecated)
2
2
  //
3
3
  // The feature toggle is:
4
4
  // - independent from the NODE_ENV
@@ -15,13 +15,4 @@ import { localStorageAvailable } from '../utils/utils'; // A guide to feature to
15
15
  //
16
16
  // Developers (users) are discouraged to enable the experimental feature by setting the GRID_EXPERIMENTAL_ENABLED env.
17
17
  // Instead, prefer exposing experimental APIs, for instance, a prop or a new `unstable_` module.
18
-
19
- let experimentalEnabled = false;
20
-
21
- if (typeof process !== 'undefined' && process.env.GRID_EXPERIMENTAL_ENABLED !== undefined && localStorageAvailable() && window.localStorage.getItem('GRID_EXPERIMENTAL_ENABLED')) {
22
- experimentalEnabled = window.localStorage.getItem('GRID_EXPERIMENTAL_ENABLED') === 'true';
23
- } else if (typeof process !== 'undefined') {
24
- experimentalEnabled = process.env.GRID_EXPERIMENTAL_ENABLED === 'true';
25
- }
26
-
27
- export const GRID_EXPERIMENTAL_ENABLED = experimentalEnabled;
18
+ export const GRID_EXPERIMENTAL_ENABLED = false;
@@ -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', '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']);
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', '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']);
@@ -19,7 +19,7 @@ export const GRID_DEFAULT_LOCALE_TEXT = {
19
19
  toolbarFiltersTooltipShow: 'Show filters',
20
20
  toolbarFiltersTooltipActive: count => count !== 1 ? `${count} active filters` : `${count} active filter`,
21
21
  // Quick filter toolbar field
22
- toolbarQuickFilterPlaceholder: 'Search...',
22
+ toolbarQuickFilterPlaceholder: 'Search',
23
23
  toolbarQuickFilterLabel: 'Search',
24
24
  toolbarQuickFilterDeleteIconLabel: 'Clear',
25
25
  // Export selector toolbar button text
@@ -8,6 +8,7 @@ import { gridDensityHeaderHeightSelector, gridDensityRowHeightSelector } from '.
8
8
  import { useGridSelector } from '../../utils';
9
9
  import { getVisibleRows } from '../../utils/useGridVisibleRows';
10
10
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
11
+ import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
11
12
  const isTestEnvironment = process.env.NODE_ENV === 'test';
12
13
 
13
14
  const hasScroll = ({
@@ -45,6 +46,7 @@ export function useGridDimensions(apiRef, props) {
45
46
  const updateGridDimensionsRef = React.useCallback(() => {
46
47
  const rootElement = apiRef.current.rootElementRef?.current;
47
48
  const columnsTotalWidth = gridColumnsTotalWidthSelector(apiRef);
49
+ const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
48
50
 
49
51
  if (!rootDimensionsRef.current) {
50
52
  return;
@@ -90,7 +92,10 @@ export function useGridDimensions(apiRef, props) {
90
92
  width: Math.round(columnsTotalWidth),
91
93
  height: rowsMeta.currentPageTotalHeight
92
94
  },
93
- container: viewportOuterSize,
95
+ container: {
96
+ width: viewportOuterSize.width,
97
+ height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
98
+ },
94
99
  scrollBarSize
95
100
  });
96
101
  hasScrollY = scrollInformation.hasScrollY;
@@ -15,6 +15,7 @@ import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../mode
15
15
  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
16
  export const useGridCellEditing = (apiRef, props) => {
17
17
  const [cellModesModel, setCellModesModel] = React.useState({});
18
+ const cellModesModelRef = React.useRef(cellModesModel);
18
19
  const prevCellModesModel = React.useRef({});
19
20
  const {
20
21
  processRowUpdate,
@@ -62,6 +63,10 @@ export const useGridCellEditing = (apiRef, props) => {
62
63
  return;
63
64
  }
64
65
 
66
+ if (apiRef.current.getCellMode(params.id, params.field) === GridCellModes.View) {
67
+ return;
68
+ }
69
+
65
70
  const newParams = _extends({}, params, {
66
71
  reason: GridCellEditStopReasons.cellFocusOut
67
72
  });
@@ -97,15 +102,14 @@ export const useGridCellEditing = (apiRef, props) => {
97
102
  } else if (params.isEditable) {
98
103
  let reason;
99
104
 
100
- if (isPrintableKey(event.key)) {
101
- if (event.ctrlKey && event.key !== 'v' || event.metaKey && event.key !== 'v' || event.altKey) {
102
- return;
103
- }
104
-
105
+ if (isPrintableKey(event)) {
106
+ reason = GridCellEditStartReasons.printableKeyDown;
107
+ } else if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
105
108
  reason = GridCellEditStartReasons.printableKeyDown;
106
109
  } else if (event.key === 'Enter') {
107
110
  reason = GridCellEditStartReasons.enterKeyDown;
108
- } else if (event.key === 'Delete') {
111
+ } else if (event.key === 'Delete' || event.key === 'Backspace') {
112
+ // Delete on Windows, Backspace on macOS
109
113
  reason = GridCellEditStartReasons.deleteKeyDown;
110
114
  }
111
115
 
@@ -141,6 +145,7 @@ export const useGridCellEditing = (apiRef, props) => {
141
145
  field,
142
146
  reason
143
147
  } = params;
148
+ apiRef.current.unstable_runPendingEditCellValueMutation(id, field);
144
149
  let cellToFocusAfter;
145
150
 
146
151
  if (reason === GridCellEditStopReasons.enterKeyDown) {
@@ -154,7 +159,7 @@ export const useGridCellEditing = (apiRef, props) => {
154
159
  let ignoreModifications = reason === 'escapeKeyDown';
155
160
  const editingState = gridEditRowsStateSelector(apiRef.current.state);
156
161
 
157
- if (editingState[id][field].isProcessingProps) {
162
+ if (editingState[id][field].isProcessingProps && !props.disableIgnoreModificationsIfProcessingProps) {
158
163
  // The user wants to stop editing the cell but we can't wait for the props to be processed.
159
164
  // In this case, discard the modifications.
160
165
  ignoreModifications = true;
@@ -166,7 +171,7 @@ export const useGridCellEditing = (apiRef, props) => {
166
171
  ignoreModifications,
167
172
  cellToFocusAfter
168
173
  });
169
- }, [apiRef]);
174
+ }, [apiRef, props.disableIgnoreModificationsIfProcessingProps]);
170
175
  useGridApiEventHandler(apiRef, 'cellDoubleClick', runIfEditModeIsCell(handleCellDoubleClick));
171
176
  useGridApiEventHandler(apiRef, 'cellFocusOut', runIfEditModeIsCell(handleCellFocusOut));
172
177
  useGridApiEventHandler(apiRef, 'cellKeyDown', runIfEditModeIsCell(handleCellKeyDown));
@@ -194,18 +199,21 @@ export const useGridCellEditing = (apiRef, props) => {
194
199
  }
195
200
 
196
201
  setCellModesModel(newModel);
202
+ cellModesModelRef.current = newModel;
197
203
  apiRef.current.publishEvent('cellModesModelChange', newModel);
198
204
  }, [apiRef, onCellModesModelChange, props.cellModesModel, signature]);
199
205
  const updateFieldInCellModesModel = React.useCallback((id, field, newProps) => {
200
- const newModel = _extends({}, cellModesModel);
206
+ // We use the ref because it always contain the up-to-date value, different from the state
207
+ // that needs a rerender to reflect the new value
208
+ const newModel = _extends({}, cellModesModelRef.current);
201
209
 
202
210
  if (newProps !== null) {
203
211
  newModel[id] = _extends({}, newModel[id], {
204
212
  [field]: _extends({}, newProps)
205
213
  });
206
214
  } else {
207
- const _cellModesModel$id = cellModesModel[id],
208
- otherFields = _objectWithoutPropertiesLoose(_cellModesModel$id, [field].map(_toPropertyKey)); // Ensure that we have a new object, not a reference
215
+ const _newModel$id = newModel[id],
216
+ otherFields = _objectWithoutPropertiesLoose(_newModel$id, [field].map(_toPropertyKey)); // Ensure that we have a new object, not a reference
209
217
 
210
218
 
211
219
  newModel[id] = otherFields;
@@ -216,7 +224,7 @@ export const useGridCellEditing = (apiRef, props) => {
216
224
  }
217
225
 
218
226
  updateCellModesModel(newModel);
219
- }, [cellModesModel, updateCellModesModel]);
227
+ }, [updateCellModesModel]);
220
228
  const updateOrDeleteFieldState = React.useCallback((id, field, newProps) => {
221
229
  apiRef.current.setState(state => {
222
230
  const newEditingState = _extends({}, state.editRows);
@@ -289,12 +297,12 @@ export const useGridCellEditing = (apiRef, props) => {
289
297
  apiRef.current.unstable_runPendingEditCellValueMutation(id, field);
290
298
 
291
299
  const finishCellEditMode = () => {
300
+ updateOrDeleteFieldState(id, field, null);
301
+ updateFieldInCellModesModel(id, field, null);
302
+
292
303
  if (cellToFocusAfter !== 'none') {
293
304
  apiRef.current.unstable_moveFocusToRelativeCell(id, field, cellToFocusAfter);
294
305
  }
295
-
296
- updateOrDeleteFieldState(id, field, null);
297
- updateFieldInCellModesModel(id, field, null);
298
306
  };
299
307
 
300
308
  if (ignoreModifications) {
@@ -394,7 +402,7 @@ export const useGridCellEditing = (apiRef, props) => {
394
402
  newProps.value = column.preProcessEditCellProps ? editingState[id][field].value : parsedValue;
395
403
  updateOrDeleteFieldState(id, field, newProps);
396
404
  editingState = gridEditRowsStateSelector(apiRef.current.state);
397
- return !editingState[id][field].error;
405
+ return !editingState[id]?.[field]?.error;
398
406
  }, [apiRef, throwIfNotEditable, throwIfNotInMode, updateOrDeleteFieldState]);
399
407
  const getRowWithUpdatedValuesFromCellEditing = React.useCallback((id, field) => {
400
408
  const column = apiRef.current.getColumn(field);
@@ -195,7 +195,7 @@ export const useCellEditing = (apiRef, props) => {
195
195
  const isEditMode = cellMode === GridCellModes.Edit;
196
196
  const isModifierKeyPressed = event.ctrlKey || event.metaKey || event.altKey;
197
197
 
198
- if (!isEditMode && isCellEnterEditModeKeys(event.key) && !isModifierKeyPressed && !(event.key === ' ' && event.shiftKey)) {
198
+ if (!isEditMode && isCellEnterEditModeKeys(event) && !isModifierKeyPressed && !(event.key === ' ' && event.shiftKey)) {
199
199
  apiRef.current.publishEvent('cellEditStart', params, event);
200
200
  }
201
201
 
@@ -265,7 +265,7 @@ export const useCellEditing = (apiRef, props) => {
265
265
 
266
266
  apiRef.current.setCellMode(params.id, params.field, GridCellModes.Edit);
267
267
 
268
- if (isKeyboardEvent(event) && isPrintableKey(event.key)) {
268
+ if (isKeyboardEvent(event) && isPrintableKey(event)) {
269
269
  apiRef.current.unstable_setEditCellProps({
270
270
  id: params.id,
271
271
  field: params.field,
@@ -31,6 +31,10 @@ export const useGridEditing = (apiRef, props) => {
31
31
  return isCellEditableProp(params);
32
32
  }
33
33
 
34
+ if (params.rowNode.isPinned) {
35
+ return false;
36
+ }
37
+
34
38
  return true;
35
39
  }, [isCellEditableProp]);
36
40
 
@@ -28,7 +28,7 @@ export function useGridEditing(apiRef, props) {
28
28
  stateSelector: gridEditRowsStateSelector,
29
29
  changeEvent: 'editRowsModelChange'
30
30
  });
31
- const isCellEditable = React.useCallback(params => !params.rowNode.isAutoGenerated && !!params.colDef.editable && !!params.colDef.renderEditCell && (!props.isCellEditable || props.isCellEditable(params)), // eslint-disable-next-line react-hooks/exhaustive-deps
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
32
  [props.isCellEditable]);
33
33
 
34
34
  const maybeDebounce = (id, field, debounceMs, callback) => {
@@ -16,6 +16,7 @@ import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models
16
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');
17
17
  export const useGridRowEditing = (apiRef, props) => {
18
18
  const [rowModesModel, setRowModesModel] = React.useState({});
19
+ const rowModesModelRef = React.useRef(rowModesModel);
19
20
  const prevRowModesModel = React.useRef({});
20
21
  const focusTimeout = React.useRef(null);
21
22
  const nextFocusedCell = React.useRef(null);
@@ -88,6 +89,11 @@ export const useGridRowEditing = (apiRef, props) => {
88
89
  // The row might have been deleted during the click
89
90
  if (!apiRef.current.getRow(params.id)) {
90
91
  return;
92
+ } // The row may already changed its mode
93
+
94
+
95
+ if (apiRef.current.getRowMode(params.id) === GridRowModes.View) {
96
+ return;
91
97
  }
92
98
 
93
99
  const rowParams = apiRef.current.getRowParams(params.id);
@@ -151,15 +157,14 @@ export const useGridRowEditing = (apiRef, props) => {
151
157
  } else if (params.isEditable) {
152
158
  let reason;
153
159
 
154
- if (isPrintableKey(event.key)) {
155
- if (event.ctrlKey && event.key !== 'v' || event.metaKey && event.key !== 'v' || event.altKey) {
156
- return;
157
- }
158
-
160
+ if (isPrintableKey(event)) {
161
+ reason = GridRowEditStartReasons.printableKeyDown;
162
+ } else if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
159
163
  reason = GridRowEditStartReasons.printableKeyDown;
160
164
  } else if (event.key === 'Enter') {
161
165
  reason = GridRowEditStartReasons.enterKeyDown;
162
- } else if (event.key === 'Delete') {
166
+ } else if (event.key === 'Delete' || event.key === 'Backspace') {
167
+ // Delete on Windows, Backspace on macOS
163
168
  reason = GridRowEditStartReasons.deleteKeyDown;
164
169
  }
165
170
 
@@ -212,7 +217,7 @@ export const useGridRowEditing = (apiRef, props) => {
212
217
  let ignoreModifications = reason === 'escapeKeyDown';
213
218
  const editingState = gridEditRowsStateSelector(apiRef.current.state);
214
219
 
215
- if (!ignoreModifications) {
220
+ if (!ignoreModifications && !props.disableIgnoreModificationsIfProcessingProps) {
216
221
  // The user wants to stop editing the cell but we can't wait for the props to be processed.
217
222
  // In this case, discard the modifications if any field is processing its props.
218
223
  ignoreModifications = Object.values(editingState[id]).some(fieldProps => {
@@ -226,7 +231,7 @@ export const useGridRowEditing = (apiRef, props) => {
226
231
  field,
227
232
  cellToFocusAfter
228
233
  });
229
- }, [apiRef]);
234
+ }, [apiRef, props.disableIgnoreModificationsIfProcessingProps]);
230
235
  useGridApiEventHandler(apiRef, 'cellDoubleClick', runIfEditModeIsRow(handleCellDoubleClick));
231
236
  useGridApiEventHandler(apiRef, 'cellFocusIn', runIfEditModeIsRow(handleCellFocusIn));
232
237
  useGridApiEventHandler(apiRef, 'cellFocusOut', runIfEditModeIsRow(handleCellFocusOut));
@@ -259,10 +264,11 @@ export const useGridRowEditing = (apiRef, props) => {
259
264
  }
260
265
 
261
266
  setRowModesModel(newModel);
267
+ rowModesModelRef.current = newModel;
262
268
  apiRef.current.publishEvent('rowModesModelChange', newModel);
263
269
  }, [apiRef, onRowModesModelChange, props.rowModesModel, signature]);
264
270
  const updateRowInRowModesModel = React.useCallback((id, newProps) => {
265
- const newModel = _extends({}, rowModesModel);
271
+ const newModel = _extends({}, rowModesModelRef.current);
266
272
 
267
273
  if (newProps !== null) {
268
274
  newModel[id] = _extends({}, newProps);
@@ -271,7 +277,7 @@ export const useGridRowEditing = (apiRef, props) => {
271
277
  }
272
278
 
273
279
  updateRowModesModel(newModel);
274
- }, [rowModesModel, updateRowModesModel]);
280
+ }, [updateRowModesModel]);
275
281
  const updateOrDeleteRowState = React.useCallback((id, newProps) => {
276
282
  apiRef.current.setState(state => {
277
283
  const newEditingState = _extends({}, state.editRows);
@@ -1,6 +1,6 @@
1
1
  import { gridColumnDefinitionsSelector, gridVisibleColumnDefinitionsSelector } from '../columns';
2
2
  import { gridFilteredSortedRowIdsSelector } from '../filter';
3
- import { gridRowTreeSelector } from '../rows/gridRowsSelector';
3
+ import { gridPinnedRowsSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
4
4
  export const getColumnsToExport = ({
5
5
  apiRef,
6
6
  options
@@ -21,6 +21,11 @@ export const defaultGetRowsToExport = ({
21
21
  const rowTree = gridRowTreeSelector(apiRef);
22
22
  const selectedRows = apiRef.current.getSelectedRows();
23
23
  const bodyRows = filteredSortedRowIds.filter(id => (rowTree[id].position ?? 'body') === 'body');
24
+ const pinnedRows = gridPinnedRowsSelector(apiRef);
25
+ const topPinnedRowsIds = pinnedRows?.top?.map(row => row.id) || [];
26
+ const bottomPinnedRowsIds = pinnedRows?.bottom?.map(row => row.id) || [];
27
+ bodyRows.unshift(...topPinnedRowsIds);
28
+ bodyRows.push(...bottomPinnedRowsIds);
24
29
 
25
30
  if (selectedRows.size > 0) {
26
31
  return bodyRows.filter(id => selectedRows.has(id));