@mui/x-data-grid 7.27.3 → 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 (161) hide show
  1. package/CHANGELOG.md +86 -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 +2 -2
  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/index.js +1 -1
  21. package/locales/arSD.js +1 -0
  22. package/locales/beBY.js +1 -0
  23. package/locales/bgBG.js +1 -0
  24. package/locales/bnBD.js +1 -0
  25. package/locales/csCZ.js +6 -6
  26. package/locales/daDK.js +1 -0
  27. package/locales/deDE.js +1 -0
  28. package/locales/elGR.js +1 -0
  29. package/locales/esES.js +1 -0
  30. package/locales/faIR.js +1 -0
  31. package/locales/fiFI.js +1 -0
  32. package/locales/frFR.js +1 -0
  33. package/locales/heIL.js +1 -0
  34. package/locales/hrHR.js +1 -0
  35. package/locales/huHU.js +1 -0
  36. package/locales/isIS.js +1 -0
  37. package/locales/itIT.js +1 -0
  38. package/locales/jaJP.js +1 -0
  39. package/locales/koKR.js +2 -1
  40. package/locales/nbNO.js +1 -0
  41. package/locales/nlNL.js +1 -0
  42. package/locales/nnNO.js +1 -0
  43. package/locales/plPL.js +1 -0
  44. package/locales/ptBR.js +1 -0
  45. package/locales/ptPT.js +1 -0
  46. package/locales/roRO.js +1 -0
  47. package/locales/ruRU.js +1 -0
  48. package/locales/skSK.js +7 -7
  49. package/locales/svSE.js +1 -0
  50. package/locales/trTR.js +1 -0
  51. package/locales/ukUA.js +1 -0
  52. package/locales/urPK.js +1 -0
  53. package/locales/viVN.js +1 -0
  54. package/locales/zhCN.js +1 -0
  55. package/locales/zhHK.js +11 -11
  56. package/locales/zhTW.js +10 -10
  57. package/models/api/gridLocaleTextApi.d.ts +1 -0
  58. package/models/api/gridRowSelectionApi.d.ts +15 -4
  59. package/modern/components/cell/GridActionsCell.js +3 -1
  60. package/modern/components/cell/GridCell.js +2 -2
  61. package/modern/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  62. package/modern/components/containers/GridRootStyles.js +3 -3
  63. package/modern/components/panel/filterPanel/index.js +1 -1
  64. package/modern/components/virtualization/GridBottomContainer.js +1 -1
  65. package/modern/components/virtualization/GridTopContainer.js +1 -1
  66. package/modern/components/virtualization/GridVirtualScrollbar.js +2 -2
  67. package/modern/constants/localeTextConstants.js +1 -0
  68. package/modern/hooks/features/editing/useGridRowEditing.js +19 -10
  69. package/modern/hooks/features/export/useGridPrintExport.js +4 -4
  70. package/modern/hooks/features/filter/useGridFilter.js +5 -0
  71. package/modern/hooks/features/rowSelection/useGridRowSelection.js +47 -11
  72. package/modern/hooks/features/rowSelection/utils.js +8 -6
  73. package/modern/index.js +1 -1
  74. package/modern/locales/arSD.js +1 -0
  75. package/modern/locales/beBY.js +1 -0
  76. package/modern/locales/bgBG.js +1 -0
  77. package/modern/locales/bnBD.js +1 -0
  78. package/modern/locales/csCZ.js +6 -6
  79. package/modern/locales/daDK.js +1 -0
  80. package/modern/locales/deDE.js +1 -0
  81. package/modern/locales/elGR.js +1 -0
  82. package/modern/locales/esES.js +1 -0
  83. package/modern/locales/faIR.js +1 -0
  84. package/modern/locales/fiFI.js +1 -0
  85. package/modern/locales/frFR.js +1 -0
  86. package/modern/locales/heIL.js +1 -0
  87. package/modern/locales/hrHR.js +1 -0
  88. package/modern/locales/huHU.js +1 -0
  89. package/modern/locales/isIS.js +1 -0
  90. package/modern/locales/itIT.js +1 -0
  91. package/modern/locales/jaJP.js +1 -0
  92. package/modern/locales/koKR.js +2 -1
  93. package/modern/locales/nbNO.js +1 -0
  94. package/modern/locales/nlNL.js +1 -0
  95. package/modern/locales/nnNO.js +1 -0
  96. package/modern/locales/plPL.js +1 -0
  97. package/modern/locales/ptBR.js +1 -0
  98. package/modern/locales/ptPT.js +1 -0
  99. package/modern/locales/roRO.js +1 -0
  100. package/modern/locales/ruRU.js +1 -0
  101. package/modern/locales/skSK.js +7 -7
  102. package/modern/locales/svSE.js +1 -0
  103. package/modern/locales/trTR.js +1 -0
  104. package/modern/locales/ukUA.js +1 -0
  105. package/modern/locales/urPK.js +1 -0
  106. package/modern/locales/viVN.js +1 -0
  107. package/modern/locales/zhCN.js +1 -0
  108. package/modern/locales/zhHK.js +11 -11
  109. package/modern/locales/zhTW.js +10 -10
  110. package/node/components/cell/GridActionsCell.js +3 -1
  111. package/node/components/cell/GridCell.js +2 -2
  112. package/node/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  113. package/node/components/containers/GridRootStyles.js +3 -3
  114. package/node/components/panel/filterPanel/index.js +7 -11
  115. package/node/components/virtualization/GridBottomContainer.js +1 -1
  116. package/node/components/virtualization/GridTopContainer.js +1 -1
  117. package/node/components/virtualization/GridVirtualScrollbar.js +2 -2
  118. package/node/constants/localeTextConstants.js +1 -0
  119. package/node/hooks/features/editing/useGridRowEditing.js +19 -10
  120. package/node/hooks/features/export/useGridPrintExport.js +4 -4
  121. package/node/hooks/features/filter/useGridFilter.js +5 -0
  122. package/node/hooks/features/rowSelection/useGridRowSelection.js +55 -19
  123. package/node/hooks/features/rowSelection/utils.js +7 -5
  124. package/node/index.js +1 -1
  125. package/node/locales/arSD.js +1 -0
  126. package/node/locales/beBY.js +1 -0
  127. package/node/locales/bgBG.js +1 -0
  128. package/node/locales/bnBD.js +1 -0
  129. package/node/locales/csCZ.js +6 -6
  130. package/node/locales/daDK.js +1 -0
  131. package/node/locales/deDE.js +1 -0
  132. package/node/locales/elGR.js +1 -0
  133. package/node/locales/esES.js +1 -0
  134. package/node/locales/faIR.js +1 -0
  135. package/node/locales/fiFI.js +1 -0
  136. package/node/locales/frFR.js +1 -0
  137. package/node/locales/heIL.js +1 -0
  138. package/node/locales/hrHR.js +1 -0
  139. package/node/locales/huHU.js +1 -0
  140. package/node/locales/isIS.js +1 -0
  141. package/node/locales/itIT.js +1 -0
  142. package/node/locales/jaJP.js +1 -0
  143. package/node/locales/koKR.js +2 -1
  144. package/node/locales/nbNO.js +1 -0
  145. package/node/locales/nlNL.js +1 -0
  146. package/node/locales/nnNO.js +1 -0
  147. package/node/locales/plPL.js +1 -0
  148. package/node/locales/ptBR.js +1 -0
  149. package/node/locales/ptPT.js +1 -0
  150. package/node/locales/roRO.js +1 -0
  151. package/node/locales/ruRU.js +1 -0
  152. package/node/locales/skSK.js +7 -7
  153. package/node/locales/svSE.js +1 -0
  154. package/node/locales/trTR.js +1 -0
  155. package/node/locales/ukUA.js +1 -0
  156. package/node/locales/urPK.js +1 -0
  157. package/node/locales/viVN.js +1 -0
  158. package/node/locales/zhCN.js +1 -0
  159. package/node/locales/zhHK.js +11 -11
  160. package/node/locales/zhTW.js +10 -10
  161. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -3,6 +3,92 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 7.28.0
