@mui/x-data-grid 7.29.2 → 7.29.4

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,93 @@
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.29.4
7
+
8
+ _May 22, 2025_
9
+
10
+ We'd like to offer a big thanks to the 6 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 🐞 Bugfixes
13
+
14
+ Special thanks go out to the community members for their valuable contributions:
15
+ @campmarc, @whereisrmsqhs, @jyash97
16
+
17
+ Following are all team members who have contributed to this release:
18
+ @mapache-salvaje, @cherniavskii, @noraleonte.
19
+
20
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
21
+
22
+ ### Data Grid
23
+
24
+ #### `@mui/x-data-grid@7.29.4`
25
+
26
+ - [DataGrid] Fix `renderContext` calculation loop (#17806) @cherniavskii
27
+ - [DataGrid] Fix column spanning jump on scroll (#17780) @cherniavskii
28
+ - [DataGrid] Fix content rendering for large rows while using automatic page size (#17866) @campmarc
29
+
30
+ #### `@mui/x-data-grid-pro@7.29.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@7.29.4`, plus:
33
+
34
+ - [DataGridPro] Add `aria-expanded` attribute to the master detail toggle button (#17890) @whereisrmsqhs
35
+ - [DataGridPro] Prevent text selection when reordering rows (#17920) @jyash97
36
+
37
+ #### `@mui/x-data-grid-premium@7.29.4` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
38
+
39
+ Same changes as in `@mui/x-data-grid-pro@7.29.4`.
40
+
41
+ ### Date and Time Pickers
42
+
43
+ #### `@mui/x-date-pickers@7.29.4`
44
+
45
+ - [pickers] Fix `PickersTextField` overflow (#17945) @noraleonte
46
+
47
+ #### `@mui/x-date-pickers-pro@7.29.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
48
+
49
+ Same changes as in `@mui/x-date-pickers@7.29.4`.
50
+
51
+ ### Docs
52
+
53
+ - [docs] Add "upgrade to v8" callout on v7 planned pages (#17901) @mapache-salvaje
54
+
55
+ ## 7.29.3
56
+
57
+ _May 8, 2025_
58
+
59
+ We'd like to offer a big thanks to the 3 contributors who made this release possible. Here are some highlights ✨:
60
+
61
+ - 🐞 Bugfixes
62
+
63
+ Team members who have contributed to this release:
64
+ @arminmeh, @LukasTy, and @MBilalShafi.
65
+
66
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
67
+
68
+ ### Data Grid
69
+
70
+ #### `@mui/x-data-grid@7.29.3`
71
+
72
+ - [DataGrid] Ignore `preProcessEditCellProps` for non-editable columns when starting a row update (#17734) @arminmeh
73
+ - [DataGrid] Avoid applying row selection propagation on filtered rows (#17742) @MBilalShafi
74
+
75
+ #### `@mui/x-data-grid-pro@7.29.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
76
+
77
+ Same changes as in `@mui/x-data-grid@7.29.3`.
78
+
79
+ #### `@mui/x-data-grid-premium@7.29.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
80
+
81
+ Same changes as in `@mui/x-data-grid-pro@7.29.3`.
82
+
83
+ ### Date and Time Pickers
84
+
85
+ #### `@mui/x-date-pickers@7.29.3`
86
+
87
+ - [DateTimePicker] Fix focus behavior on desktop variant (#17730) @LukasTy
88
+
89
+ #### `@mui/x-date-pickers-pro@7.29.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
90
+
91
+ Same changes as in `@mui/x-date-pickers@7.29.3`.
92
+
6
93
  ## 7.29.2
7
94
 
8
95
  _May 1, 2025_
@@ -639,7 +639,7 @@ export const GridRootStyles = styled('div', {
639
639
  borderTop: 'none'
640
640
  }
641
641
  },
642
- [`&.${c['root--disableUserSelection']} .${c.cell}`]: {
642
+ [`&.${c['root--disableUserSelection']}`]: {
643
643
  userSelect: 'none'
644
644
  },
645
645
  [`& .${c['row--dynamicHeight']} > .${c.cell}`]: {
@@ -299,13 +299,21 @@ export function getFirstNonSpannedColumnToRender({
299
299
  visibleRows
300
300
  }) {
301
301
  let firstNonSpannedColumnToRender = firstColumnToRender;
302
- for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
303
- const row = visibleRows[i];
304
- if (row) {
305
- const rowId = visibleRows[i].id;
306
- const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstColumnToRender);
307
- if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan) {
308
- firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
302
+ let foundStableColumn = false;
303
+
304
+ // Keep checking columns until we find one that's not spanned in any visible row
305
+ while (!foundStableColumn) {
306
+ foundStableColumn = true;
307
+ for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
308
+ const row = visibleRows[i];
309
+ if (row) {
310
+ const rowId = visibleRows[i].id;
311
+ const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstNonSpannedColumnToRender);
312
+ if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan && cellColSpanInfo.leftVisibleCellIndex < firstNonSpannedColumnToRender) {
313
+ firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
314
+ foundStableColumn = false;
315
+ break; // Check the new column index against the visible rows, because it might be spanned
316
+ }
309
317
  }
310
318
  }
311
319
  }
@@ -11,7 +11,7 @@ import { GridEditModes, GridRowModes } from "../../../models/gridEditRowModel.js
11
11
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
12
12
  import { gridEditRowsStateSelector, gridRowIsEditingSelector } from "./gridEditingSelectors.js";
13
13
  import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
14
- import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
14
+ import { gridColumnDefinitionsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
15
15
  import { gridRowsLookupSelector } from "../rows/gridRowsSelector.js";
16
16
  import { deepClone } from "../../../utils/utils.js";
17
17
  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({
@@ -138,7 +138,7 @@ export const useGridPaginationModel = (apiRef, props) => {
138
138
  return;
139
139
  }
140
140
  const dimensions = apiRef.current.getRootDimensions();
141
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
141
+ const maximumPageSizeWithoutScrollBar = Math.max(1, Math.floor(dimensions.viewportInnerSize.height / rowHeight));
142
142
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
143
143
  }, [apiRef, props.autoPageSize, rowHeight]);
144
144
  const handleRowCountChange = React.useCallback(newRowCount => {
@@ -97,7 +97,7 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
97
97
  export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow, selectedIds = new Set(gridRowSelectionStateSelector(apiRef.current.state))) => {
98
98
  const filteredRows = gridFilteredRowsLookupSelector(apiRef);
99
99
  const selectedDescendants = new Set([]);
100
- if (!autoSelectDescendants && !autoSelectParents) {
100
+ if (!autoSelectDescendants && !autoSelectParents || filteredRows[selectedRow] === false) {
101
101
  return;
102
102
  }
103
103
  if (autoSelectDescendants) {
@@ -217,12 +217,13 @@ export const useGridVirtualScroller = () => {
217
217
  scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6);
218
218
  const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
219
219
  const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
220
-
221
- // Prevents batching render context changes
222
- ReactDOM.flushSync(() => {
223
- updateRenderContext(nextRenderContext);
224
- });
225
- scrollTimeout.start(1000, triggerUpdateRenderContext);
220
+ if (!areRenderContextsEqual(nextRenderContext, renderContext)) {
221
+ // Prevents batching render context changes
222
+ ReactDOM.flushSync(() => {
223
+ updateRenderContext(nextRenderContext);
224
+ });
225
+ scrollTimeout.start(1000, triggerUpdateRenderContext);
226
+ }
226
227
  return nextRenderContext;
227
228
  });
228
229
  const forceUpdateRenderContext = () => {
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.29.2
2
+ * @mui/x-data-grid v7.29.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -639,7 +639,7 @@ export const GridRootStyles = styled('div', {
639
639
  borderTop: 'none'
640
640
  }
641
641
  },
642
- [`&.${c['root--disableUserSelection']} .${c.cell}`]: {
642
+ [`&.${c['root--disableUserSelection']}`]: {
643
643
  userSelect: 'none'
644
644
  },
645
645
  [`& .${c['row--dynamicHeight']} > .${c.cell}`]: {
@@ -299,13 +299,21 @@ export function getFirstNonSpannedColumnToRender({
299
299
  visibleRows
300
300
  }) {
301
301
  let firstNonSpannedColumnToRender = firstColumnToRender;
302
- for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
303
- const row = visibleRows[i];
304
- if (row) {
305
- const rowId = visibleRows[i].id;
306
- const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstColumnToRender);
307
- if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan) {
308
- firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
302
+ let foundStableColumn = false;
303
+
304
+ // Keep checking columns until we find one that's not spanned in any visible row
305
+ while (!foundStableColumn) {
306
+ foundStableColumn = true;
307
+ for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
308
+ const row = visibleRows[i];
309
+ if (row) {
310
+ const rowId = visibleRows[i].id;
311
+ const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstNonSpannedColumnToRender);
312
+ if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan && cellColSpanInfo.leftVisibleCellIndex < firstNonSpannedColumnToRender) {
313
+ firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
314
+ foundStableColumn = false;
315
+ break; // Check the new column index against the visible rows, because it might be spanned
316
+ }
309
317
  }
310
318
  }
311
319
  }
@@ -11,7 +11,7 @@ import { GridEditModes, GridRowModes } from "../../../models/gridEditRowModel.js
11
11
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
12
12
  import { gridEditRowsStateSelector, gridRowIsEditingSelector } from "./gridEditingSelectors.js";
13
13
  import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
14
- import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
14
+ import { gridColumnDefinitionsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
15
15
  import { gridRowsLookupSelector } from "../rows/gridRowsSelector.js";
16
16
  import { deepClone } from "../../../utils/utils.js";
17
17
  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({
@@ -138,7 +138,7 @@ export const useGridPaginationModel = (apiRef, props) => {
138
138
  return;
139
139
  }
140
140
  const dimensions = apiRef.current.getRootDimensions();
141
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
141
+ const maximumPageSizeWithoutScrollBar = Math.max(1, Math.floor(dimensions.viewportInnerSize.height / rowHeight));
142
142
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
143
143
  }, [apiRef, props.autoPageSize, rowHeight]);
144
144
  const handleRowCountChange = React.useCallback(newRowCount => {
@@ -97,7 +97,7 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
97
97
  export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow, selectedIds = new Set(gridRowSelectionStateSelector(apiRef.current.state))) => {
98
98
  const filteredRows = gridFilteredRowsLookupSelector(apiRef);
99
99
  const selectedDescendants = new Set([]);
100
- if (!autoSelectDescendants && !autoSelectParents) {
100
+ if (!autoSelectDescendants && !autoSelectParents || filteredRows[selectedRow] === false) {
101
101
  return;
102
102
  }
103
103
  if (autoSelectDescendants) {
@@ -217,12 +217,13 @@ export const useGridVirtualScroller = () => {
217
217
  scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6);
218
218
  const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
219
219
  const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
220
-
221
- // Prevents batching render context changes
222
- ReactDOM.flushSync(() => {
223
- updateRenderContext(nextRenderContext);
224
- });
225
- scrollTimeout.start(1000, triggerUpdateRenderContext);
220
+ if (!areRenderContextsEqual(nextRenderContext, renderContext)) {
221
+ // Prevents batching render context changes
222
+ ReactDOM.flushSync(() => {
223
+ updateRenderContext(nextRenderContext);
224
+ });
225
+ scrollTimeout.start(1000, triggerUpdateRenderContext);
226
+ }
226
227
  return nextRenderContext;
227
228
  });
228
229
  const forceUpdateRenderContext = () => {
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.29.2
2
+ * @mui/x-data-grid v7.29.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -646,7 +646,7 @@ const GridRootStyles = exports.GridRootStyles = (0, _styles.styled)('div', {
646
646
  borderTop: 'none'
647
647
  }
648
648
  },
649
- [`&.${_gridClasses.gridClasses['root--disableUserSelection']} .${_gridClasses.gridClasses.cell}`]: {
649
+ [`&.${_gridClasses.gridClasses['root--disableUserSelection']}`]: {
650
650
  userSelect: 'none'
651
651
  },
652
652
  [`& .${_gridClasses.gridClasses['row--dynamicHeight']} > .${_gridClasses.gridClasses.cell}`]: {
@@ -314,13 +314,21 @@ function getFirstNonSpannedColumnToRender({
314
314
  visibleRows
315
315
  }) {
316
316
  let firstNonSpannedColumnToRender = firstColumnToRender;
317
- for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
318
- const row = visibleRows[i];
319
- if (row) {
320
- const rowId = visibleRows[i].id;
321
- const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstColumnToRender);
322
- if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan) {
323
- firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
317
+ let foundStableColumn = false;
318
+
319
+ // Keep checking columns until we find one that's not spanned in any visible row
320
+ while (!foundStableColumn) {
321
+ foundStableColumn = true;
322
+ for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
323
+ const row = visibleRows[i];
324
+ if (row) {
325
+ const rowId = visibleRows[i].id;
326
+ const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, firstNonSpannedColumnToRender);
327
+ if (cellColSpanInfo && cellColSpanInfo.spannedByColSpan && cellColSpanInfo.leftVisibleCellIndex < firstNonSpannedColumnToRender) {
328
+ firstNonSpannedColumnToRender = cellColSpanInfo.leftVisibleCellIndex;
329
+ foundStableColumn = false;
330
+ break; // Check the new column index against the visible rows, because it might be spanned
331
+ }
324
332
  }
325
333
  }
326
334
  }
@@ -321,8 +321,9 @@ const useGridRowEditing = (apiRef, props) => {
321
321
  initialValue
322
322
  } = params;
323
323
  const row = apiRef.current.getRow(id);
324
- const columnFields = (0, _gridColumnsSelector.gridColumnFieldsSelector)(apiRef);
325
- const newProps = columnFields.reduce((acc, field) => {
324
+ const columns = (0, _gridColumnsSelector.gridColumnDefinitionsSelector)(apiRef);
325
+ const newProps = columns.reduce((acc, col) => {
326
+ const field = col.field;
326
327
  const cellParams = apiRef.current.getCellParams(id, field);
327
328
  if (!cellParams.isEditable) {
328
329
  return acc;
@@ -339,7 +340,7 @@ const useGridRowEditing = (apiRef, props) => {
339
340
  acc[field] = {
340
341
  value: newValue,
341
342
  error: false,
342
- isProcessingProps: !!column.preProcessEditCellProps && deleteValue
343
+ isProcessingProps: column.editable && !!column.preProcessEditCellProps && deleteValue
343
344
  };
344
345
  return acc;
345
346
  }, {});
@@ -348,8 +349,8 @@ const useGridRowEditing = (apiRef, props) => {
348
349
  if (fieldToFocus) {
349
350
  apiRef.current.setCellFocus(id, fieldToFocus);
350
351
  }
351
- columnFields.filter(field => !!apiRef.current.getColumn(field).preProcessEditCellProps && deleteValue).forEach(field => {
352
- const column = apiRef.current.getColumn(field);
352
+ columns.filter(column => column.editable && !!column.preProcessEditCellProps && deleteValue).forEach(column => {
353
+ const field = column.field;
353
354
  const value = apiRef.current.getCellValue(id, field);
354
355
  const newValue = deleteValue ? (0, _utils3.getDefaultCellValue)(column) : initialValue ?? value;
355
356
  Promise.resolve(column.preProcessEditCellProps({
@@ -147,7 +147,7 @@ const useGridPaginationModel = (apiRef, props) => {
147
147
  return;
148
148
  }
149
149
  const dimensions = apiRef.current.getRootDimensions();
150
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
150
+ const maximumPageSizeWithoutScrollBar = Math.max(1, Math.floor(dimensions.viewportInnerSize.height / rowHeight));
151
151
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
152
152
  }, [apiRef, props.autoPageSize, rowHeight]);
153
153
  const handleRowCountChange = React.useCallback(newRowCount => {
@@ -105,7 +105,7 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
105
105
  const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow, selectedIds = new Set((0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef.current.state))) => {
106
106
  const filteredRows = (0, _gridFilterSelector.gridFilteredRowsLookupSelector)(apiRef);
107
107
  const selectedDescendants = new Set([]);
108
- if (!autoSelectDescendants && !autoSelectParents) {
108
+ if (!autoSelectDescendants && !autoSelectParents || filteredRows[selectedRow] === false) {
109
109
  return;
110
110
  }
111
111
  if (autoSelectDescendants) {
@@ -228,12 +228,13 @@ const useGridVirtualScroller = () => {
228
228
  scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6);
229
229
  const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
230
230
  const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
231
-
232
- // Prevents batching render context changes
233
- ReactDOM.flushSync(() => {
234
- updateRenderContext(nextRenderContext);
235
- });
236
- scrollTimeout.start(1000, triggerUpdateRenderContext);
231
+ if (!areRenderContextsEqual(nextRenderContext, renderContext)) {
232
+ // Prevents batching render context changes
233
+ ReactDOM.flushSync(() => {
234
+ updateRenderContext(nextRenderContext);
235
+ });
236
+ scrollTimeout.start(1000, triggerUpdateRenderContext);
237
+ }
237
238
  return nextRenderContext;
238
239
  });
239
240
  const forceUpdateRenderContext = () => {
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.29.2
2
+ * @mui/x-data-grid v7.29.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "7.29.2",
3
+ "version": "7.29.4",
4
4
  "description": "The Community plan edition of the Data Grid components (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",