@mui/x-data-grid 7.27.2 → 7.28.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 (168) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +1 -1
  3. package/components/cell/GridActionsCell.js +3 -1
  4. package/components/cell/GridCell.js +2 -2
  5. package/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  6. package/components/containers/GridRootStyles.js +3 -3
  7. package/components/panel/filterPanel/GridFilterInputValue.d.ts +4 -0
  8. package/components/panel/filterPanel/index.d.ts +1 -1
  9. package/components/panel/filterPanel/index.js +1 -1
  10. package/components/virtualization/GridBottomContainer.js +1 -1
  11. package/components/virtualization/GridTopContainer.js +1 -1
  12. package/components/virtualization/GridVirtualScrollbar.js +9 -3
  13. package/constants/localeTextConstants.js +1 -0
  14. package/hooks/features/editing/useGridRowEditing.js +19 -10
  15. package/hooks/features/export/useGridPrintExport.js +4 -4
  16. package/hooks/features/filter/useGridFilter.js +5 -0
  17. package/hooks/features/rowSelection/useGridRowSelection.js +47 -11
  18. package/hooks/features/rowSelection/utils.d.ts +2 -2
  19. package/hooks/features/rowSelection/utils.js +8 -6
  20. package/hooks/features/rows/useGridRowsMeta.js +8 -0
  21. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +0 -2
  22. package/hooks/features/virtualization/useGridVirtualScroller.js +0 -2
  23. package/index.js +1 -1
  24. package/locales/arSD.js +1 -0
  25. package/locales/beBY.js +1 -0
  26. package/locales/bgBG.js +1 -0
  27. package/locales/bnBD.js +1 -0
  28. package/locales/csCZ.js +6 -6
  29. package/locales/daDK.js +1 -0
  30. package/locales/deDE.js +1 -0
  31. package/locales/elGR.js +1 -0
  32. package/locales/esES.js +1 -0
  33. package/locales/faIR.js +1 -0
  34. package/locales/fiFI.js +1 -0
  35. package/locales/frFR.js +1 -0
  36. package/locales/heIL.js +1 -0
  37. package/locales/hrHR.js +1 -0
  38. package/locales/huHU.js +1 -0
  39. package/locales/isIS.js +1 -0
  40. package/locales/itIT.js +1 -0
  41. package/locales/jaJP.js +1 -0
  42. package/locales/koKR.js +2 -1
  43. package/locales/nbNO.js +1 -0
  44. package/locales/nlNL.js +1 -0
  45. package/locales/nnNO.js +1 -0
  46. package/locales/plPL.js +1 -0
  47. package/locales/ptBR.js +1 -0
  48. package/locales/ptPT.js +1 -0
  49. package/locales/roRO.js +1 -0
  50. package/locales/ruRU.js +1 -0
  51. package/locales/skSK.js +7 -7
  52. package/locales/svSE.js +1 -0
  53. package/locales/trTR.js +1 -0
  54. package/locales/ukUA.js +1 -0
  55. package/locales/urPK.js +1 -0
  56. package/locales/viVN.js +1 -0
  57. package/locales/zhCN.js +1 -0
  58. package/locales/zhHK.js +11 -11
  59. package/locales/zhTW.js +10 -10
  60. package/models/api/gridLocaleTextApi.d.ts +1 -0
  61. package/models/api/gridRowSelectionApi.d.ts +15 -4
  62. package/modern/components/cell/GridActionsCell.js +3 -1
  63. package/modern/components/cell/GridCell.js +2 -2
  64. package/modern/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  65. package/modern/components/containers/GridRootStyles.js +3 -3
  66. package/modern/components/panel/filterPanel/index.js +1 -1
  67. package/modern/components/virtualization/GridBottomContainer.js +1 -1
  68. package/modern/components/virtualization/GridTopContainer.js +1 -1
  69. package/modern/components/virtualization/GridVirtualScrollbar.js +9 -3
  70. package/modern/constants/localeTextConstants.js +1 -0
  71. package/modern/hooks/features/editing/useGridRowEditing.js +19 -10
  72. package/modern/hooks/features/export/useGridPrintExport.js +4 -4
  73. package/modern/hooks/features/filter/useGridFilter.js +5 -0
  74. package/modern/hooks/features/rowSelection/useGridRowSelection.js +47 -11
  75. package/modern/hooks/features/rowSelection/utils.js +8 -6
  76. package/modern/hooks/features/rows/useGridRowsMeta.js +8 -0
  77. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +0 -2
  78. package/modern/index.js +1 -1
  79. package/modern/locales/arSD.js +1 -0
  80. package/modern/locales/beBY.js +1 -0
  81. package/modern/locales/bgBG.js +1 -0
  82. package/modern/locales/bnBD.js +1 -0
  83. package/modern/locales/csCZ.js +6 -6
  84. package/modern/locales/daDK.js +1 -0
  85. package/modern/locales/deDE.js +1 -0
  86. package/modern/locales/elGR.js +1 -0
  87. package/modern/locales/esES.js +1 -0
  88. package/modern/locales/faIR.js +1 -0
  89. package/modern/locales/fiFI.js +1 -0
  90. package/modern/locales/frFR.js +1 -0
  91. package/modern/locales/heIL.js +1 -0
  92. package/modern/locales/hrHR.js +1 -0
  93. package/modern/locales/huHU.js +1 -0
  94. package/modern/locales/isIS.js +1 -0
  95. package/modern/locales/itIT.js +1 -0
  96. package/modern/locales/jaJP.js +1 -0
  97. package/modern/locales/koKR.js +2 -1
  98. package/modern/locales/nbNO.js +1 -0
  99. package/modern/locales/nlNL.js +1 -0
  100. package/modern/locales/nnNO.js +1 -0
  101. package/modern/locales/plPL.js +1 -0
  102. package/modern/locales/ptBR.js +1 -0
  103. package/modern/locales/ptPT.js +1 -0
  104. package/modern/locales/roRO.js +1 -0
  105. package/modern/locales/ruRU.js +1 -0
  106. package/modern/locales/skSK.js +7 -7
  107. package/modern/locales/svSE.js +1 -0
  108. package/modern/locales/trTR.js +1 -0
  109. package/modern/locales/ukUA.js +1 -0
  110. package/modern/locales/urPK.js +1 -0
  111. package/modern/locales/viVN.js +1 -0
  112. package/modern/locales/zhCN.js +1 -0
  113. package/modern/locales/zhHK.js +11 -11
  114. package/modern/locales/zhTW.js +10 -10
  115. package/node/components/cell/GridActionsCell.js +3 -1
  116. package/node/components/cell/GridCell.js +2 -2
  117. package/node/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  118. package/node/components/containers/GridRootStyles.js +3 -3
  119. package/node/components/panel/filterPanel/index.js +7 -11
  120. package/node/components/virtualization/GridBottomContainer.js +1 -1
  121. package/node/components/virtualization/GridTopContainer.js +1 -1
  122. package/node/components/virtualization/GridVirtualScrollbar.js +9 -3
  123. package/node/constants/localeTextConstants.js +1 -0
  124. package/node/hooks/features/editing/useGridRowEditing.js +19 -10
  125. package/node/hooks/features/export/useGridPrintExport.js +4 -4
  126. package/node/hooks/features/filter/useGridFilter.js +5 -0
  127. package/node/hooks/features/rowSelection/useGridRowSelection.js +55 -19
  128. package/node/hooks/features/rowSelection/utils.js +7 -5
  129. package/node/hooks/features/rows/useGridRowsMeta.js +8 -0
  130. package/node/hooks/features/virtualization/useGridVirtualScroller.js +0 -2
  131. package/node/index.js +1 -1
  132. package/node/locales/arSD.js +1 -0
  133. package/node/locales/beBY.js +1 -0
  134. package/node/locales/bgBG.js +1 -0
  135. package/node/locales/bnBD.js +1 -0
  136. package/node/locales/csCZ.js +6 -6
  137. package/node/locales/daDK.js +1 -0
  138. package/node/locales/deDE.js +1 -0
  139. package/node/locales/elGR.js +1 -0
  140. package/node/locales/esES.js +1 -0
  141. package/node/locales/faIR.js +1 -0
  142. package/node/locales/fiFI.js +1 -0
  143. package/node/locales/frFR.js +1 -0
  144. package/node/locales/heIL.js +1 -0
  145. package/node/locales/hrHR.js +1 -0
  146. package/node/locales/huHU.js +1 -0
  147. package/node/locales/isIS.js +1 -0
  148. package/node/locales/itIT.js +1 -0
  149. package/node/locales/jaJP.js +1 -0
  150. package/node/locales/koKR.js +2 -1
  151. package/node/locales/nbNO.js +1 -0
  152. package/node/locales/nlNL.js +1 -0
  153. package/node/locales/nnNO.js +1 -0
  154. package/node/locales/plPL.js +1 -0
  155. package/node/locales/ptBR.js +1 -0
  156. package/node/locales/ptPT.js +1 -0
  157. package/node/locales/roRO.js +1 -0
  158. package/node/locales/ruRU.js +1 -0
  159. package/node/locales/skSK.js +7 -7
  160. package/node/locales/svSE.js +1 -0
  161. package/node/locales/trTR.js +1 -0
  162. package/node/locales/ukUA.js +1 -0
  163. package/node/locales/urPK.js +1 -0
  164. package/node/locales/viVN.js +1 -0
  165. package/node/locales/zhCN.js +1 -0
  166. package/node/locales/zhHK.js +11 -11
  167. package/node/locales/zhTW.js +10 -10
  168. package/package.json +5 -5
