@mui/x-data-grid 8.2.0 → 8.3.1

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 (42) hide show
  1. package/CHANGELOG.md +199 -6
  2. package/components/GridScrollArea.js +1 -2
  3. package/components/base/GridOverlays.js +2 -3
  4. package/components/columnSelection/GridCellCheckboxRenderer.js +4 -2
  5. package/components/columnSelection/GridHeaderCheckbox.js +4 -0
  6. package/esm/components/GridScrollArea.js +1 -2
  7. package/esm/components/base/GridOverlays.js +2 -3
  8. package/esm/components/columnSelection/GridCellCheckboxRenderer.js +6 -4
  9. package/esm/components/columnSelection/GridHeaderCheckbox.js +4 -0
  10. package/esm/hooks/features/columns/gridColumnsUtils.js +15 -7
  11. package/esm/hooks/features/editing/useGridCellEditing.js +2 -1
  12. package/esm/hooks/features/editing/useGridRowEditing.js +7 -6
  13. package/esm/hooks/features/rowSelection/useGridRowSelection.js +6 -6
  14. package/esm/hooks/features/rowSelection/utils.d.ts +4 -1
  15. package/esm/hooks/features/rowSelection/utils.js +34 -33
  16. package/esm/hooks/features/virtualization/useGridVirtualScroller.js +7 -6
  17. package/esm/index.d.ts +1 -0
  18. package/esm/index.js +2 -1
  19. package/esm/locales/koKR.js +68 -76
  20. package/esm/locales/nbNO.js +22 -24
  21. package/esm/material/index.js +24 -24
  22. package/esm/models/api/gridRowSelectionApi.d.ts +4 -2
  23. package/esm/models/events/gridEventLookup.d.ts +1 -0
  24. package/esm/utils/cleanupTracking/TimerBasedCleanupTracking.d.ts +1 -1
  25. package/esm/utils/css/context.js +4 -1
  26. package/hooks/features/columns/gridColumnsUtils.js +15 -7
  27. package/hooks/features/editing/useGridCellEditing.js +2 -1
  28. package/hooks/features/editing/useGridRowEditing.js +6 -5
  29. package/hooks/features/rowSelection/useGridRowSelection.js +6 -6
  30. package/hooks/features/rowSelection/utils.d.ts +4 -1
  31. package/hooks/features/rowSelection/utils.js +35 -35
  32. package/hooks/features/virtualization/useGridVirtualScroller.js +7 -6
  33. package/index.d.ts +1 -0
  34. package/index.js +2 -1
  35. package/locales/koKR.js +68 -76
  36. package/locales/nbNO.js +22 -24
  37. package/material/index.js +24 -24
  38. package/models/api/gridRowSelectionApi.d.ts +4 -2
  39. package/models/events/gridEventLookup.d.ts +1 -0
  40. package/package.json +4 -4
  41. package/utils/cleanupTracking/TimerBasedCleanupTracking.d.ts +1 -1
  42. package/utils/css/context.js +4 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,201 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.3.1
