@mui/x-data-grid 7.0.0-beta.4 → 7.0.0-beta.6

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 (116) hide show
  1. package/CHANGELOG.md +271 -61
  2. package/DataGrid/DataGrid.js +2 -0
  3. package/colDef/gridBooleanOperators.js +1 -1
  4. package/components/GridPinnedRows.d.ts +1 -2
  5. package/components/GridRow.d.ts +7 -9
  6. package/components/GridRow.js +41 -54
  7. package/components/cell/GridCell.d.ts +2 -3
  8. package/components/cell/GridCell.js +10 -10
  9. package/components/cell/GridSkeletonCell.d.ts +3 -2
  10. package/components/cell/GridSkeletonCell.js +14 -6
  11. package/components/columnSelection/GridCellCheckboxRenderer.js +6 -4
  12. package/components/columnsManagement/GridColumnsManagement.js +1 -1
  13. package/components/containers/GridRootStyles.js +9 -4
  14. package/components/virtualization/GridBottomContainer.js +1 -1
  15. package/components/virtualization/GridTopContainer.js +1 -1
  16. package/components/virtualization/GridVirtualScroller.js +7 -5
  17. package/components/virtualization/GridVirtualScrollerRenderZone.js +9 -3
  18. package/hooks/core/pipeProcessing/useGridPipeProcessing.js +22 -20
  19. package/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -8
  20. package/hooks/features/columns/gridColumnsSelector.d.ts +6 -0
  21. package/hooks/features/columns/gridColumnsSelector.js +8 -1
  22. package/hooks/features/columns/useGridColumns.js +4 -0
  23. package/hooks/features/dimensions/useGridDimensions.js +1 -0
  24. package/hooks/features/editing/useGridRowEditing.js +1 -2
  25. package/hooks/features/filter/useGridFilter.js +2 -2
  26. package/hooks/features/rows/useGridParamsApi.js +6 -10
  27. package/hooks/features/rows/useGridRows.js +8 -4
  28. package/hooks/features/rows/useGridRowsMeta.js +5 -13
  29. package/hooks/features/sorting/gridSortingUtils.js +9 -1
  30. package/hooks/features/sorting/useGridSorting.js +2 -2
  31. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +0 -9
  32. package/hooks/features/virtualization/gridVirtualizationSelectors.js +0 -7
  33. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +3 -0
  34. package/hooks/features/virtualization/useGridVirtualScroller.js +88 -138
  35. package/hooks/features/virtualization/useGridVirtualization.d.ts +0 -8
  36. package/hooks/features/virtualization/useGridVirtualization.js +1 -6
  37. package/hooks/utils/useTimeout.d.ts +5 -3
  38. package/hooks/utils/useTimeout.js +13 -5
  39. package/index.js +1 -1
  40. package/internals/index.d.ts +1 -1
  41. package/internals/index.js +1 -1
  42. package/models/api/gridApiCommon.d.ts +2 -1
  43. package/models/api/gridInfiniteLoaderApi.d.ts +6 -0
  44. package/models/api/gridInfiniteLoaderApi.js +1 -0
  45. package/models/colDef/gridColDef.d.ts +7 -0
  46. package/modern/DataGrid/DataGrid.js +2 -0
  47. package/modern/colDef/gridBooleanOperators.js +1 -1
  48. package/modern/components/GridRow.js +40 -53
  49. package/modern/components/cell/GridCell.js +10 -10
  50. package/modern/components/cell/GridSkeletonCell.js +14 -6
  51. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +6 -4
  52. package/modern/components/columnsManagement/GridColumnsManagement.js +1 -1
  53. package/modern/components/containers/GridRootStyles.js +9 -4
  54. package/modern/components/virtualization/GridBottomContainer.js +1 -1
  55. package/modern/components/virtualization/GridTopContainer.js +1 -1
  56. package/modern/components/virtualization/GridVirtualScroller.js +7 -5
  57. package/modern/components/virtualization/GridVirtualScrollerRenderZone.js +8 -3
  58. package/modern/hooks/core/pipeProcessing/useGridPipeProcessing.js +22 -20
  59. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -8
  60. package/modern/hooks/features/columns/gridColumnsSelector.js +8 -1
  61. package/modern/hooks/features/columns/useGridColumns.js +2 -0
  62. package/modern/hooks/features/dimensions/useGridDimensions.js +1 -0
  63. package/modern/hooks/features/editing/useGridRowEditing.js +1 -2
  64. package/modern/hooks/features/filter/useGridFilter.js +2 -2
  65. package/modern/hooks/features/rows/useGridParamsApi.js +6 -10
  66. package/modern/hooks/features/rows/useGridRows.js +8 -4
  67. package/modern/hooks/features/rows/useGridRowsMeta.js +5 -13
  68. package/modern/hooks/features/sorting/gridSortingUtils.js +9 -1
  69. package/modern/hooks/features/sorting/useGridSorting.js +2 -2
  70. package/modern/hooks/features/virtualization/gridVirtualizationSelectors.js +0 -7
  71. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +85 -136
  72. package/modern/hooks/features/virtualization/useGridVirtualization.js +1 -6
  73. package/modern/hooks/utils/useTimeout.js +13 -5
  74. package/modern/index.js +1 -1
  75. package/modern/internals/index.js +1 -1
  76. package/modern/models/api/gridInfiniteLoaderApi.js +1 -0
  77. package/modern/utils/createSelector.js +12 -20
  78. package/modern/utils/utils.js +9 -0
  79. package/node/DataGrid/DataGrid.js +1 -0
  80. package/node/colDef/gridBooleanOperators.js +1 -1
  81. package/node/components/GridRow.js +40 -53
  82. package/node/components/cell/GridCell.js +10 -10
  83. package/node/components/cell/GridSkeletonCell.js +15 -7
  84. package/node/components/columnSelection/GridCellCheckboxRenderer.js +6 -4
  85. package/node/components/columnsManagement/GridColumnsManagement.js +1 -1
  86. package/node/components/containers/GridRootStyles.js +9 -4
  87. package/node/components/virtualization/GridBottomContainer.js +1 -1
  88. package/node/components/virtualization/GridTopContainer.js +1 -1
  89. package/node/components/virtualization/GridVirtualScroller.js +7 -5
  90. package/node/components/virtualization/GridVirtualScrollerRenderZone.js +7 -2
  91. package/node/hooks/core/pipeProcessing/useGridPipeProcessing.js +22 -20
  92. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +8 -5
  93. package/node/hooks/features/columns/gridColumnsSelector.js +9 -2
  94. package/node/hooks/features/columns/useGridColumns.js +2 -0
  95. package/node/hooks/features/dimensions/useGridDimensions.js +1 -0
  96. package/node/hooks/features/editing/useGridRowEditing.js +1 -2
  97. package/node/hooks/features/filter/useGridFilter.js +2 -2
  98. package/node/hooks/features/rows/useGridParamsApi.js +6 -10
  99. package/node/hooks/features/rows/useGridRows.js +8 -4
  100. package/node/hooks/features/rows/useGridRowsMeta.js +5 -13
  101. package/node/hooks/features/sorting/gridSortingUtils.js +9 -1
  102. package/node/hooks/features/sorting/useGridSorting.js +2 -2
  103. package/node/hooks/features/virtualization/gridVirtualizationSelectors.js +1 -8
  104. package/node/hooks/features/virtualization/useGridVirtualScroller.js +86 -136
  105. package/node/hooks/features/virtualization/useGridVirtualization.js +2 -7
  106. package/node/hooks/utils/useTimeout.js +13 -4
  107. package/node/index.js +1 -1
  108. package/node/internals/index.js +0 -7
  109. package/node/models/api/gridInfiniteLoaderApi.js +5 -0
  110. package/node/utils/createSelector.js +14 -23
  111. package/node/utils/utils.js +12 -1
  112. package/package.json +2 -2
  113. package/utils/createSelector.d.ts +0 -1
  114. package/utils/createSelector.js +12 -22
  115. package/utils/utils.d.ts +4 -0
  116. package/utils/utils.js +9 -0
