@mui/x-data-grid 7.29.3 → 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,55 @@
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
+
6
55
  ## 7.29.3
7
56
 
8
57
  _May 8, 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
  }
@@ -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 => {
@@ -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.3
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
  }
@@ -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 => {
@@ -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.3
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
  }
@@ -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 => {
@@ -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.3
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.3",
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",