9
+
10
+ _May 14, 2025_
11
+
12
+ We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🌍 Improve Norwegian Bokmål (nb-NO) locale on the Data Grid
15
+ - 🌍 Improve Korean (ko-KR) locale on the Data Grid and Pickers
16
+ - 📚 Documentation improvements
17
+ - 🐞 Bugfixes
18
+
19
+ Special thanks go out to the community members for their valuable contributions:
20
+ @100pearlcent, @htollefsen, @JanPretzel, @sai6855.
21
+ Following are all team members who have contributed to this release:
22
+ @bernardobelchior, @cherniavskii, @flaviendelangle, @Janpot, @JCQuintas, @MBilalShafi, @oliviertassinari, @prakhargupta1.
23
+
24
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
25
+
26
+ ### Data Grid
27
+
28
+ #### `@mui/x-data-grid@8.3.1`
29
+
30
+ - [DataGrid] Add `reason` param for `onRowSelectionModelChange` callback (#17545) @sai6855
31
+ - [DataGrid] Fix `renderContext` calculation loop (#17779) @cherniavskii
32
+ - [DataGrid] Fix column spanning jump on scroll (#17759) @cherniavskii
33
+ - [DataGrid] Fix material augmentation not working (#17761) @cherniavskii
34
+ - [DataGrid] Use arguments selector for checkbox props (#17683) @MBilalShafi
35
+ - [l10n] Improve Norwegian Bokmål (nb-NO) locale (#17766) @htollefsen
36
+ - [l10n] Improve Korean (ko-KR) locale (#17484) @100pearlcent
37
+
38
+ #### `@mui/x-data-grid-pro@8.3.1` [![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@8.3.1`.
41
+
42
+ #### `@mui/x-data-grid-premium@8.3.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
43
+
44
+ Same changes as in `@mui/x-data-grid-pro@8.3.1`, plus:
45
+
46
+ - [DataGridPremium] Fix aggregation label not being used in pivot panel (#17760) @cherniavskii
47
+
48
+ ### Date and Time Pickers
49
+
50
+ #### `@mui/x-date-pickers@8.3.1`
51
+
52
+ - [fields] Add notch to the field outlined when the label is manually shrank (#17620) @flaviendelangle
53
+ - [l10n] Improve Korean (ko-KR) locale (#17484) @100pearlcent
54
+
55
+ #### `@mui/x-date-pickers-pro@8.3.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
56
+
57
+ Same changes as in `@mui/x-date-pickers@8.3.1`.
58
+
59
+ ### Charts
60
+
61
+ #### `@mui/x-charts@8.3.1`
62
+
63
+ - [charts] Fix infinite tick number when zoom range is zero (#17750) @bernardobelchior
64
+ - [charts] Improve tick rendering performance (#17755) @bernardobelchior
65
+
66
+ #### `@mui/x-charts-pro@8.3.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
67
+
68
+ Same changes as in `@mui/x-charts@8.3.1`, plus:
69
+
70
+ - [charts-pro] Fix ESM build issue with Vite (#17774) @bernardobelchior
71
+ - [charts-pro] Add benchmark for zoomed in scatter chart (#17756) @bernardobelchior
72
+
73
+ ### Tree View
74
+
75
+ #### `@mui/x-tree-view@8.3.1`
76
+
77
+ Internal changes.
78
+
79
+ #### `@mui/x-tree-view-pro@8.3.1` [![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@8.3.1`.
82
+
83
+ ### Docs
84
+
85
+ - [docs] Fix 301 to Next.js docs for license @oliviertassinari
86
+ - [docs] Fix AI assistant API URL (#17745) @oliviertassinari
87
+ - [docs] Fix heading structure in README @oliviertassinari
88
+ - [docs] Fix translation keys documentation (#17811) @JanPretzel
89
+ - [docs] Improve CHANGELOG format @oliviertassinari
90
+
91
+ ### Core
92
+
93
+ - [core] Apply YAML convention, blank line only at top level @oliviertassinari
94
+ - [code-infra] Fix dynamic import missing extensions (#17767) @Janpot
95
+ - [code-infra] Replace `mocha` with `vitest` for browser & jsdom tests (#14508) @JCQuintas
96
+ - [scheduler] Create the package and setup a private doc page (#17239) @flaviendelangle
97
+
98
+ ## 8.3.0
99
+
100
+ _May 8, 2025_
101
+
102
+ We'd like to offer a big thanks to the 11 contributors who made this release possible. Here are some highlights ✨:
103
+
104
+ - 🎨 Added new styling options and shapes for `<FunnelChart />`, including `variant`, `borderRadius`, `pyramid`, and `step-pyramid` curves.
105
+ - 📚 Documentation improvements
106
+ - 🐞 Bugfixes
107
+
108
+ Special thanks go out to this community member for a valuable contribution: @ptuukkan.
109
+ Team members who have contributed to this release: @alexfauquette, @arminmeh, @bernardobelchior, @flaviendelangle, @Janpot, @JCQuintas, @LukasTy, @MBilalShafi, @rita-codes, @romgrk.
110
+
111
+ ### Data Grid
112
+
113
+ #### `@mui/x-data-grid@8.3.0`
114
+
115
+ - [DataGrid] Fix cell editing of computed columns with data source (#17684) @ptuukkan
116
+ - [DataGrid] Fix lazy loading crash with `isRowSelectable` prop (#17629) @MBilalShafi
117
+ - [DataGrid] Fix: use CSS nonce (#17726) @romgrk
118
+ - [DataGrid] Ignore `preProcessEditCellProps` for non-editable columns when starting a row update (#17732) @arminmeh
119
+ - [DataGrid] Avoid applying row selection propagation on filtered rows (#17739) @MBilalShafi
120
+
121
+ #### `@mui/x-data-grid-pro@8.3.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
122
+
123
+ Same changes as in `@mui/x-data-grid@8.3.0`.
124
+
125
+ #### `@mui/x-data-grid-premium@8.3.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
126
+
127
+ Same changes as in `@mui/x-data-grid-pro@8.3.0`.
128
+
129
+ ### Date and Time Pickers
130
+
131
+ #### `@mui/x-date-pickers@8.3.0`
132
+
133
+ - [DateTimePicker] Fix focus behavior on desktop variant (#17719) @LukasTy
134
+ - [pickers] Avoid `DigitalClock` stealing focus from a Picker open button on close (#17686) @LukasTy
135
+
136
+ #### `@mui/x-date-pickers-pro@8.3.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
137
+
138
+ Same changes as in `@mui/x-date-pickers@8.3.0`, plus:
139
+
140
+ - [DateRangePicker] Fix to reset range position after closing mobile Picker (#17631) @LukasTy
141
+
142
+ ### Charts
143
+
144
+ - The `<FunnelChart />` series now accepts a `variant='outlined'` prop for a simpler style.
145
+ <img width="398" alt="Screenshot 2025-05-06 at 20 36 12" src="https://github.com/user-attachments/assets/00fef14f-9026-421e-a4b6-7e081adce1e8" />
146
+
147
+ - Add a `borderRadius` property to `<FunnelChart />`. All funnels have `8px` as a default value.
148
+ <img width="386" alt="Screenshot 2025-05-06 at 14 00 20" src="https://github.com/user-attachments/assets/4f4cc0e7-01ce-4ed6-a0e1-a387f78def23" />
149
+
150
+ - Add a `pyramid` curve to `<FunnelChart />`, which allows creation of a pyramid-shaped funnel.
151
+ <img width="344" alt="Screenshot 2025-05-06 at 14 32 59" src="https://github.com/user-attachments/assets/0b2896e0-0478-4766-bb1b-258a4977a751" />
152
+
153
+ - Add a `step-pyramid` curve to `<FunnelChart />`, which creates a stepped-pyramid like shape.
154
+ <img width="344" alt="Screenshot 2025-05-06 at 14 33 03" src="https://github.com/user-attachments/assets/894f0ab3-7898-40fe-b0df-560feea4085a" />
155
+
156
+ #### `@mui/x-charts@8.3.0`
157
+
158
+ - [charts] Add charts toolbar with zoom options (#17615) @bernardobelchior
159
+ - [charts] Add zoom slider (#17496) @bernardobelchior
160
+ - [charts] Cleanup compiler warnings (#17360) @alexfauquette
161
+ - [charts] Fix `<PieArcLabel />` not taking `arcLabelRadius` into account (#17655) @bernardobelchior
162
+ - [charts] Fix spark line not having clip path (#17501) @bernardobelchior
163
+ - [charts] Fix type issue with ESM (#17624) @alexfauquette
164
+ - [charts] Improve `<MarkElement />` performance (#17546) @bernardobelchior
165
+ - [charts] Rename `materialSlots` internal constant (#17710) @bernardobelchior
166
+ - [charts] Update zoom slider design (#17682) @bernardobelchior
167
+ - [charts] Fix zoom being documented as available for heatmap (#17657) @bernardobelchior
168
+
169
+ #### `@mui/x-charts-pro@8.3.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
170
+
171
+ Same changes as in `@mui/x-charts@8.3.0`, plus:
172
+
173
+ - [charts-pro] Add `pyramid` curve to `<FunnelChart />` (#17665) @JCQuintas
174
+ - [charts-pro] Add `variant='outlined'` to `<FunnelChart />` series (#17661) @JCQuintas
175
+ - [charts-pro] Add a `borderRadius` property to `<FunnelChart />` (#17660) @JCQuintas
176
+
177
+ ### Tree View
178
+
179
+ #### `@mui/x-tree-view@8.3.0`
180
+
181
+ - [tree view] Bug fix - Escape does not cancel Drag n Drop (#17735) @rita-codes
182
+ - [tree view] Fix keyboard navigation error (#17685) @rita-codes
183
+ - [tree view] Continue cleaning the plugin system (#17386) @flaviendelangle
184
+
185
+ #### `@mui/x-tree-view-pro@8.3.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
186
+
187
+ Same changes as in `@mui/x-tree-view@8.3.0`.
188
+
189
+ ### Docs
190
+
191
+ - [charts] Add population pyramid demo (#17652) @bernardobelchior
192
+ - [charts] Fix randomised argos test (#17658) @JCQuintas
193
+ - [docs] Make preview messaging consistent in charts @bernardobelchior
194
+
195
+ ### Core
196
+
197
+ - [code-infra] Avoid `node` types in the built packages (#17533) @LukasTy
198
+ - [code-infra] Add `pkg.pr.new` publishing (#17402) @Janpot
199
+ - [code-infra] Normalize author package in org @oliviertassinari
200
+ - [code-infra] Remove required checkout step (#17729) @JCQuintas
201
+ - [docs-infra] Normalize netlify.toml in org @oliviertassinari
202
+
8
203
  ## 8.2.0
9
204
 
10
205
  _May 1, 2025_
@@ -424,8 +619,7 @@ We'd like to offer a big thanks to the 12 contributors who made this release pos
424
619
  - 📚 Documentation improvements
425
620
  - 🐞 Bugfixes
426
621
 
427
- Team members who have contributed to this release:
428
- @bernardobelchior, @cherniavskii, @flaviendelangle, @JCQuintas, @KenanYusuf, @LukasTy, @MBilalShafi, @michelengelen, @oliviertassinari, @noraleonte, @romgrk, @alexfauquette.
622
+ Team members who have contributed to this release: @bernardobelchior, @cherniavskii, @flaviendelangle, @JCQuintas, @KenanYusuf, @LukasTy, @MBilalShafi, @michelengelen, @oliviertassinari, @noraleonte, @romgrk, @alexfauquette.
429
623
 
430
624
  <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
431
625
 
@@ -738,7 +932,7 @@ We'd like to offer a big thanks to the 21 contributors who made this release pos
738
932
  - 🌍 Improve Chinese (zh-CN), (zh-HK), (zh-TW), Czech (cs-CZ), Korean (ko-KR) and Slovak (sk-Sk) locales on the Data Grid
739
933
  - 🌍 Improve Chinese (zh-CN), (zh-HK) and (zh-TW) locales on the Pickers
740
934
 
741
- ## Breaking changes
935
+ ### Breaking changes
742
936
 
743
937
  - ℹ️ The peer dependency on `@mui/material` has been updated to accept only v7.
744
938
  This has been done to increase the adoption rate of ESM.
@@ -751,7 +945,7 @@ Following are all team members who have contributed to this release:
751
945
 
752
946
  <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
753
947
 
754
- ## Alpha release highlights
948
+ ### Alpha release highlights
755
949
 
756
950
  Below are the highlights of the alpha releases leading up to this beta release:
757
951
 
@@ -3045,8 +3239,7 @@ We'd like to offer a big thanks to the 4 contributors who made this release poss
3045
3239
 
3046
3240
  - 🐞 Bugfixes
3047
3241
 
3048
- Team members who have contributed to this release:
3049
- @arminmeh, @cherniavskii, @LukasTy, @michelengelen.
3242
+ Team members who have contributed to this release: @arminmeh, @cherniavskii, @LukasTy, @michelengelen.
3050
3243
 
3051
3244
  <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
3052
3245
 
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.GridScrollArea = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
  var React = _interopRequireWildcard(require("react"));
12
- var _clsx = _interopRequireDefault(require("clsx"));
13
12
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
14
13
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
15
14
  var _system = require("@mui/system");
@@ -149,7 +148,7 @@ function GridScrollAreaContent(props) {
149
148
  }
150
149
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridScrollAreaRawRoot, {
151
150
  ref: rootRef,
152
- className: (0, _clsx.default)(classes.root),
151
+ className: classes.root,
153
152
  ownerState: ownerState,
154
153
  onDragOver: handleDragOver,
155
154
  style: style
@@ -11,7 +11,6 @@ var React = _interopRequireWildcard(require("react"));
11
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
12
12
  var _system = require("@mui/system");
13
13
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
14
- var _clsx = _interopRequireDefault(require("clsx"));
15
14
  var _gridRowsUtils = require("../../hooks/features/rows/gridRowsUtils");
16
15
  var _useGridSelector = require("../../hooks/utils/useGridSelector");
17
16
  var _dimensions = require("../../hooks/features/dimensions");
@@ -70,11 +69,11 @@ function GridOverlayWrapper(props) {
70
69
  classes: rootProps.classes
71
70
  }));
72
71
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridOverlayWrapperRoot, (0, _extends2.default)({
73
- className: (0, _clsx.default)(classes.root)
72
+ className: classes.root
74
73
  }, props, {
75
74
  right: dimensions.columnsTotalWidth - dimensions.viewportOuterSize.width,
76
75
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(GridOverlayWrapperInner, (0, _extends2.default)({
77
- className: (0, _clsx.default)(classes.inner),
76
+ className: classes.inner,
78
77
  style: {
79
78
  height,
80
79
  width: dimensions.viewportOuterSize.width
@@ -65,11 +65,13 @@ const GridCellCheckboxForwardRef = exports.GridCellCheckboxForwardRef = (0, _for
65
65
  }
66
66
  }, []);
67
67
  const isSelectable = apiRef.current.isRowSelectable(id);
68
- const checkboxPropsSelector = (0, _utils2.getCheckboxPropsSelector)(id, rootProps.rowSelectionPropagation?.parents ?? false);
69
68
  const {
70
69
  isIndeterminate,
71
70
  isChecked
72
- } = (0, _useGridSelector.useGridSelector)(apiRef, checkboxPropsSelector, undefined, _useGridSelector.objectShallowCompare);
71
+ } = (0, _useGridSelector.useGridSelector)(apiRef, _utils2.checkboxPropsSelector, {
72
+ groupId: id,
73
+ autoSelectParents: rootProps.rowSelectionPropagation?.parents ?? false
74
+ });
73
75
  if (rowNode.type === 'footer' || rowNode.type === 'pinnedRow') {
74
76
  return null;
75
77
  }
@@ -83,6 +83,10 @@ const GridHeaderCheckbox = exports.GridHeaderCheckbox = (0, _forwardRef.forwardR
83
83
  const candidates = new Set();
84
84
  for (let i = 0; i < rowIds.length; i += 1) {
85
85
  const id = rowIds[i];
86
+ if (!apiRef.current.getRow(id)) {
87
+ // The row could have been removed
88
+ continue;
89
+ }
86
90
  if (apiRef.current.isRowSelectable(id)) {
87
91
  candidates.add(id);
88
92
  }
@@ -2,7 +2,6 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
- import clsx from 'clsx';
6
5
  import useEventCallback from '@mui/utils/useEventCallback';
7
6
  import composeClasses from '@mui/utils/composeClasses';
8
7
  import { styled } from '@mui/system';
@@ -142,7 +141,7 @@ function GridScrollAreaContent(props) {
142
141
  }
143
142
  return /*#__PURE__*/_jsx(GridScrollAreaRawRoot, {
144
143
  ref: rootRef,
145
- className: clsx(classes.root),
144
+ className: classes.root,
146
145
  ownerState: ownerState,
147
146
  onDragOver: handleDragOver,
148
147
  style: style
@@ -3,7 +3,6 @@ import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { styled } from '@mui/system';
5
5
  import composeClasses from '@mui/utils/composeClasses';
6
- import clsx from 'clsx';
7
6
  import { minimalContentHeight } from "../../hooks/features/rows/gridRowsUtils.js";
8
7
  import { useGridSelector } from "../../hooks/utils/useGridSelector.js";
9
8
  import { gridDimensionsSelector } from "../../hooks/features/dimensions/index.js";
@@ -62,11 +61,11 @@ export function GridOverlayWrapper(props) {
62
61
  classes: rootProps.classes
63
62
  }));
64
63
  return /*#__PURE__*/_jsx(GridOverlayWrapperRoot, _extends({
65
- className: clsx(classes.root)
64
+ className: classes.root
66
65
  }, props, {
67
66
  right: dimensions.columnsTotalWidth - dimensions.viewportOuterSize.width,
68
67
  children: /*#__PURE__*/_jsx(GridOverlayWrapperInner, _extends({
69
- className: clsx(classes.inner),
68
+ className: classes.inner,
70
69
  style: {
71
70
  height,
72
71
  width: dimensions.viewportOuterSize.width
@@ -8,8 +8,8 @@ import { forwardRef } from '@mui/x-internals/forwardRef';
8
8
  import { useGridApiContext } from "../../hooks/utils/useGridApiContext.js";
9
9
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
10
10
  import { getDataGridUtilityClass } from "../../constants/gridClasses.js";
11
- import { objectShallowCompare, useGridSelector } from "../../hooks/utils/useGridSelector.js";
12
- import { getCheckboxPropsSelector } from "../../hooks/features/rowSelection/utils.js";
11
+ import { useGridSelector } from "../../hooks/utils/useGridSelector.js";
12
+ import { checkboxPropsSelector } from "../../hooks/features/rowSelection/utils.js";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const useUtilityClasses = ownerState => {
15
15
  const {
@@ -57,11 +57,13 @@ const GridCellCheckboxForwardRef = forwardRef(function GridCellCheckboxRenderer(
57
57
  }
58
58
  }, []);
59
59
  const isSelectable = apiRef.current.isRowSelectable(id);
60
- const checkboxPropsSelector = getCheckboxPropsSelector(id, rootProps.rowSelectionPropagation?.parents ?? false);
61
60
  const {
62
61
  isIndeterminate,
63
62
  isChecked
64
- } = useGridSelector(apiRef, checkboxPropsSelector, undefined, objectShallowCompare);
63
+ } = useGridSelector(apiRef, checkboxPropsSelector, {
64
+ groupId: id,
65
+ autoSelectParents: rootProps.rowSelectionPropagation?.parents ?? false
66
+ });
65
67
  if (rowNode.type === 'footer' || rowNode.type === 'pinnedRow') {
66
68
  return null;
67
69
  }
@@ -75,6 +75,10 @@ const GridHeaderCheckbox = forwardRef(function GridHeaderCheckbox(props, ref) {
75
75
  const candidates = new Set();
76
76
  for (let i = 0; i < rowIds.length; i += 1) {
77
77
  const id = rowIds[i];
78
+ if (!apiRef.current.getRow(id)) {
79
+ // The row could have been removed
80
+ continue;
81
+ }
78
82
  if (apiRef.current.isRowSelectable(id)) {
79
83
  candidates.add(id);
80
84
  }
@@ -302,13 +302,21 @@ export function getFirstNonSpannedColumnToRender({
302
302
  visibleRows
303
303
  }) {
304
304
  let firstNonSpannedColumnToRender = firstColumnToRender;
305
- for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
306
- const row = visibleRows[i];
307
- if (row) {
308
- const rowId = visibleRows[i].id;
309
- const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstColumnToRender);
310
- if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan) {
311
- firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
305
+ let foundStableColumn = false;
306
+
307
+ // Keep checking columns until we find one that's not spanned in any visible row
308
+ while (!foundStableColumn && firstNonSpannedColumnToRender >= 0) {
309
+ foundStableColumn = true;
310
+ for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
311
+ const row = visibleRows[i];
312
+ if (row) {
313
+ const rowId = visibleRows[i].id;
314
+ const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstNonSpannedColumnToRender);
315
+ if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan && cellColSpanInfo.leftVisibleCellIndex < firstNonSpannedColumnToRender) {
316
+ firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
317
+ foundStableColumn = false;
318
+ break; // Check the new column index against the visible rows, because it might be spanned
319
+ }
312
320
  }
313
321
  }
314
322
  }
@@ -7,6 +7,7 @@ import * as React from 'react';
7
7
  import { warnOnce } from '@mui/x-internals/warning';
8
8
  import useEventCallback from '@mui/utils/useEventCallback';
9
9
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
10
+ import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
10
11
  import { useGridEvent, useGridEventPriority } from "../../utils/useGridEvent.js";
11
12
  import { GridEditModes, GridCellModes } from "../../../models/gridEditRowModel.js";
12
13
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
@@ -330,7 +331,7 @@ export const useGridCellEditing = (apiRef, props) => {
330
331
  }
331
332
  const rowUpdate = apiRef.current.getRowWithUpdatedValuesFromCellEditing(id, field);
332
333
  if (props.dataSource?.updateRow) {
333
- if (row[field] === rowUpdate[field]) {
334
+ if (isDeepEqual(row, rowUpdate)) {
334
335
  finishCellEditMode();
335
336
  return;
336
337
  }
@@ -13,7 +13,7 @@ import { GridEditModes, GridRowModes } from "../../../models/gridEditRowModel.js
13
13
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
14
14
  import { gridEditRowsStateSelector, gridRowIsEditingSelector } from "./gridEditingSelectors.js";
15
15
  import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
16
- import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
16
+ import { gridColumnDefinitionsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
17
17
  import { gridRowsLookupSelector } from "../rows/gridRowsSelector.js";
18
18
  import { deepClone } from "../../../utils/utils.js";
19
19
  import { GridRowEditStopReasons, GridRowEditStartReasons } from "../../../models/params/gridRowParams.js";
@@ -313,8 +313,9 @@ export const useGridRowEditing = (apiRef, props) => {
313
313
  initialValue
314
314
  } = params;
315
315
  const row = apiRef.current.getRow(id);
316
- const columnFields = gridColumnFieldsSelector(apiRef);
317
- const newProps = columnFields.reduce((acc, field) => {
316
+ const columns = gridColumnDefinitionsSelector(apiRef);
317
+ const newProps = columns.reduce((acc, col) => {
318
+ const field = col.field;
318
319
  const cellParams = apiRef.current.getCellParams(id, field);
319
320
  if (!cellParams.isEditable) {
320
321
  return acc;
@@ -331,7 +332,7 @@ export const useGridRowEditing = (apiRef, props) => {
331
332
  acc[field] = {
332
333
  value: newValue,
333
334
  error: false,
334
- isProcessingProps: !!column.preProcessEditCellProps && deleteValue
335
+ isProcessingProps: column.editable && !!column.preProcessEditCellProps && deleteValue
335
336
  };
336
337
  return acc;
337
338
  }, {});
@@ -340,8 +341,8 @@ export const useGridRowEditing = (apiRef, props) => {
340
341
  if (fieldToFocus) {
341
342
  apiRef.current.setCellFocus(id, fieldToFocus);
342
343
  }
343
- columnFields.filter(field => !!apiRef.current.getColumn(field).preProcessEditCellProps && deleteValue).forEach(field => {
344
- const column = apiRef.current.getColumn(field);
344
+ columns.filter(column => column.editable && !!column.preProcessEditCellProps && deleteValue).forEach(column => {
345
+ const field = column.field;
345
346
  const value = apiRef.current.getCellValue(id, field);
346
347
  const newValue = deleteValue ? getDefaultCellValue(column) : initialValue ?? value;
347
348
  Promise.resolve(column.preProcessEditCellProps({
@@ -92,7 +92,7 @@ export const useGridRowSelection = (apiRef, props) => {
92
92
  /*
93
93
  * API METHODS
94
94
  */
95
- const setRowSelectionModel = React.useCallback(model => {
95
+ const setRowSelectionModel = React.useCallback((model, reason) => {
96
96
  if (props.signature === GridSignature.DataGrid && !canHaveMultipleSelection && (model.type !== 'include' || model.ids.size > 1)) {
97
97
  throw new Error(['MUI X: `rowSelectionModel` can only contain 1 item in DataGrid.', 'You need to upgrade to DataGridPro or DataGridPremium component to unlock multiple selection.'].join('\n'));
98
98
  }
@@ -101,7 +101,7 @@ export const useGridRowSelection = (apiRef, props) => {
101
101
  logger.debug(`Setting selection model`);
102
102
  apiRef.current.setState(state => _extends({}, state, {
103
103
  rowSelection: props.rowSelection ? model : emptyModel
104
- }));
104
+ }), reason);
105
105
  }
106
106
  }, [apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection]);
107
107
  const isRowSelected = React.useCallback(id => {
@@ -142,7 +142,7 @@ export const useGridRowSelection = (apiRef, props) => {
142
142
  findRowsToSelect(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow);
143
143
  }
144
144
  }
145
- apiRef.current.setRowSelectionModel(newSelectionModel);
145
+ apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
146
146
  } else {
147
147
  logger.debug(`Toggling selection for row ${id}`);
148
148
  const selectionModel = gridRowSelectionStateSelector(apiRef);
@@ -168,7 +168,7 @@ export const useGridRowSelection = (apiRef, props) => {
168
168
  }
169
169
  const isSelectionValid = newSelectionModel.type === 'include' && newSelectionModel.ids.size < 2 || canHaveMultipleSelection;
170
170
  if (isSelectionValid) {
171
- apiRef.current.setRowSelectionModel(newSelectionModel);
171
+ apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
172
172
  }
173
173
  }
174
174
  }, [apiRef, logger, applyAutoSelection, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, canHaveMultipleSelection]);
@@ -235,7 +235,7 @@ export const useGridRowSelection = (apiRef, props) => {
235
235
  }
236
236
  const isSelectionValid = newSelectionModel.type === 'include' && newSelectionModel.ids.size < 2 || canHaveMultipleSelection;
237
237
  if (isSelectionValid) {
238
- apiRef.current.setRowSelectionModel(newSelectionModel);
238
+ apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
239
239
  }
240
240
  }, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, props.rowSelection]);
241
241
  const getPropagatedRowSelectionModel = React.useCallback(inputSelectionModel => {
@@ -360,7 +360,7 @@ export const useGridRowSelection = (apiRef, props) => {
360
360
  apiRef.current.selectRows(Array.from(newSelectionModel.ids), true, true);
361
361
  }
362
362
  } else {
363
- apiRef.current.setRowSelectionModel(newSelectionModel);
363
+ apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
364
364
  }
365
365
  }
366
366
  }, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode, tree, getRowsToBeSelected]);
@@ -5,7 +5,10 @@ import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommuni
5
5
  import { type GridRowSelectionPropagation } from "../../../models/gridRowSelectionModel.js";
6
6
  import { type RowSelectionManager } from "../../../models/gridRowSelectionManager.js";
7
7
  export declare const ROW_SELECTION_PROPAGATION_DEFAULT: GridRowSelectionPropagation;
8
- export declare function getCheckboxPropsSelector(groupId: GridRowId, autoSelectParents: boolean): import("@mui/x-data-grid").OutputSelector<import("../../../models/gridStateCommunity.js").GridStateCommunity, RowSelectionManager, {
8
+ export declare const checkboxPropsSelector: import("@mui/x-data-grid").OutputSelector<import("../../../models/gridStateCommunity.js").GridStateCommunity, {
9
+ groupId: GridRowId;
10
+ autoSelectParents: boolean;
11
+ }, {
9
12
  isIndeterminate: boolean;
10
13
  isChecked: boolean;
11
14
  }>;
@@ -27,41 +27,42 @@ function getGridRowGroupSelectableDescendants(apiRef, groupId) {
27
27
  }
28
28
  return descendants;
29
29
  }
30
-
31
- // TODO v8: Use `createSelectorV8`
32
- export function getCheckboxPropsSelector(groupId, autoSelectParents) {
33
- return createSelector(gridRowTreeSelector, gridSortedRowIdsSelector, gridFilteredRowsLookupSelector, gridRowSelectionManagerSelector, (rowTree, sortedRowIds, filteredRowsLookup, rowSelectionManager) => {
34
- const groupNode = rowTree[groupId];
35
- if (!groupNode || groupNode.type !== 'group') {
36
- return {
37
- isIndeterminate: false,
38
- isChecked: rowSelectionManager.has(groupId)
39
- };
30
+ export const checkboxPropsSelector = createSelector(gridRowTreeSelector, gridFilteredRowsLookupSelector, gridRowSelectionManagerSelector, (rowTree, filteredRowsLookup, rowSelectionManager, {
31
+ groupId,
32
+ autoSelectParents
33
+ }) => {
34
+ const groupNode = rowTree[groupId];
35
+ if (!groupNode || groupNode.type !== 'group' || rowSelectionManager.has(groupId)) {
36
+ return {
37
+ isIndeterminate: false,
38
+ isChecked: rowSelectionManager.has(groupId)
39
+ };
40
+ }
41
+ let hasSelectedDescendant = false;
42
+ let hasUnSelectedDescendant = false;
43
+ const traverseDescendants = itemToTraverseId => {
44
+ if (filteredRowsLookup[itemToTraverseId] === false ||
45
+ // Perf: Skip checking the rest of the descendants if we already
46
+ // know that there is a selected and an unselected descendant
47
+ hasSelectedDescendant && hasUnSelectedDescendant) {
48
+ return;
40
49
  }
41
- if (rowSelectionManager.has(groupId)) {
42
- return {
43
- isIndeterminate: false,
44
- isChecked: true
45
- };
50
+ const node = rowTree[itemToTraverseId];
51
+ if (node?.type === 'group') {
52
+ node.children.forEach(traverseDescendants);
46
53
  }
47
- let selectableDescendantsCount = 0;
48
- let selectedDescendantsCount = 0;
49
- const startIndex = sortedRowIds.findIndex(id => id === groupId) + 1;
50
- for (let index = startIndex; index < sortedRowIds.length && rowTree[sortedRowIds[index]]?.depth > groupNode.depth; index += 1) {
51
- const id = sortedRowIds[index];
52
- if (filteredRowsLookup[id] !== false) {
53
- selectableDescendantsCount += 1;
54
- if (rowSelectionManager.has(id)) {
55
- selectedDescendantsCount += 1;
56
- }
57
- }
54
+ if (rowSelectionManager.has(itemToTraverseId)) {
55
+ hasSelectedDescendant = true;
56
+ } else {
57
+ hasUnSelectedDescendant = true;
58
58
  }
59
- return {
60
- isIndeterminate: selectedDescendantsCount > 0 && (selectedDescendantsCount < selectableDescendantsCount || !rowSelectionManager.has(groupId)),
61
- isChecked: autoSelectParents ? selectedDescendantsCount > 0 : rowSelectionManager.has(groupId)
62
- };
63
- });
64
- }
59
+ };
60
+ traverseDescendants(groupId);
61
+ return {
62
+ isIndeterminate: hasSelectedDescendant && hasUnSelectedDescendant,
63
+ isChecked: autoSelectParents ? hasSelectedDescendant && !hasUnSelectedDescendant : false
64
+ };
65
+ });
65
66
  export function isMultipleRowSelectionEnabled(props) {
66
67
  if (props.signature === GridSignature.DataGrid) {
67
68
  // DataGrid Community has multiple row selection enabled only if checkbox selection is enabled.
@@ -97,7 +98,7 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
97
98
  export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow, rowSelectionManager = gridRowSelectionManagerSelector(apiRef)) => {
98
99
  const filteredRows = gridFilteredRowsLookupSelector(apiRef);
99
100
  const selectedDescendants = new Set([]);
100
- if (!autoSelectDescendants && !autoSelectParents) {
101
+ if (!autoSelectDescendants && !autoSelectParents || filteredRows[selectedRow] === false) {
101
102
  return;
102
103
  }
103
104
  if (autoSelectDescendants) {
@@ -218,12 +218,13 @@ export const useGridVirtualScroller = () => {
218
218
  scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6);
219
219
  const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
220
220
  const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
221
-
222
- // Prevents batching render context changes
223
- ReactDOM.flushSync(() => {
224
- updateRenderContext(nextRenderContext);
225
- });
226
- scrollTimeout.start(1000, triggerUpdateRenderContext);
221
+ if (!areRenderContextsEqual(nextRenderContext, renderContext)) {
222
+ // Prevents batching render context changes
223
+ ReactDOM.flushSync(() => {
224
+ updateRenderContext(nextRenderContext);
225
+ });
226
+ scrollTimeout.start(1000, triggerUpdateRenderContext);
227
+ }
227
228
  return nextRenderContext;
228
229
  });
229
230
  const forceUpdateRenderContext = () => {