7
+
8
+ _Mar 17, 2025_
9
+
10
+ We'd like to offer a big thanks to the 10 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 🎁 Add support for `@mui/material` version 7 in all X packages
13
+ - 🐞 Bugfixes
14
+ - 🌍 Improve Chinese (zh-CN), (zh-HK), (zh-TW), Czech (cs-CZ), Korean (ko-KR) and Slovak (sk-Sk) locales on the Data Grid
15
+ - 🌍 Improve Chinese (zh-CN), (zh-HK) and (zh-TW) locales on the Pickers
16
+
17
+ Special thanks go out to the community contributors who have helped make this release possible:
18
+ @Blake-McCullough, @hlavacz, @yelahj, @k-rajat19, @nusr.
19
+ Following are all team members who have contributed to this release:
20
+ @arminmeh, @flaviendelangle, @LukasTy, @michelengelen, @MBilalShafi.
21
+
22
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
23
+
24
+ ### Data Grid
25
+
26
+ #### `@mui/x-data-grid@7.28.0`
27
+
28
+ - [DataGrid] Add click propagation and prevents default on `toggleMenu` click (#16909) @michelengelen
29
+ - [DataGrid] Fix `processRowUpdate()` error if the row is removed before it is executed (#16904) @arminmeh
30
+ - [DataGrid] Fix bug with adding and removing columns in active edit state (#16916) @Blake-McCullough
31
+ - [DataGrid] Fix visual issue with pinned columns and row spanning (#16942) @MBilalShafi
32
+ - [DataGrid] Make column header menu button aria-labels unique (#16925) @owais635
33
+ - [DataGrid] Fix `printOptions` not respecting `hideFooter` root prop (#16915) @k-rajat19
34
+ - [l10n] Improve Chinese (zh-CN), (zh-HK) and (zh-TW) locales (#16917 and #16887) @nusr
35
+ - [l10n] Improve Czech (cs-CZ) and Slovak (sk-Sk) locales (#16996) @hlavacz
36
+ - [l10n] Improve Korean (ko-KR) locale (#16998) @yelahj
37
+
38
+ #### `@mui/x-data-grid-pro@7.28.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
39
+
40
+ Same changes as in `@mui/x-data-grid@7.28.0`, plus:
41
+
42
+ - [DataGridPro] Fix header filters not displaying restored values (#16976) @MBilalShafi
43
+ - [DataGridPro] Fix infinite loading not reacting when scrolling to the end (#16939) @arminmeh
44
+
45
+ #### `@mui/x-data-grid-premium@7.28.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
46
+
47
+ Same changes as in `@mui/x-data-grid-pro@7.28.0`, plus:
48
+
49
+ - [DataGridPremium] Fix selection propagation issues with controlled state (#16995) @MBilalShafi
50
+
51
+ ### Date and Time Pickers
52
+
53
+ #### `@mui/x-date-pickers@7.28.0`
54
+
55
+ - [l10n] Improve Chinese (zh-CN), (zh-HK) and (zh-TW) locales (#16997) @nusr
56
+
57
+ #### `@mui/x-date-pickers-pro@7.28.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
58
+
59
+ Same changes as in `@mui/x-date-pickers@7.28.0`, plus:
60
+
61
+ - [DateRangeCalendar] Do not update the previewed day when hovering a day and the value is empty (#16892) @flaviendelangle
62
+
63
+ ### Charts
64
+
65
+ #### `@mui/x-charts@7.28.0`
66
+
67
+ Internal changes.
68
+
69
+ #### `@mui/x-charts-pro@7.28.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
70
+
71
+ Same changes as in `@mui/x-charts@7.28.0`.
72
+
73
+ ### Tree View
74
+
75
+ #### `@mui/x-tree-view@7.28.0`
76
+
77
+ Internal changes.
78
+
79
+ #### `@mui/x-tree-view-pro@7.28.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
80
+
81
+ Same changes as in `@mui/x-tree-view@7.28.0`.
82
+
83
+ ### Docs
84
+
85
+ - [docs] Fix link to the lazy loading demo for the DataGrid (#16912) @nusr
86
+
87
+ ### Core
88
+
89
+ - [core] Allow `@mui/material` v7 in dependencies (#16951) @LukasTy
90
+ - [infra] Make tests on React 18 part of pipeline (#16958) @LukasTy
91
+
6
92
  ## 7.27.3
7
93
 
8
94
  _Mar 7, 2025_
package/README.md CHANGED
@@ -15,7 +15,7 @@ This component has the following peer dependencies that you will need to install
15
15
 
16
16
  ```json
17
17
  "peerDependencies": {
18
- "@mui/material": "^5.15.14 || ^6.0.0",
18
+ "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0",
19
19
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
20
20
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
21
21
  },
@@ -90,7 +90,9 @@ function GridActionsCell(props) {
90
90
  const hideMenu = () => {
91
91
  setOpen(false);
92
92
  };
93
- const toggleMenu = () => {
93
+ const toggleMenu = event => {
94
+ event.stopPropagation();
95
+ event.preventDefault();
94
96
  if (open) {
95
97
  hideMenu();
96
98
  } else {
@@ -193,9 +193,9 @@ const GridCell = forwardRef(function GridCell(props, ref) {
193
193
  const isRightPinned = pinnedPosition === PinnedColumnPosition.RIGHT;
194
194
  if (rowSpan > 1) {
195
195
  cellStyle.height = `calc(var(--height) * ${rowSpan})`;
196
- cellStyle.zIndex = 5;
196
+ cellStyle.zIndex = 10;
197
197
  if (isLeftPinned || isRightPinned) {
198
- cellStyle.zIndex = 6;
198
+ cellStyle.zIndex = 40;
199
199
  }
200
200
  }
201
201
  return cellStyle;
@@ -35,6 +35,7 @@ export const ColumnHeaderMenuIcon = /*#__PURE__*/React.memo(props => {
35
35
  event.stopPropagation();
36
36
  apiRef.current.toggleColumnMenu(colDef.field);
37
37
  }, [apiRef, colDef.field]);
38
+ const columnName = colDef.headerName ?? colDef.field;
38
39
  return /*#__PURE__*/_jsx("div", {
39
40
  className: classes.root,
40
41
  children: /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, _extends({
@@ -45,7 +46,7 @@ export const ColumnHeaderMenuIcon = /*#__PURE__*/React.memo(props => {
45
46
  ref: iconButtonRef,
46
47
  tabIndex: -1,
47
48
  className: classes.button,
48
- "aria-label": apiRef.current.getLocaleText('columnMenuLabel'),
49
+ "aria-label": apiRef.current.getLocaleText('columnMenuAriaLabel')(columnName),
49
50
  size: "small",
50
51
  onClick: handleMenuIconClick,
51
52
  "aria-haspopup": "menu",
@@ -485,14 +485,14 @@ export const GridRootStyles = styled('div', {
485
485
  },
486
486
  [`& .${c['columnHeader--pinnedLeft']}, & .${c['columnHeader--pinnedRight']}`]: {
487
487
  position: 'sticky',
488
- zIndex: 4,
488
+ zIndex: 40,
489
489
  // Should be above the column separator
490
490
  background: 'var(--DataGrid-pinnedBackground)'
491
491
  },
492
492
  [`& .${c.columnSeparator}`]: {
493
493
  position: 'absolute',
494
494
  overflow: 'hidden',
495
- zIndex: 3,
495
+ zIndex: 30,
496
496
  display: 'flex',
497
497
  flexDirection: 'column',
498
498
  justifyContent: 'center',
@@ -732,7 +732,7 @@ export const GridRootStyles = styled('div', {
732
732
  },
733
733
  [`& .${c['cell--pinnedLeft']}, & .${c['cell--pinnedRight']}`]: {
734
734
  position: 'sticky',
735
- zIndex: 3,
735
+ zIndex: 30,
736
736
  background: 'var(--DataGrid-pinnedBackground)',
737
737
  '&.Mui-selected': {
738
738
  backgroundColor: pinnedSelectedBackgroundColor
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { TextFieldProps } from '@mui/material/TextField';
3
+ import { GridFilterItem } from '../../../models/gridFilterItem';
3
4
  import { GridFilterInputValueProps } from './GridFilterInputValueProps';
4
5
  export type GridTypeFilterInputValueProps = GridFilterInputValueProps & TextFieldProps & {
5
6
  type?: 'text' | 'number' | 'date' | 'datetime-local';
@@ -10,6 +11,9 @@ export type GridTypeFilterInputValueProps = GridFilterInputValueProps & TextFiel
10
11
  */
11
12
  isFilterActive?: boolean;
12
13
  };
14
+ export type ItemPlusTag = GridFilterItem & {
15
+ fromInput?: string;
16
+ };
13
17
  declare function GridFilterInputValue(props: GridTypeFilterInputValueProps): React.JSX.Element;
14
18
  declare namespace GridFilterInputValue {
15
19
  var propTypes: any;
@@ -1,5 +1,5 @@
1
1
  export * from './GridFilterForm';
2
- export * from './GridFilterInputValue';
2
+ export { GridFilterInputValue, type GridTypeFilterInputValueProps } from './GridFilterInputValue';
3
3
  export * from './GridFilterInputDate';
4
4
  export * from './GridFilterInputSingleSelect';
5
5
  export * from './GridFilterInputBoolean';
@@ -1,5 +1,5 @@
1
1
  export * from "./GridFilterForm.js";
2
- export * from "./GridFilterInputValue.js";
2
+ export { GridFilterInputValue } from "./GridFilterInputValue.js";
3
3
  export * from "./GridFilterInputDate.js";
4
4
  export * from "./GridFilterInputSingleSelect.js";
5
5
  export * from "./GridFilterInputBoolean.js";
@@ -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
@@ -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,12 +2,12 @@ import { RefObject } from '@mui/x-internals/types';
2
2
  import type { GridRowId, GridRowTreeConfig } from '../../../models/gridRows';
3
3
  import type { DataGridProcessedProps } from '../../../models/props/DataGridProps';
4
4
  import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
5
- import type { GridRowSelectionPropagation } from '../../../models/gridRowSelectionModel';
5
+ import { type GridRowSelectionPropagation } from '../../../models/gridRowSelectionModel';
6
6
  export declare const ROW_SELECTION_PROPAGATION_DEFAULT: GridRowSelectionPropagation;
7
7
  export declare function getCheckboxPropsSelector(groupId: GridRowId, autoSelectParents: boolean): import("../../..").OutputSelector<import("../../../models/gridStateCommunity").GridStateCommunity, {
8
8
  isIndeterminate: boolean;
9
9
  isChecked: boolean;
10
10
  }>;
11
11
  export declare function isMultipleRowSelectionEnabled(props: Pick<DataGridProcessedProps, 'signature' | 'disableMultipleRowSelection' | 'checkboxSelection'>): boolean;
12
- export declare const findRowsToSelect: (apiRef: RefObject<GridPrivateApiCommunity>, tree: GridRowTreeConfig, selectedRow: GridRowId, autoSelectDescendants: boolean, autoSelectParents: boolean, addRow: (rowId: GridRowId) => void) => void;
12
+ export declare const findRowsToSelect: (apiRef: RefObject<GridPrivateApiCommunity>, tree: GridRowTreeConfig, selectedRow: GridRowId, autoSelectDescendants: boolean, autoSelectParents: boolean, addRow: (rowId: GridRowId) => void, selectedIds?: Set<GridRowId>) => void;
13
13
  export declare const findRowsToDeselect: (apiRef: RefObject<GridPrivateApiCommunity>, tree: GridRowTreeConfig, deselectedRow: GridRowId, autoSelectDescendants: boolean, autoSelectParents: boolean, removeRow: (rowId: GridRowId) => void) => void;
@@ -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);
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.27.3
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
package/locales/arSD.js CHANGED
@@ -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: 'المرشِح',
package/locales/beBY.js CHANGED
@@ -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: 'Фільтр',
package/locales/bgBG.js CHANGED
@@ -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: 'Филтри',
package/locales/bnBD.js CHANGED
@@ -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: 'ফিল্টার',
package/locales/csCZ.js CHANGED
@@ -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',
package/locales/daDK.js CHANGED
@@ -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',
package/locales/deDE.js CHANGED
@@ -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',