@@ -6,17 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.EMPTY_DETAIL_PANELS = void 0;
8
8
  exports.areRenderContextsEqual = areRenderContextsEqual;
9
+ exports.computeOffsetLeft = computeOffsetLeft;
9
10
  exports.useGridVirtualScroller = void 0;
10
11
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
12
  var React = _interopRequireWildcard(require("react"));
12
13
  var ReactDOM = _interopRequireWildcard(require("react-dom"));
13
14
  var _utils = require("@mui/utils");
14
15
  var _styles = require("@mui/material/styles");
15
- var _reselect = require("reselect");
16
16
  var _useGridPrivateApiContext = require("../../utils/useGridPrivateApiContext");
17
17
  var _useGridRootProps = require("../../utils/useGridRootProps");
18
18
  var _useGridSelector = require("../../utils/useGridSelector");
19
- var _useLazyRef = require("../../utils/useLazyRef");
20
19
  var _useResizeObserver = require("../../utils/useResizeObserver");
21
20
  var _useRunOnce = require("../../utils/useRunOnce");
22
21
  var _gridColumnsSelector = require("../columns/gridColumnsSelector");
@@ -24,7 +23,8 @@ var _gridDimensionsSelectors = require("../dimensions/gridDimensionsSelectors");
24
23
  var _gridRowsSelector = require("../rows/gridRowsSelector");
25
24
  var _gridFocusStateSelector = require("../focus/gridFocusStateSelector");
26
25
  var _useGridVisibleRows = require("../../utils/useGridVisibleRows");
27
- var _utils2 = require("../../../utils/utils");
26
+ var _utils2 = require("../../utils");
27
+ var _utils3 = require("../../../utils/utils");
28
28
  var _gridRowSelectionSelector = require("../rowSelection/gridRowSelectionSelector");
29
29
  var _gridRowsMetaSelector = require("../rows/gridRowsMetaSelector");
30
30
  var _gridColumnsUtils = require("../columns/gridColumnsUtils");
@@ -60,40 +60,29 @@ const useGridVirtualScroller = () => {
60
60
  const scrollbarHorizontalRef = React.useRef(null);
61
61
  const contentHeight = dimensions.contentSize.height;
62
62
  const columnsTotalWidth = dimensions.columnsTotalWidth;
63
+ const hasColSpan = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridHasColSpanSelector);
63
64
  (0, _useResizeObserver.useResizeObserver)(mainRef, () => apiRef.current.resize());
64
65
  const previousContext = React.useRef(_useGridVirtualization.EMPTY_RENDER_CONTEXT);
65
66
  const previousRowContext = React.useRef(_useGridVirtualization.EMPTY_RENDER_CONTEXT);