@@ -13,7 +13,7 @@ const useUtilityClasses = () => {
13
13
  };
14
14
  const Element = styled('div')({
15
15
  position: 'sticky',
16
- zIndex: 4,
16
+ zIndex: 40,
17
17
  bottom: 'calc(var(--DataGrid-hasScrollX) * var(--DataGrid-scrollbarSize))'
18
18
  });
19
19
  export function GridBottomContainer(props) {
@@ -13,7 +13,7 @@ const useUtilityClasses = () => {
13
13
  };
14
14
  const Element = styled('div')({
15
15
  position: 'sticky',
16
- zIndex: 4,
16
+ zIndex: 40,
17
17
  top: 0
18
18
  });
19
19
  export function GridTopContainer(props) {
@@ -21,9 +21,9 @@ const useUtilityClasses = (ownerState, position) => {
21
21
  const Scrollbar = styled('div')({
22
22
  position: 'absolute',
23
23
  display: 'inline-block',
24
- zIndex: 6,
24
+ zIndex: 60,
25
25
  '&:hover': {
26
- zIndex: 7
26
+ zIndex: 70
27
27
  },
28
28
  // In macOS Safari and Gnome Web, scrollbars are overlaid and don't affect the layout. So we consider
29
29
  // their size to be 0px throughout all the calculations, but the floating scrollbar container does need
@@ -130,7 +130,13 @@ const GridVirtualScrollbar = forwardRef(function GridVirtualScrollbar(props, ref
130
130
  top: 0
131
131
  } : undefined,
132
132
  tabIndex: -1,
133
- "aria-hidden": "true",
133
+ "aria-hidden": "true"
134
+ // tabIndex does not prevent focus with a mouse click, throwing a console error
135
+ // https://github.com/mui/mui-x/issues/16706
136
+ ,
137
+ onFocus: event => {
138
+ event.target.blur();
139
+ },
134
140
  children: /*#__PURE__*/_jsx("div", {
135
141
  ref: contentRef,
136
142
  className: classes.content
@@ -94,6 +94,7 @@ export const GRID_DEFAULT_LOCALE_TEXT = {
94
94
  filterValueFalse: 'false',
95
95
  // Column menu text
96
96
  columnMenuLabel: 'Menu',
97
+ columnMenuAriaLabel: columnName => `${columnName} column menu`,
97
98
  columnMenuShowColumns: 'Show columns',
98
99
  columnMenuManageColumns: 'Manage columns',
99
100
  columnMenuFilter: 'Filter',
@@ -21,6 +21,7 @@ export const useGridRowEditing = (apiRef, props) => {
21
21
  const [rowModesModel, setRowModesModel] = React.useState({});
22
22
  const rowModesModelRef = React.useRef(rowModesModel);
23
23
  const prevRowModesModel = React.useRef({});
24
+ const prevRowValuesLookup = React.useRef({});
24
25
  const focusTimeout = React.useRef(undefined);
25
26
  const nextFocusedCell = React.useRef(null);
26
27
  const {
@@ -311,6 +312,7 @@ export const useGridRowEditing = (apiRef, props) => {
311
312
  deleteValue,
312
313
  initialValue
313
314
  } = params;
315
+ const row = apiRef.current.getRow(id);
314
316
  const columnFields = gridColumnFieldsSelector(apiRef);
315
317
  const newProps = columnFields.reduce((acc, field) => {
316
318
  const cellParams = apiRef.current.getCellParams(id, field);
@@ -333,6 +335,7 @@ export const useGridRowEditing = (apiRef, props) => {
333
335
  };
334
336
  return acc;
335
337
  }, {});
338
+ prevRowValuesLookup.current[id] = row;
336
339
  updateOrDeleteRowState(id, newProps);
337
340
  if (fieldToFocus) {
338
341
  apiRef.current.setCellFocus(id, fieldToFocus);
@@ -343,7 +346,7 @@ export const useGridRowEditing = (apiRef, props) => {
343
346
  const newValue = deleteValue ? getDefaultCellValue(column) : initialValue ?? value;
344
347
  Promise.resolve(column.preProcessEditCellProps({
345
348
  id,
346
- row: apiRef.current.getRow(id),
349
+ row,
347
350
  props: newProps[field],
348
351
  hasChanged: newValue !== value
349
352
  })).then(processedProps => {
@@ -382,13 +385,14 @@ export const useGridRowEditing = (apiRef, props) => {
382
385
  }
383
386
  updateOrDeleteRowState(id, null);
384
387
  updateRowInRowModesModel(id, null);
388
+ delete prevRowValuesLookup.current[id];
385
389
  };
386
390
  if (ignoreModifications) {
387
391
  finishRowEditMode();
388
392
  return;
389
393
  }
390
394
  const editingState = gridEditRowsStateSelector(apiRef.current.state);
391
- const row = apiRef.current.getRow(id);
395
+ const row = prevRowValuesLookup.current[id];
392
396
  const isSomeFieldProcessingProps = Object.values(editingState[id]).some(fieldProps => fieldProps.isProcessingProps);
393
397
  if (isSomeFieldProcessingProps) {
394
398
  prevRowModesModel.current[id].mode = GridRowModes.Edit;
@@ -402,14 +406,17 @@ export const useGridRowEditing = (apiRef, props) => {
402
406
  });
403
407
  return;
404
408
  }
405
- const rowUpdate = apiRef.current.getRowWithUpdatedValuesFromRowEditing(id);
409
+ const rowUpdate = apiRef.current.getRowWithUpdatedValuesFromRowEditing(row.id);
406
410
  if (processRowUpdate) {
407
411
  const handleError = errorThrown => {
408
- prevRowModesModel.current[id].mode = GridRowModes.Edit;
409
- // Revert the mode in the rowModesModel prop back to "edit"
410
- updateRowInRowModesModel(id, {
411
- mode: GridRowModes.Edit
412
- });
412
+ // The row might have been deleted
413
+ if (prevRowModesModel.current[id]) {
414
+ prevRowModesModel.current[id].mode = GridRowModes.Edit;
415
+ // Revert the mode in the rowModesModel prop back to "edit"
416
+ updateRowInRowModesModel(id, {
417
+ mode: GridRowModes.Edit
418
+ });
419
+ }
413
420
  if (onProcessRowUpdateError) {
414
421
  onProcessRowUpdateError(errorThrown);
415
422
  } else if (process.env.NODE_ENV !== 'production') {
@@ -540,10 +547,12 @@ export const useGridRowEditing = (apiRef, props) => {
540
547
  if (!editingState[id]) {
541
548
  return apiRef.current.getRow(id);
542
549
  }
543
- let rowUpdate = _extends({}, row);
550
+ let rowUpdate = _extends({}, prevRowValuesLookup.current[id], row);
544
551
  Object.entries(editingState[id]).forEach(([field, fieldProps]) => {
545
552
  const column = apiRef.current.getColumn(field);
546
- if (column.valueSetter) {
553
+ // Column might have been removed
554
+ // see https://github.com/mui/mui-x/pull/16888
555
+ if (column?.valueSetter) {
547
556
  rowUpdate = column.valueSetter(fieldProps.value, rowUpdate, column, apiRef);
548
557
  } else {
549
558
  rowUpdate[field] = fieldProps.value;
@@ -106,12 +106,13 @@ export const useGridPrintExport = (apiRef, props) => {
106
106
  gridClone.style.contain = 'size';
107
107
  let gridToolbarElementHeight = gridRootElement.querySelector(`.${gridClasses.toolbarContainer}`)?.offsetHeight || 0;
108
108
  let gridFooterElementHeight = gridRootElement.querySelector(`.${gridClasses.footerContainer}`)?.offsetHeight || 0;
109
+ const gridFooterElement = gridClone.querySelector(`.${gridClasses.footerContainer}`);
109
110
  if (normalizeOptions.hideToolbar) {
110
111
  gridClone.querySelector(`.${gridClasses.toolbarContainer}`)?.remove();
111
112
  gridToolbarElementHeight = 0;
112
113
  }
113
- if (normalizeOptions.hideFooter) {
114
- gridClone.querySelector(`.${gridClasses.footerContainer}`)?.remove();
114
+ if (normalizeOptions.hideFooter && gridFooterElement) {
115
+ gridFooterElement.remove();
115
116
  gridFooterElementHeight = 0;
116
117
  }
117
118
 
@@ -120,11 +121,10 @@ export const useGridPrintExport = (apiRef, props) => {
120
121
  gridClone.style.height = `${computedTotalHeight}px`;
121
122
  // The height above does not include grid border width, so we need to exclude it
122
123
  gridClone.style.boxSizing = 'content-box';
123
- if (!normalizeOptions.hideFooter) {
124
+ if (!normalizeOptions.hideFooter && gridFooterElement) {
124
125
  // the footer is always being placed at the bottom of the page as if all rows are exported
125
126
  // so if getRowsToExport is being used to only export a subset of rows then we need to
126
127
  // adjust the footer position to be correctly placed at the bottom of the grid
127
- const gridFooterElement = gridClone.querySelector(`.${gridClasses.footerContainer}`);
128
128
  gridFooterElement.style.position = 'absolute';
129
129
  gridFooterElement.style.width = '100%';
130
130
  gridFooterElement.style.top = `${computedTotalHeight - gridFooterElementHeight}px`;
@@ -228,6 +228,11 @@ export const useGridFilter = (apiRef, props) => {
228
228
  */
229
229
  const stateExportPreProcessing = React.useCallback((prevState, context) => {
230
230
  const filterModelToExport = gridFilterModelSelector(apiRef);
231
+
232
+ // Remove the additional `fromInput` property from the filter model
233
+ filterModelToExport.items.forEach(item => {
234
+ delete item.fromInput;
235
+ });
231
236
  const shouldExportFilterModel =
232
237
  // Always export if the `exportOnlyDirtyModels` property is not activated
233
238
  !context.exportOnlyDirtyModels ||
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
+ import { useEventCallback } from '@mui/material/utils';
3
4
  import { GridSignature, useGridApiEventHandler } from "../../utils/useGridApiEventHandler.js";
4
5
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
5
6
  import { useGridLogger } from "../../utils/useGridLogger.js";
@@ -213,6 +214,19 @@ export const useGridRowSelection = (apiRef, props) => {
213
214
  apiRef.current.setRowSelectionModel(Array.from(newSelection));
214
215
  }
215
216
  }, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents]);
217
+ const getPropagatedRowSelectionModel = React.useCallback(inputSelectionModel => {
218
+ if (!isNestedData || !applyAutoSelection || inputSelectionModel.length === 0) {
219
+ return inputSelectionModel;
220
+ }
221
+ const propagatedSelectionModel = new Set(inputSelectionModel);
222
+ const addRow = rowId => {
223
+ propagatedSelectionModel.add(rowId);
224
+ };
225
+ for (const id of inputSelectionModel) {
226
+ findRowsToSelect(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow, propagatedSelectionModel);
227
+ }
228
+ return Array.from(propagatedSelectionModel);
229
+ }, [apiRef, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, isNestedData, applyAutoSelection]);
216
230
  const selectRowRange = React.useCallback(({
217
231
  startId,
218
232
  endId
@@ -239,7 +253,8 @@ export const useGridRowSelection = (apiRef, props) => {
239
253
  };
240
254
  const selectionPrivateApi = {
241
255
  selectRows,
242
- selectRowRange
256
+ selectRowRange,
257
+ getPropagatedRowSelectionModel
243
258
  };
244
259
  useGridApiMethod(apiRef, selectionPublicApi, 'public');
245
260
  useGridApiMethod(apiRef, selectionPrivateApi, props.signature === GridSignature.DataGrid ? 'private' : 'public');
@@ -247,7 +262,11 @@ export const useGridRowSelection = (apiRef, props) => {
247
262
  /*
248
263
  * EVENTS
249
264
  */
265
+ const isFirstRender = React.useRef(true);
250
266
  const removeOutdatedSelection = React.useCallback((sortModelUpdated = false) => {
267
+ if (isFirstRender.current) {
268
+ return;
269
+ }
251
270
  const currentSelection = gridRowSelectionStateSelector(apiRef.current.state);
252
271
  const rowsLookup = gridRowsLookupSelector(apiRef);
253
272
  const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
@@ -427,8 +446,27 @@ export const useGridRowSelection = (apiRef, props) => {
427
446
  selectRows(apiRef.current.getAllRowIds(), true);
428
447
  }
429
448
  }, [apiRef, handleSingleRowSelection, selectRows, canHaveMultipleSelection]);
449
+ const syncControlledState = useEventCallback(() => {
450
+ if (!props.rowSelection) {
451
+ apiRef.current.setRowSelectionModel([]);
452
+ return;
453
+ }
454
+ if (propRowSelectionModel === undefined) {
455
+ return;
456
+ }
457
+ if (!applyAutoSelection || !isNestedData || propRowSelectionModel.length === 0) {
458
+ apiRef.current.setRowSelectionModel(propRowSelectionModel);
459
+ return;
460
+ }
461
+ const newSelectionModel = apiRef.current.getPropagatedRowSelectionModel(propRowSelectionModel);
462
+ if (newSelectionModel.length !== propRowSelectionModel.length || !newSelectionModel.every(id => propRowSelectionModel.includes(id))) {
463
+ apiRef.current.setRowSelectionModel(newSelectionModel);
464
+ return;
465
+ }
466
+ apiRef.current.setRowSelectionModel(propRowSelectionModel);
467
+ });
430
468
  useGridApiEventHandler(apiRef, 'sortedRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection(true)));
431
- useGridApiEventHandler(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(removeOutdatedSelection));
469
+ useGridApiEventHandler(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection()));
432
470
  useGridApiEventHandler(apiRef, 'rowClick', runIfRowSelectionIsEnabled(handleRowClick));
433
471
  useGridApiEventHandler(apiRef, 'rowSelectionCheckboxChange', runIfRowSelectionIsEnabled(handleRowSelectionCheckboxChange));
434
472
  useGridApiEventHandler(apiRef, 'headerSelectionCheckboxChange', handleHeaderSelectionCheckboxChange);
@@ -439,15 +477,8 @@ export const useGridRowSelection = (apiRef, props) => {
439
477
  * EFFECTS
440
478
  */
441
479
  React.useEffect(() => {
442
- if (propRowSelectionModel !== undefined) {
443
- apiRef.current.setRowSelectionModel(propRowSelectionModel);
444
- }
445
- }, [apiRef, propRowSelectionModel, props.rowSelection]);
446
- React.useEffect(() => {
447
- if (!props.rowSelection) {
448
- apiRef.current.setRowSelectionModel([]);
449
- }
450
- }, [apiRef, props.rowSelection]);
480
+ syncControlledState();
481
+ }, [apiRef, propRowSelectionModel, props.rowSelection, syncControlledState]);
451
482
  const isStateControlled = propRowSelectionModel != null;
452
483
  React.useEffect(() => {
453
484
  if (isStateControlled || !props.rowSelection) {
@@ -476,4 +507,9 @@ export const useGridRowSelection = (apiRef, props) => {
476
507
  React.useEffect(() => {
477
508
  runIfRowSelectionIsEnabled(removeOutdatedSelection);
478
509
  }, [removeOutdatedSelection, runIfRowSelectionIsEnabled]);
510
+ React.useEffect(() => {
511
+ if (isFirstRender.current) {
512
+ isFirstRender.current = false;
513
+ }
514
+ }, []);
479
515
  };
@@ -2,7 +2,7 @@ import { GridSignature } from "../../utils/useGridApiEventHandler.js";
2
2
  import { GRID_ROOT_GROUP_ID } from "../rows/gridRowsUtils.js";
3
3
  import { gridFilteredRowsLookupSelector } from "../filter/gridFilterSelector.js";
4
4
  import { gridSortedRowIdsSelector } from "../sorting/gridSortingSelector.js";
5
- import { selectedIdsLookupSelector } from "./gridRowSelectionSelector.js";
5
+ import { gridRowSelectionStateSelector, selectedIdsLookupSelector } from "./gridRowSelectionSelector.js";
6
6
  import { gridRowTreeSelector } from "../rows/gridRowsSelector.js";
7
7
  import { createSelector } from "../../../utils/createSelector.js";
8
8
  export const ROW_SELECTION_PROPAGATION_DEFAULT = {
@@ -94,9 +94,8 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
94
94
  const parentNode = tree[parent];
95
95
  return parentNode.children.filter(childId => childId !== id && filteredRows[childId] !== false);
96
96
  };
97
- export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow) => {
97
+ export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow, selectedIds = new Set(gridRowSelectionStateSelector(apiRef.current.state))) => {
98
98
  const filteredRows = gridFilteredRowsLookupSelector(apiRef);
99
- const selectedIdsLookup = selectedIdsLookupSelector(apiRef);
100
99
  const selectedDescendants = new Set([]);
101
100
  if (!autoSelectDescendants && !autoSelectParents) {
102
101
  return;
@@ -113,11 +112,14 @@ export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendant
113
112
  }
114
113
  if (autoSelectParents) {
115
114
  const checkAllDescendantsSelected = rowId => {
116
- if (selectedIdsLookup[rowId] !== rowId && !selectedDescendants.has(rowId)) {
115
+ if (!selectedIds.has(rowId) && !selectedDescendants.has(rowId)) {
117
116
  return false;
118
117
  }
119
118
  const node = tree[rowId];
120
- if (node?.type !== 'group') {
119
+ if (!node) {
120
+ return false;
121
+ }
122
+ if (node.type !== 'group') {
121
123
  return true;
122
124
  }
123
125
  return node.children.every(checkAllDescendantsSelected);
@@ -126,7 +128,7 @@ export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendant
126
128
  const siblings = getFilteredRowNodeSiblings(tree, filteredRows, rowId);
127
129
  if (siblings.length === 0 || siblings.every(checkAllDescendantsSelected)) {
128
130
  const rowNode = tree[rowId];
129
- const parent = rowNode.parent;
131
+ const parent = rowNode?.parent;
130
132
  if (parent != null && parent !== GRID_ROOT_GROUP_ID && apiRef.current.isRowSelectable(parent)) {
131
133
  addRow(parent);
132
134
  selectedDescendants.add(parent);
@@ -13,6 +13,7 @@ import { useGridRegisterPipeApplier } from "../../core/pipeProcessing/index.js";
13
13
  import { gridPinnedRowsSelector, gridRowCountSelector } from "./gridRowsSelector.js";
14
14
  import { gridDimensionsSelector, gridRowHeightSelector } from "../dimensions/gridDimensionsSelectors.js";
15
15
  import { getValidRowHeight, getRowHeightWarning } from "./gridRowsUtils.js";
16
+ import { gridFocusedVirtualCellSelector } from "../virtualization/gridFocusedVirtualCellSelector.js";
16
17
  /* eslint-disable no-underscore-dangle */
17
18
 
18
19
  export const rowsMetaStateInitializer = (state, props, apiRef) => {
@@ -183,6 +184,13 @@ export const useGridRowsMeta = (apiRef, props) => {
183
184
  const entry = entries[i];
184
185
  const height = entry.borderBoxSize && entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.contentRect.height;
185
186
  const rowId = entry.target.__mui_id;
187
+ const focusedVirtualRowId = gridFocusedVirtualCellSelector(apiRef)?.id;
188
+ if (focusedVirtualRowId === rowId && height === 0) {
189
+ // Focused virtual row has 0 height.
190
+ // We don't want to store it to avoid scroll jumping.
191
+ // https://github.com/mui/mui-x/issues/14726
192
+ return;
193
+ }
186
194
  apiRef.current.unstable_storeRowHeightMeasurement(rowId, height);
187
195
  }
188
196
  if (!isHeightMetaValid.current) {
@@ -524,12 +524,10 @@ export const useGridVirtualScroller = () => {
524
524
  }),
525
525
  getScrollbarVerticalProps: () => ({
526
526
  ref: scrollbarVerticalRef,
527
- role: 'presentation',
528
527
  scrollPosition
529
528
  }),
530
529
  getScrollbarHorizontalProps: () => ({
531
530
  ref: scrollbarHorizontalRef,
532
- role: 'presentation',
533
531
  scrollPosition
534
532
  }),
535
533
  getScrollAreaProps: () => ({
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.27.2
2
+ * @mui/x-data-grid v7.28.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -97,6 +97,7 @@ const arSDGrid = {
97
97
  filterValueFalse: 'خاطئ',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'القائمة',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'إظهار الأعمدة',
101
102
  columnMenuManageColumns: 'إدارة الأعمدة',
102
103
  columnMenuFilter: 'المرشِح',
@@ -113,6 +113,7 @@ const beBYGrid = {
113
113
  filterValueFalse: 'няпраўда',
114
114
  // Column menu text
115
115
  columnMenuLabel: 'Меню',
116
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
116
117
  columnMenuShowColumns: 'Паказаць слупкі',
117
118
  columnMenuManageColumns: 'Кіраваць слупкамі',
118
119
  columnMenuFilter: 'Фільтр',
@@ -97,6 +97,7 @@ const bgBGGrid = {
97
97
  filterValueFalse: 'невярно',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Меню',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Покажи колоните',
101
102
  columnMenuManageColumns: 'Управление на колони',
102
103
  columnMenuFilter: 'Филтри',
@@ -96,6 +96,7 @@ const bnBDGrid = {
96
96
  filterValueFalse: 'মিথ্যা',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'মেনু',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'কলাম দেখান',
100
101
  columnMenuManageColumns: 'কলাম পরিচালনা করুন',
101
102
  columnMenuFilter: 'ফিল্টার',
@@ -42,8 +42,7 @@ const csCZGrid = {
42
42
  columnsManagementNoColumns: 'Žádné sloupce',
43
43
  columnsManagementShowHideAllText: 'Zobrazit/skrýt vše',
44
44
  columnsManagementReset: 'Resetovat',
45
- // columnsManagementDeleteIconLabel: 'Clear',
46
-
45
+ columnsManagementDeleteIconLabel: 'Vyčistit',
47
46
  // Filter panel text
48
47
  filterPanelAddFilter: 'Přidat filtr',
49
48
  filterPanelRemoveAll: 'Odstranit vše',
@@ -57,9 +56,9 @@ const csCZGrid = {
57
56
  filterPanelInputPlaceholder: 'Hodnota filtru',
58
57
  // Filter operators text
59
58
  filterOperatorContains: 'obsahuje',
60
- // filterOperatorDoesNotContain: 'does not contain',
59
+ filterOperatorDoesNotContain: 'neobsahuje',
61
60
  filterOperatorEquals: 'rovná se',
62
- // filterOperatorDoesNotEqual: 'does not equal',
61
+ filterOperatorDoesNotEqual: 'nerovná se',
63
62
  filterOperatorStartsWith: 'začíná na',
64
63
  filterOperatorEndsWith: 'končí na',
65
64
  filterOperatorIs: 'je',
@@ -79,9 +78,9 @@ const csCZGrid = {
79
78
  'filterOperator<=': '<=',
80
79
  // Header filter operators text
81
80
  headerFilterOperatorContains: 'Obsahuje',
82
- // headerFilterOperatorDoesNotContain: 'Does not contain',
81
+ headerFilterOperatorDoesNotContain: 'Neobsahuje',
83
82
  headerFilterOperatorEquals: 'Rovná se',
84
- // headerFilterOperatorDoesNotEqual: 'Does not equal',
83
+ headerFilterOperatorDoesNotEqual: 'Nerovná se',
85
84
  headerFilterOperatorStartsWith: 'Začíná na',
86
85
  headerFilterOperatorEndsWith: 'Končí na',
87
86
  headerFilterOperatorIs: 'Je',
@@ -105,6 +104,7 @@ const csCZGrid = {
105
104
  filterValueFalse: 'ne',
106
105
  // Column menu text
107
106
  columnMenuLabel: 'Menu',
107
+ columnMenuAriaLabel: columnName => `Možnosti sloupce ${columnName}`,
108
108
  columnMenuShowColumns: 'Zobrazit sloupce',
109
109
  columnMenuManageColumns: 'Spravovat sloupce',
110
110
  columnMenuFilter: 'Filtr',
@@ -97,6 +97,7 @@ const daDKGrid = {
97
97
  filterValueFalse: 'negativ',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Menu',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Vis kolonner',
101
102
  columnMenuManageColumns: 'Administrer kolonner',
102
103
  columnMenuFilter: 'Filtrer',
@@ -96,6 +96,7 @@ const deDEGrid = {
96
96
  filterValueFalse: 'Nein',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menü',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Zeige alle Spalten',
100
101
  columnMenuManageColumns: 'Spalten verwalten',
101
102
  columnMenuFilter: 'Filter',
@@ -97,6 +97,7 @@ const elGRGrid = {
97
97
  filterValueFalse: 'ψευδές',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Μενού',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Εμφάνιση στηλών',
101
102
  columnMenuManageColumns: 'Διαχείριση στηλών',
102
103
  columnMenuFilter: 'Φίλτρο',
@@ -96,6 +96,7 @@ const esESGrid = {
96
96
  filterValueFalse: 'falso',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menú',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Mostrar columnas',
100
101
  columnMenuManageColumns: 'Administrar columnas',
101
102
  columnMenuFilter: 'Filtro',
@@ -96,6 +96,7 @@ const faIRGrid = {
96
96
  filterValueFalse: 'غلط',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'فهرست',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'نمایش ستون‌ها',
100
101
  columnMenuManageColumns: 'مدیریت ستون‌ها',
101
102
  columnMenuFilter: 'فیلتر',
@@ -97,6 +97,7 @@ const fiFIGrid = {
97
97
  filterValueFalse: 'epätosi',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Valikko',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Näytä sarakkeet',
101
102
  columnMenuManageColumns: 'Hallitse sarakkeita',
102
103
  columnMenuFilter: 'Suodata',
@@ -97,6 +97,7 @@ const frFRGrid = {
97
97
  filterValueFalse: 'faux',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Menu',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Afficher les colonnes',
101
102
  columnMenuManageColumns: 'Gérer les colonnes',
102
103
  columnMenuFilter: 'Filtrer',
@@ -97,6 +97,7 @@ const heILGrid = {
97
97
  filterValueFalse: 'לא',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'תפריט',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'הצג עמודות',
101
102
  columnMenuManageColumns: 'נהל עמודות',
102
103
  columnMenuFilter: 'סנן',
@@ -105,6 +105,7 @@ const hrHRGrid = {
105
105
  filterValueFalse: 'netačno',
106
106
  // Column menu text
107
107
  columnMenuLabel: 'Izbornik',
108
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
108
109
  columnMenuShowColumns: 'Prikaži stupce',
109
110
  columnMenuManageColumns: 'Upravljanje stupcima',
110
111
  columnMenuFilter: 'Filter',
@@ -96,6 +96,7 @@ const huHUGrid = {
96
96
  filterValueFalse: 'hamis',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menü',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Oszlopok megjelenítése',
100
101
  columnMenuManageColumns: 'Oszlopok kezelése',
101
102
  columnMenuFilter: 'Szűrők',
@@ -97,6 +97,7 @@ const isISGrid = {
97
97
  filterValueFalse: 'falskt',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Valmynd',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Sýna dálka',
101
102
  columnMenuManageColumns: 'Stjórna dálkum',
102
103
  columnMenuFilter: 'Síur',
@@ -97,6 +97,7 @@ const itITGrid = {
97
97
  filterValueFalse: 'falso',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Menu',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Mostra le colonne',
101
102
  columnMenuManageColumns: 'Gestisci colonne',
102
103
  columnMenuFilter: 'Filtra',
@@ -97,6 +97,7 @@ const jaJPGrid = {
97
97
  filterValueFalse: '偽',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'メニュー',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: '列表示',
101
102
  columnMenuManageColumns: '列管理',
102
103
  columnMenuFilter: 'フィルター',
@@ -96,6 +96,7 @@ const koKRGrid = {
96
96
  filterValueFalse: '거짓',
97
97
  // Column menu text
98
98
  columnMenuLabel: '메뉴',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: '열 표시',
100
101
  columnMenuManageColumns: '열 관리',
101
102
  columnMenuFilter: '필터',
@@ -143,7 +144,7 @@ const koKRGrid = {
143
144
  // Row reordering text
144
145
  rowReorderingHeaderName: '행 재배치',
145
146
  // Aggregation
146
- aggregationMenuItemHeader: '총계',
147
+ aggregationMenuItemHeader: '집계',
147
148
  aggregationFunctionLabelSum: '합',
148
149
  aggregationFunctionLabelAvg: '평균',
149
150
  aggregationFunctionLabelMin: '최소값',
@@ -97,6 +97,7 @@ const nbNOGrid = {
97
97
  filterValueFalse: 'usant',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Meny',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Vis kolonner',
101
102
  columnMenuManageColumns: 'Administrer kolonner',
102
103
  columnMenuFilter: 'Filter',
@@ -96,6 +96,7 @@ const nlNLGrid = {
96
96
  filterValueFalse: 'onwaar',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menu',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Toon kolommen',
100
101
  columnMenuManageColumns: 'Kolommen beheren',
101
102
  columnMenuFilter: 'Filteren',
@@ -97,6 +97,7 @@ const nnNOGrid = {
97
97
  filterValueFalse: 'usant',
98
98
  // Column menu text
99
99
  columnMenuLabel: 'Meny',
100
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
100
101
  columnMenuShowColumns: 'Vis kolonner',
101
102
  columnMenuManageColumns: 'Administrer kolonner',
102
103
  columnMenuFilter: 'Filter',
@@ -96,6 +96,7 @@ const plPLGrid = {
96
96
  filterValueFalse: 'fałsz',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menu',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Pokaż wszystkie kolumny',
100
101
  columnMenuManageColumns: 'Zarządzaj kolumnami',
101
102
  columnMenuFilter: 'Filtr',
@@ -96,6 +96,7 @@ const ptBRGrid = {
96
96
  filterValueFalse: 'falso',
97
97
  // Column menu text
98
98
  columnMenuLabel: 'Menu',
99
+ // columnMenuAriaLabel: (columnName: string) => `${columnName} column menu`,
99
100
  columnMenuShowColumns: 'Exibir colunas',
100
101
  columnMenuManageColumns: 'Gerir colunas',
101
102
  columnMenuFilter: 'Filtrar',