66
- const offsets = (0, _useGridSelector.useGridSelector)(apiRef, _gridVirtualizationSelectors.gridOffsetsSelector);
67
67
  const renderContext = (0, _useGridSelector.useGridSelector)(apiRef, _gridVirtualizationSelectors.gridRenderContextSelector);
68
68
  const scrollPosition = React.useRef({
69
69
  top: 0,
70
70
  left: 0
71
71
  }).current;
72
72
  const prevTotalWidth = React.useRef(columnsTotalWidth);
73
- const getRenderedColumns = (0, _useLazyRef.useLazyRef)(createGetRenderedColumns).current;
74
- const indexOfRowWithFocusedCell = React.useMemo(() => {
75
- if (cellFocus !== null) {
76
- return currentPage.rows.findIndex(row => row.id === cellFocus.id);
77
- }
78
- return -1;
79
- }, [cellFocus, currentPage.rows]);
80
- const indexOfColumnWithFocusedCell = React.useMemo(() => {
81
- if (cellFocus !== null) {
82
- return visibleColumns.findIndex(column => column.field === cellFocus.field);
83
- }
84
- return -1;
85
- }, [cellFocus, visibleColumns]);
73
+ const focusedCell = {
74
+ rowIndex: React.useMemo(() => cellFocus ? currentPage.rows.findIndex(row => row.id === cellFocus.id) : -1, [cellFocus, currentPage.rows]),
75
+ columnIndex: React.useMemo(() => cellFocus ? visibleColumns.findIndex(column => column.field === cellFocus.field) : -1, [cellFocus, visibleColumns])
76
+ };
86
77
  const updateRenderContext = React.useCallback((nextRenderContext, rawRenderContext) => {
87
78
  if (areRenderContextsEqual(nextRenderContext, apiRef.current.state.virtualization.renderContext)) {
88
79
  return;
89
80
  }
90
81
  const didRowsIntervalChange = nextRenderContext.firstRowIndex !== previousRowContext.current.firstRowIndex || nextRenderContext.lastRowIndex !== previousRowContext.current.lastRowIndex;
91
- const nextOffsets = computeOffsets(apiRef, nextRenderContext, theme.direction, pinnedColumns.left.length);
92
82
  apiRef.current.setState(state => {
93
83
  return (0, _extends2.default)({}, state, {
94
84
  virtualization: (0, _extends2.default)({}, state.virtualization, {
95
- renderContext: nextRenderContext,
96
- offsets: nextOffsets
85
+ renderContext: nextRenderContext
97
86
  })
98
87
  });
99
88
  });
@@ -107,7 +96,7 @@ const useGridVirtualScroller = () => {
107
96
  }
108
97
  previousContext.current = rawRenderContext;
109
98
  prevTotalWidth.current = dimensions.columnsTotalWidth;
110
- }, [apiRef, pinnedColumns.left.length, theme.direction, dimensions.isReady, dimensions.columnsTotalWidth]);
99
+ }, [apiRef, dimensions.isReady, dimensions.columnsTotalWidth]);
111
100
  const triggerUpdateRenderContext = () => {
112
101
  const inputs = inputsSelector(apiRef, rootProps, enabled, enabledForColumns);
113
102
  const [nextRenderContext, rawRenderContext] = computeRenderContext(inputs, scrollPosition);
@@ -168,9 +157,12 @@ const useGridVirtualScroller = () => {
168
157
  const handleTouchMove = (0, _utils.unstable_useEventCallback)(event => {
169
158
  apiRef.current.publishEvent('virtualScrollerTouchMove', {}, event);
170
159
  });
171
- const minFirstColumn = pinnedColumns.left.length;
172
- const maxLastColumn = visibleColumns.length - pinnedColumns.right.length;
173
160
  const getRows = (params = {}) => {
161
+ if (!params.rows && !currentPage.range) {
162
+ return [];
163
+ }
164
+ const columnPositions = (0, _gridColumnsSelector.gridColumnPositionsSelector)(apiRef);
165
+ const currentRenderContext = params.renderContext ?? renderContext;
174
166
  const isLastSection = !hasBottomPinnedRows && params.position === undefined || hasBottomPinnedRows && params.position === 'bottom';
175
167
  const isPinnedSection = params.position !== undefined;
176
168
  let rowIndexOffset;
@@ -187,77 +179,57 @@ const useGridVirtualScroller = () => {
187
179
  rowIndexOffset = pinnedRows.top.length;
188
180
  break;
189
181
  }
190
- const firstRowToRender = renderContext.firstRowIndex;
191
- const lastRowToRender = renderContext.lastRowIndex;
192
- const firstColumnToRender = renderContext.firstColumnIndex;
193
- const lastColumnToRender = renderContext.lastColumnIndex;
194
- if (!params.rows && !currentPage.range) {
195
- return [];
196
- }
197
- const renderedRows = params.rows ?? currentPage.rows.slice(firstRowToRender, lastRowToRender);
198
-
199
- // If the selected row is not within the current range of rows being displayed,
200
- // we need to render it at either the top or bottom of the rows,
201
- // depending on whether it is above or below the range.
202
- let isRowWithFocusedCellNotInRange = false;
203
- if (!isPinnedSection && indexOfRowWithFocusedCell > -1 && (firstRowToRender > indexOfRowWithFocusedCell || lastRowToRender < indexOfRowWithFocusedCell)) {
204
- isRowWithFocusedCellNotInRange = true;
205
- const rowWithFocusedCell = currentPage.rows[indexOfRowWithFocusedCell];
206
- if (indexOfRowWithFocusedCell > firstRowToRender) {
207
- renderedRows.push(rowWithFocusedCell);
208
- } else {
209
- renderedRows.unshift(rowWithFocusedCell);
182
+ const rowModels = params.rows ?? currentPage.rows;
183
+ const firstRowToRender = currentRenderContext.firstRowIndex;
184
+ const lastRowToRender = Math.min(currentRenderContext.lastRowIndex, rowModels.length);
185
+ const rowIndexes = params.rows ? (0, _utils3.range)(0, params.rows.length) : (0, _utils3.range)(firstRowToRender, lastRowToRender);
186
+ let virtualRowIndex = -1;
187
+ if (!isPinnedSection && focusedCell.rowIndex !== -1) {
188
+ if (focusedCell.rowIndex < firstRowToRender) {
189
+ virtualRowIndex = focusedCell.rowIndex;
190
+ rowIndexes.unshift(virtualRowIndex);
210
191
  }
211
- }
212
- let isColumnWihFocusedCellNotInRange = false;
213
- if (!isPinnedSection && (firstColumnToRender > indexOfColumnWithFocusedCell || lastColumnToRender < indexOfColumnWithFocusedCell)) {
214
- isColumnWihFocusedCellNotInRange = true;
215
- }
216
- const {
217
- focusedCellColumnIndexNotInRange,
218
- renderedColumns
219
- } = getRenderedColumns(visibleColumns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, isColumnWihFocusedCellNotInRange ? indexOfColumnWithFocusedCell : -1);
220
- renderedRows.forEach(row => {
221
- apiRef.current.calculateColSpan({
222
- rowId: row.id,
223
- minFirstColumn,
224
- maxLastColumn,
225
- columns: visibleColumns
226
- });
227
- if (pinnedColumns.left.length > 0) {
228
- apiRef.current.calculateColSpan({
229
- rowId: row.id,
230
- minFirstColumn: 0,
231
- maxLastColumn: pinnedColumns.left.length,
232
- columns: visibleColumns
233
- });
234
- }
235
- if (pinnedColumns.right.length > 0) {
236
- apiRef.current.calculateColSpan({
237
- rowId: row.id,
238
- minFirstColumn: visibleColumns.length - pinnedColumns.right.length,
239
- maxLastColumn: visibleColumns.length,
240
- columns: visibleColumns
241
- });
192
+ if (focusedCell.rowIndex >= lastRowToRender) {
193
+ virtualRowIndex = focusedCell.rowIndex;
194
+ rowIndexes.push(virtualRowIndex);
242
195
  }
243
- });
196
+ }
244
197
  const rows = [];
245
198
  const rowProps = rootProps.slotProps?.row;
246
- let isRowWithFocusedCellRendered = false;
247
- for (let i = 0; i < renderedRows.length; i += 1) {
199
+ rowIndexes.forEach(rowIndexInPage => {
248
200
  const {
249
201
  id,
250
202
  model
251
- } = renderedRows[i];
252
- const rowIndexInPage = (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i;
253
- let index = rowIndexOffset + rowIndexInPage;
254
- if (isRowWithFocusedCellNotInRange && cellFocus?.id === id) {
255
- index = indexOfRowWithFocusedCell;
256
- isRowWithFocusedCellRendered = true;
257
- } else if (isRowWithFocusedCellRendered) {
258
- index -= 1;
203
+ } = rowModels[rowIndexInPage];
204
+
205
+ // NOTE: This is an expensive feature, the colSpan code could be optimized.
206
+ if (hasColSpan) {
207
+ const minFirstColumn = pinnedColumns.left.length;
208
+ const maxLastColumn = visibleColumns.length - pinnedColumns.right.length;
209
+ apiRef.current.calculateColSpan({
210
+ rowId: id,
211
+ minFirstColumn,
212
+ maxLastColumn,
213
+ columns: visibleColumns
214
+ });
215
+ if (pinnedColumns.left.length > 0) {
216
+ apiRef.current.calculateColSpan({
217
+ rowId: id,
218
+ minFirstColumn: 0,
219
+ maxLastColumn: pinnedColumns.left.length,
220
+ columns: visibleColumns
221
+ });
222
+ }
223
+ if (pinnedColumns.right.length > 0) {
224
+ apiRef.current.calculateColSpan({
225
+ rowId: id,
226
+ minFirstColumn: visibleColumns.length - pinnedColumns.right.length,
227
+ maxLastColumn: visibleColumns.length,
228
+ columns: visibleColumns
229
+ });
230
+ }
259
231
  }
260
- const isRowNotVisible = isRowWithFocusedCellNotInRange && cellFocus.id === id;
232
+ const hasFocus = cellFocus?.id === id;
261
233
  const baseRowHeight = !apiRef.current.rowHasAutoHeight(id) ? apiRef.current.unstable_getRowHeight(id) : 'auto';
262
234
  let isSelected;
263
235
  if (selectedRowsLookup[id] == null) {
@@ -273,47 +245,51 @@ const useGridVirtualScroller = () => {
273
245
  if (isLastSection) {
274
246
  if (!isPinnedSection) {
275
247
  const lastIndex = currentPage.rows.length - 1;
276
- const isLastVisibleRowIndex = isRowWithFocusedCellNotInRange ? firstRowToRender + i === lastIndex + 1 : firstRowToRender + i === lastIndex;
248
+ const isLastVisibleRowIndex = rowIndexInPage === lastIndex;
277
249
  if (isLastVisibleRowIndex) {
278
250
  isLastVisible = true;
279
251
  }
280
252
  } else {
281
- isLastVisible = i === renderedRows.length - 1;
253
+ isLastVisible = rowIndexInPage === rowModels.length - 1;
282
254
  }
283
255
  }
284
- const focusedCell = cellFocus !== null && cellFocus.id === id ? cellFocus.field : null;
285
- const columnWithFocusedCellNotInRange = focusedCellColumnIndexNotInRange !== undefined && visibleColumns[focusedCellColumnIndexNotInRange];
286
- const renderedColumnsWithFocusedCell = columnWithFocusedCellNotInRange && focusedCell ? [columnWithFocusedCellNotInRange, ...renderedColumns] : renderedColumns;
256
+ const isVirtualRow = rowIndexInPage === virtualRowIndex;
257
+ const isNotVisible = isVirtualRow;
287
258
  let tabbableCell = null;
288
259
  if (cellTabIndex !== null && cellTabIndex.id === id) {
289
260
  const cellParams = apiRef.current.getCellParams(id, cellTabIndex.field);
290
261
  tabbableCell = cellParams.cellMode === 'view' ? cellTabIndex.field : null;
291
262
  }
263
+ const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, theme.direction, pinnedColumns.left.length);
264
+ const rowIndex = (currentPage?.range?.firstRowIndex || 0) + rowIndexOffset + rowIndexInPage;
292
265
  rows.push( /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.row, (0, _extends2.default)({
293
266
  row: model,
294
267
  rowId: id,
295
- index: index,
268
+ index: rowIndex,
269
+ selected: isSelected,
270
+ offsetTop: params.rows ? undefined : rowsMeta.positions[rowIndexInPage],
271
+ offsetLeft: offsetLeft,
272
+ dimensions: dimensions,
296
273
  rowHeight: baseRowHeight,
297
- focusedCell: focusedCell,
298
274
  tabbableCell: tabbableCell,
299
- focusedCellColumnIndexNotInRange: focusedCellColumnIndexNotInRange,
300
- renderedColumns: renderedColumnsWithFocusedCell,
301
- visibleColumns: visibleColumns,
302
275
  pinnedColumns: pinnedColumns,
303
- firstColumnToRender: firstColumnToRender,
304
- lastColumnToRender: lastColumnToRender,
305
- selected: isSelected,
306
- offsets: offsets,
307
- dimensions: dimensions,
276
+ visibleColumns: visibleColumns,
277
+ renderContext: currentRenderContext,
278
+ focusedColumnIndex: hasFocus ? focusedCell.columnIndex : undefined,
308
279
  isFirstVisible: isFirstVisible,
309
280
  isLastVisible: isLastVisible,
310
- isNotVisible: isRowNotVisible
281
+ isNotVisible: isNotVisible
311
282
  }, rowProps), id));
312
283
  const panel = panels.get(id);
313
284
  if (panel) {
314
285
  rows.push(panel);
315
286
  }
316
- }
287
+ if (isLastVisible) {
288
+ rows.push(apiRef.current.getInfiniteLoadingTriggerElement?.({
289
+ lastRowId: id
290
+ }));
291
+ }
292
+ });
317
293
  return rows;
318
294
  };
319
295
  const needsHorizontalScrollbar = outerSize.width && columnsTotalWidth >= outerSize.width;
@@ -366,6 +342,9 @@ const useGridVirtualScroller = () => {
366
342
  apiRef.current.register('private', {
367
343
  updateRenderContext: forceUpdateRenderContext
368
344
  });
345
+ (0, _utils2.useGridApiEventHandler)(apiRef, 'columnsChange', forceUpdateRenderContext);
346
+ (0, _utils2.useGridApiEventHandler)(apiRef, 'filteredRowsSet', forceUpdateRenderContext);
347
+ (0, _utils2.useGridApiEventHandler)(apiRef, 'rowExpansionChange', forceUpdateRenderContext);
369
348
  return {
370
349
  renderContext,
371
350
  setPanels,
@@ -400,29 +379,6 @@ const useGridVirtualScroller = () => {
400
379
  };
401
380
  };
402
381
  exports.useGridVirtualScroller = useGridVirtualScroller;
403
- function createGetRenderedColumns() {
404
- return (0, _reselect.defaultMemoize)((columns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, indexOfColumnWithFocusedCell) => {
405
- // If the selected column is not within the current range of columns being displayed,
406
- // we need to render it at either the left or right of the columns,
407
- // depending on whether it is above or below the range.
408
- let focusedCellColumnIndexNotInRange;
409
- const renderedColumns = columns.slice(firstColumnToRender, lastColumnToRender);
410
- if (indexOfColumnWithFocusedCell > -1) {
411
- // check if it is not on the left pinned column.
412
- if (firstColumnToRender > indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell >= minFirstColumn) {
413
- focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
414
- }
415
- // check if it is not on the right pinned column.
416
- else if (lastColumnToRender < indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell < maxLastColumn) {
417
- focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
418
- }
419
- }
420
- return {
421
- focusedCellColumnIndexNotInRange,
422
- renderedColumns
423
- };
424
- });
425
- }
426
382
  function inputsSelector(apiRef, rootProps, enabled, enabledForColumns) {
427
383
  const dimensions = (0, _gridDimensionsSelectors.gridDimensionsSelector)(apiRef.current.state);
428
384
  const currentPage = (0, _useGridVisibleRows.getVisibleRows)(apiRef, rootProps);
@@ -505,7 +461,7 @@ function getNearestIndexToRender(inputs, offset) {
505
461
  // Check if all rows in this page are already measured
506
462
  allRowsMeasured = lastMeasuredIndexRelativeToAllRows >= inputs.range.lastRowIndex;
507
463
  }
508
- const lastMeasuredIndexRelativeToCurrentPage = (0, _utils2.clamp)(lastMeasuredIndexRelativeToAllRows - (inputs.range?.firstRowIndex || 0), 0, inputs.rowsMeta.positions.length);
464
+ const lastMeasuredIndexRelativeToCurrentPage = (0, _utils3.clamp)(lastMeasuredIndexRelativeToAllRows - (inputs.range?.firstRowIndex || 0), 0, inputs.rowsMeta.positions.length);
509
465
  if (allRowsMeasured || inputs.rowsMeta.positions[lastMeasuredIndexRelativeToCurrentPage] >= offset) {
510
466
  // If all rows were measured (when no row has "auto" as height) or all rows before the offset
511
467
  // were measured, then use a binary search because it's faster.
@@ -592,7 +548,7 @@ function getIndexesToRender({
592
548
  minFirstIndex,
593
549
  maxLastIndex
594
550
  }) {
595
- return [(0, _utils2.clamp)(firstIndex - buffer, minFirstIndex, maxLastIndex), (0, _utils2.clamp)(lastIndex + buffer, minFirstIndex, maxLastIndex)];
551
+ return [(0, _utils3.clamp)(firstIndex - buffer, minFirstIndex, maxLastIndex), (0, _utils3.clamp)(lastIndex + buffer, minFirstIndex, maxLastIndex)];
596
552
  }
597
553
  function areRenderContextsEqual(context1, context2) {
598
554
  if (context1 === context2) {
@@ -600,14 +556,8 @@ function areRenderContextsEqual(context1, context2) {
600
556
  }
601
557
  return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
602
558
  }
603
- function computeOffsets(apiRef, renderContext, direction, pinnedLeftLength) {
559
+ function computeOffsetLeft(columnPositions, renderContext, direction, pinnedLeftLength) {
604
560
  const factor = direction === 'ltr' ? 1 : -1;
605
- const rowPositions = (0, _gridRowsMetaSelector.gridRowsMetaSelector)(apiRef.current.state).positions;
606
- const columnPositions = (0, _gridColumnsSelector.gridColumnPositionsSelector)(apiRef);
607
- const top = rowPositions[renderContext.firstRowIndex] ?? 0;
608
561
  const left = factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0);
609
- return {
610
- top,
611
- left
612
- };
562
+ return left;
613
563
  }
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.EMPTY_RENDER_CONTEXT = exports.EMPTY_OFFSETS = void 0;
7
+ exports.EMPTY_RENDER_CONTEXT = void 0;
8
8
  exports.useGridVirtualization = useGridVirtualization;
9
9
  exports.virtualizationStateInitializer = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
@@ -12,10 +12,6 @@ var React = _interopRequireWildcard(require("react"));
12
12
  var _useGridApiMethod = require("../../utils/useGridApiMethod");
13
13
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
14
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
- const EMPTY_OFFSETS = exports.EMPTY_OFFSETS = {
16
- top: 0,
17
- left: 0
18
- };
19
15
  const EMPTY_RENDER_CONTEXT = exports.EMPTY_RENDER_CONTEXT = {
20
16
  firstRowIndex: 0,
21
17
  lastRowIndex: 0,
@@ -26,8 +22,7 @@ const virtualizationStateInitializer = (state, props) => {
26
22
  const virtualization = {
27
23
  enabled: !props.disableVirtualization,
28
24
  enabledForColumns: true,
29
- renderContext: EMPTY_RENDER_CONTEXT,
30
- offsets: EMPTY_OFFSETS
25
+ renderContext: EMPTY_RENDER_CONTEXT
31
26
  };
32
27
  return (0, _extends2.default)({}, state, {
33
28
  virtualization
@@ -1,18 +1,20 @@
1
1
  "use strict";
2
+ 'use client';
2
3
 
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
7
+ exports.Timeout = void 0;
6
8
  exports.useTimeout = useTimeout;
7
9
  var _useLazyRef = require("./useLazyRef");
8
10
  var _useOnMount = require("./useOnMount");
9
11
  class Timeout {
10
12
  constructor() {
11
- this.currentId = 0;
13
+ this.currentId = null;
12
14
  this.clear = () => {
13
- if (this.currentId !== 0) {
15
+ if (this.currentId !== null) {
14
16
  clearTimeout(this.currentId);
15
- this.currentId = 0;
17
+ this.currentId = null;
16
18
  }
17
19
  };
18
20
  this.disposeEffect = () => {
@@ -22,11 +24,18 @@ class Timeout {
22
24
  static create() {
23
25
  return new Timeout();
24
26
  }
27
+ /**
28
+ * Executes `fn` after `delay`, clearing any previously scheduled call.
29
+ */
25
30
  start(delay, fn) {
26
31
  this.clear();
27
- this.currentId = setTimeout(fn, delay);
32
+ this.currentId = setTimeout(() => {
33
+ this.currentId = null;
34
+ fn();
35
+ }, delay);
28
36
  }
29
37
  }
38
+ exports.Timeout = Timeout;
30
39
  function useTimeout() {
31
40
  const timeout = (0, _useLazyRef.useLazyRef)(Timeout.create).current;
32
41
  (0, _useOnMount.useOnMount)(timeout.disposeEffect);
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.0.0-beta.4
2
+ * @mui/x-data-grid v7.0.0-beta.6
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -80,7 +80,6 @@ var _exportNames = {
80
80
  defaultGetRowsToExport: true,
81
81
  createSelector: true,
82
82
  createSelectorMemoized: true,
83
- unstable_resetCreateSelectorCache: true,
84
83
  findParentElementFromClassName: true,
85
84
  getActiveElement: true,
86
85
  isEventTargetInPortal: true,
@@ -391,12 +390,6 @@ Object.defineProperty(exports, "sortingStateInitializer", {
391
390
  return _useGridSorting.sortingStateInitializer;
392
391
  }
393
392
  });
394
- Object.defineProperty(exports, "unstable_resetCreateSelectorCache", {
395
- enumerable: true,
396
- get: function () {
397
- return _createSelector.unstable_resetCreateSelectorCache;
398
- }
399
- });
400
393
  Object.defineProperty(exports, "unwrapPrivateAPI", {
401
394
  enumerable: true,
402
395
  get: function () {
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -3,12 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.unstable_resetCreateSelectorCache = exports.createSelectorMemoized = exports.createSelector = void 0;
6
+ exports.createSelectorMemoized = exports.createSelector = void 0;
7
7
  var _reselect = require("reselect");
8
8
  var _warning = require("./warning");
9
- const cacheContainer = {
10
- cache: new WeakMap()
11
- };
9
+ const cache = new WeakMap();
12
10
  const missingInstanceIdWarning = (0, _warning.buildWarning)(['MUI X: A selector was called without passing the instance ID, which may impact the performance of the grid.', 'To fix, call it with `apiRef`, e.g. `mySelector(apiRef)`, or pass the instance ID explicitly, e.g. `mySelector(state, apiRef.current.instanceId)`.']);
13
11
  function checkIsAPIRef(value) {
14
12
  return 'current' in value && 'instanceId' in value.current;
@@ -82,8 +80,7 @@ const createSelector = (a, b, c, d, e, f, ...rest) => {
82
80
  };
83
81
  exports.createSelector = createSelector;
84
82
  const createSelectorMemoized = (...args) => {
85
- const selector = (...selectorArgs) => {
86
- const [stateOrApiRef, instanceId] = selectorArgs;
83
+ const selector = (stateOrApiRef, instanceId) => {
87
84
  const isAPIRef = checkIsAPIRef(stateOrApiRef);
88
85
  const cacheKey = isAPIRef ? stateOrApiRef.current.instanceId : instanceId ?? DEFAULT_INSTANCE_ID;
89
86
  const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
@@ -92,20 +89,20 @@ const createSelectorMemoized = (...args) => {
92
89
  missingInstanceIdWarning();
93
90
  }
94
91
  }
95
- const {
96
- cache
97
- } = cacheContainer;
98
- if (cache.get(cacheKey) && cache.get(cacheKey)?.get(args)) {
92
+ const cacheArgsInit = cache.get(cacheKey);
93
+ const cacheArgs = cacheArgsInit ?? new Map();
94
+ const cacheFn = cacheArgs?.get(args);
95
+ if (cacheArgs && cacheFn) {
99
96
  // We pass the cache key because the called selector might have as
100
97
  // dependency another selector created with this `createSelector`.
101
- return cache.get(cacheKey)?.get(args)(state, cacheKey);
98
+ return cacheFn(state, cacheKey);
102
99
  }
103
- const newSelector = (0, _reselect.createSelector)(...args);
104
- if (!cache.get(cacheKey)) {
105
- cache.set(cacheKey, new Map());
100
+ const fn = (0, _reselect.createSelector)(...args);
101
+ if (!cacheArgsInit) {
102
+ cache.set(cacheKey, cacheArgs);
106
103
  }
107
- cache.get(cacheKey)?.set(args, newSelector);
108
- return newSelector(state, cacheKey);
104
+ cacheArgs.set(args, fn);
105
+ return fn(state, cacheKey);
109
106
  };
110
107
 
111
108
  // We use this property to detect if the selector was created with createSelector
@@ -113,10 +110,4 @@ const createSelectorMemoized = (...args) => {
113
110
  selector.acceptsApiRef = true;
114
111
  return selector;
115
112
  };
116
-
117
- // eslint-disable-next-line @typescript-eslint/naming-convention
118
- exports.createSelectorMemoized = createSelectorMemoized;
119
- const unstable_resetCreateSelectorCache = () => {
120
- cacheContainer.cache = new WeakMap();
121
- };
122
- exports.unstable_resetCreateSelectorCache = unstable_resetCreateSelectorCache;
113
+ exports.createSelectorMemoized = createSelectorMemoized;
@@ -13,6 +13,7 @@ exports.isNumber = isNumber;
13
13
  exports.isObject = isObject;
14
14
  exports.localStorageAvailable = localStorageAvailable;
15
15
  exports.randomNumberBetween = randomNumberBetween;
16
+ exports.range = range;
16
17
  function isNumber(value) {
17
18
  return typeof value === 'number' && !Number.isNaN(value);
18
19
  }
@@ -45,6 +46,16 @@ function escapeRegExp(value) {
45
46
  */
46
47
  const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
47
48
 
49
+ /**
50
+ * Create an array containing the range [from, to[
51
+ */
52
+ exports.clamp = clamp;
53
+ function range(from, to) {
54
+ return Array.from({
55
+ length: to - from
56
+ }).map((_, i) => from + i);
57
+ }
58
+
48
59
  /**
49
60
  * Based on `fast-deep-equal`
50
61
  *
@@ -71,7 +82,7 @@ const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
71
82
  * SOFTWARE.
72
83
  * We only type the public interface to avoid dozens of `as` in the function.
73
84
  */
74
- exports.clamp = clamp;
85
+
75
86
  function isDeepEqual(a, b) {
76
87
  if (a === b) {
77
88
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "7.0.0-beta.4",
3
+ "version": "7.0.0-beta.6",
4
4
  "description": "The community edition of the data grid component (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",
@@ -36,7 +36,7 @@
36
36
  "directory": "packages/x-data-grid"
37
37
  },
38
38
  "dependencies": {
39
- "@babel/runtime": "^7.23.9",
39
+ "@babel/runtime": "^7.24.0",
40
40
  "@mui/system": "^5.15.9",
41
41
  "@mui/utils": "^5.15.9",
42
42
  "clsx": "^2.1.0",
@@ -20,5 +20,4 @@ type SelectorArgs<Selectors extends ReadonlyArray<Selector<any>>, Result> = [sel
20
20
  type CreateSelectorFunction = <Selectors extends ReadonlyArray<Selector<any>>, Result>(...items: SelectorArgs<Selectors, Result>) => OutputSelector<StateFromSelectorList<Selectors>, Result>;
21
21
  export declare const createSelector: CreateSelectorFunction;
22
22
  export declare const createSelectorMemoized: CreateSelectorFunction;
23
- export declare const unstable_resetCreateSelectorCache: () => void;
24
23
  export {};
@@ -1,8 +1,6 @@
1
1
  import { createSelector as reselectCreateSelector } from 'reselect';
2
2
  import { buildWarning } from './warning';
3
- const cacheContainer = {
4
- cache: new WeakMap()
5
- };
3
+ const cache = new WeakMap();
6
4
  const missingInstanceIdWarning = buildWarning(['MUI X: A selector was called without passing the instance ID, which may impact the performance of the grid.', 'To fix, call it with `apiRef`, e.g. `mySelector(apiRef)`, or pass the instance ID explicitly, e.g. `mySelector(state, apiRef.current.instanceId)`.']);
7
5
  function checkIsAPIRef(value) {
8
6
  return 'current' in value && 'instanceId' in value.current;
@@ -75,9 +73,7 @@ export const createSelector = (a, b, c, d, e, f, ...rest) => {
75
73
  return selector;
76
74
  };
77
75
  export const createSelectorMemoized = (...args) => {
78
- const selector = (...selectorArgs) => {
79
- var _cache$get, _cache$get3;
80
- const [stateOrApiRef, instanceId] = selectorArgs;
76
+ const selector = (stateOrApiRef, instanceId) => {
81
77
  const isAPIRef = checkIsAPIRef(stateOrApiRef);
82
78
  const cacheKey = isAPIRef ? stateOrApiRef.current.instanceId : instanceId != null ? instanceId : DEFAULT_INSTANCE_ID;
83
79
  const state = isAPIRef ? stateOrApiRef.current.state : stateOrApiRef;
@@ -86,30 +82,24 @@ export const createSelectorMemoized = (...args) => {
86
82
  missingInstanceIdWarning();
87
83
  }
88
84
  }
89
- const {
90
- cache
91
- } = cacheContainer;
92
- if (cache.get(cacheKey) && (_cache$get = cache.get(cacheKey)) != null && _cache$get.get(args)) {
93
- var _cache$get2;
85
+ const cacheArgsInit = cache.get(cacheKey);
86
+ const cacheArgs = cacheArgsInit != null ? cacheArgsInit : new Map();
87
+ const cacheFn = cacheArgs == null ? void 0 : cacheArgs.get(args);
88
+ if (cacheArgs && cacheFn) {
94
89
  // We pass the cache key because the called selector might have as
95
90
  // dependency another selector created with this `createSelector`.
96
- return (_cache$get2 = cache.get(cacheKey)) == null ? void 0 : _cache$get2.get(args)(state, cacheKey);
91
+ return cacheFn(state, cacheKey);
97
92
  }
98
- const newSelector = reselectCreateSelector(...args);
99
- if (!cache.get(cacheKey)) {
100
- cache.set(cacheKey, new Map());
93
+ const fn = reselectCreateSelector(...args);
94
+ if (!cacheArgsInit) {
95
+ cache.set(cacheKey, cacheArgs);
101
96
  }
102
- (_cache$get3 = cache.get(cacheKey)) == null || _cache$get3.set(args, newSelector);
103
- return newSelector(state, cacheKey);
97
+ cacheArgs.set(args, fn);
98
+ return fn(state, cacheKey);
104
99
  };
105
100
 
106
101
  // We use this property to detect if the selector was created with createSelector
107
102
  // or it's only a simple function the receives the state and returns part of it.
108
103
  selector.acceptsApiRef = true;
109
104
  return selector;
110
- };
111
-
112
- // eslint-disable-next-line @typescript-eslint/naming-convention
113
- export const unstable_resetCreateSelectorCache = () => {
114
- cacheContainer.cache = new WeakMap();
115
105
  };