@mui/x-data-grid 8.17.0 → 8.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +213 -0
  2. package/DataGrid/useDataGridComponent.js +4 -3
  3. package/components/GridRow.js +1 -1
  4. package/components/cell/GridActionsCell.d.ts +9 -0
  5. package/components/cell/GridActionsCell.js +54 -36
  6. package/components/cell/GridActionsCellItem.js +0 -4
  7. package/components/cell/GridBooleanCell.js +0 -10
  8. package/components/cell/GridCell.js +4 -10
  9. package/components/columnHeaders/GridColumnHeaderItem.js +2 -2
  10. package/components/columnSelection/GridCellCheckboxRenderer.js +37 -22
  11. package/components/containers/GridRootStyles.js +1 -1
  12. package/components/toolbarV8/Toolbar.js +1 -1
  13. package/components/virtualization/GridVirtualScrollbar.d.ts +1 -0
  14. package/components/virtualization/GridVirtualScrollbar.js +13 -8
  15. package/components/virtualization/GridVirtualScroller.js +2 -1
  16. package/components/virtualization/GridVirtualScrollerRenderZone.js +1 -1
  17. package/constants/dataGridPropsDefaultValues.js +2 -1
  18. package/esm/DataGrid/useDataGridComponent.js +5 -4
  19. package/esm/components/GridRow.js +1 -1
  20. package/esm/components/cell/GridActionsCell.d.ts +9 -0
  21. package/esm/components/cell/GridActionsCell.js +55 -36
  22. package/esm/components/cell/GridActionsCellItem.js +0 -4
  23. package/esm/components/cell/GridBooleanCell.js +0 -10
  24. package/esm/components/cell/GridCell.js +4 -10
  25. package/esm/components/columnHeaders/GridColumnHeaderItem.js +2 -2
  26. package/esm/components/columnSelection/GridCellCheckboxRenderer.js +37 -22
  27. package/esm/components/containers/GridRootStyles.js +1 -1
  28. package/esm/components/toolbarV8/Toolbar.js +1 -1
  29. package/esm/components/virtualization/GridVirtualScrollbar.d.ts +1 -0
  30. package/esm/components/virtualization/GridVirtualScrollbar.js +12 -7
  31. package/esm/components/virtualization/GridVirtualScroller.js +2 -1
  32. package/esm/components/virtualization/GridVirtualScrollerRenderZone.js +1 -1
  33. package/esm/constants/dataGridPropsDefaultValues.js +2 -1
  34. package/esm/hooks/core/gridPropsSelectors.d.ts +2 -1
  35. package/esm/hooks/core/gridPropsSelectors.js +3 -0
  36. package/esm/hooks/core/useGridProps.js +8 -2
  37. package/esm/hooks/core/useGridVirtualizer.d.ts +80 -6
  38. package/esm/hooks/core/useGridVirtualizer.js +27 -12
  39. package/esm/hooks/features/columnGrouping/useGridColumnGrouping.js +6 -1
  40. package/esm/hooks/features/columnMenu/useGridColumnMenu.js +14 -4
  41. package/esm/hooks/features/columns/useGridColumnSpanning.js +9 -4
  42. package/esm/hooks/features/dimensions/useGridDimensions.js +12 -6
  43. package/esm/hooks/features/export/useGridPrintExport.js +18 -18
  44. package/esm/hooks/features/filter/useGridFilter.d.ts +1 -1
  45. package/esm/hooks/features/filter/useGridFilter.js +3 -1
  46. package/esm/hooks/features/focus/useGridFocus.js +0 -1
  47. package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  48. package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +189 -25
  49. package/esm/hooks/features/pagination/useGridPaginationMeta.js +3 -3
  50. package/esm/hooks/features/pagination/useGridPaginationModel.js +7 -4
  51. package/esm/hooks/features/pagination/useGridRowCount.js +31 -15
  52. package/esm/hooks/features/rowSelection/useGridRowSelection.js +8 -7
  53. package/esm/hooks/features/rowSelection/utils.d.ts +1 -0
  54. package/esm/hooks/features/rowSelection/utils.js +17 -4
  55. package/esm/hooks/features/rows/gridRowSpanningUtils.js +8 -5
  56. package/esm/hooks/features/rows/useGridParamsApi.js +2 -12
  57. package/esm/hooks/features/rows/useGridRowSpanning.js +23 -60
  58. package/esm/hooks/features/scroll/useGridScroll.js +2 -3
  59. package/esm/hooks/features/sorting/useGridSorting.d.ts +1 -1
  60. package/esm/hooks/features/sorting/useGridSorting.js +3 -1
  61. package/esm/hooks/features/virtualization/useGridVirtualization.js +24 -5
  62. package/esm/hooks/utils/useGridApiRef.d.ts +1 -2
  63. package/esm/hooks/utils/useGridEvent.js +6 -2
  64. package/esm/hooks/utils/useRunOncePerLoop.d.ts +4 -1
  65. package/esm/hooks/utils/useRunOncePerLoop.js +28 -18
  66. package/esm/index.js +1 -1
  67. package/esm/models/colDef/gridColDef.d.ts +14 -0
  68. package/esm/models/events/gridEventLookup.d.ts +5 -0
  69. package/esm/models/gridStateCommunity.d.ts +1 -1
  70. package/esm/models/params/gridCellParams.d.ts +0 -10
  71. package/esm/models/props/DataGridProps.d.ts +13 -6
  72. package/esm/utils/keyboardUtils.d.ts +1 -8
  73. package/esm/utils/keyboardUtils.js +0 -7
  74. package/hooks/core/gridPropsSelectors.d.ts +2 -1
  75. package/hooks/core/gridPropsSelectors.js +4 -1
  76. package/hooks/core/useGridProps.js +8 -2
  77. package/hooks/core/useGridVirtualizer.d.ts +80 -6
  78. package/hooks/core/useGridVirtualizer.js +26 -11
  79. package/hooks/features/columnGrouping/useGridColumnGrouping.js +6 -1
  80. package/hooks/features/columnMenu/useGridColumnMenu.js +14 -4
  81. package/hooks/features/columns/useGridColumnSpanning.js +9 -4
  82. package/hooks/features/dimensions/useGridDimensions.js +12 -6
  83. package/hooks/features/export/useGridPrintExport.js +18 -18
  84. package/hooks/features/filter/useGridFilter.d.ts +1 -1
  85. package/hooks/features/filter/useGridFilter.js +3 -1
  86. package/hooks/features/focus/useGridFocus.js +0 -1
  87. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  88. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +189 -25
  89. package/hooks/features/pagination/useGridPaginationMeta.js +2 -2
  90. package/hooks/features/pagination/useGridPaginationModel.js +7 -4
  91. package/hooks/features/pagination/useGridRowCount.js +30 -14
  92. package/hooks/features/rowSelection/useGridRowSelection.js +8 -7
  93. package/hooks/features/rowSelection/utils.d.ts +1 -0
  94. package/hooks/features/rowSelection/utils.js +16 -3
  95. package/hooks/features/rows/gridRowSpanningUtils.js +8 -5
  96. package/hooks/features/rows/useGridParamsApi.js +2 -12
  97. package/hooks/features/rows/useGridRowSpanning.js +23 -60
  98. package/hooks/features/scroll/useGridScroll.js +2 -3
  99. package/hooks/features/sorting/useGridSorting.d.ts +1 -1
  100. package/hooks/features/sorting/useGridSorting.js +3 -1
  101. package/hooks/features/virtualization/useGridVirtualization.js +24 -5
  102. package/hooks/utils/useGridApiRef.d.ts +1 -2
  103. package/hooks/utils/useGridEvent.js +6 -2
  104. package/hooks/utils/useRunOncePerLoop.d.ts +4 -1
  105. package/hooks/utils/useRunOncePerLoop.js +27 -18
  106. package/index.js +1 -1
  107. package/models/colDef/gridColDef.d.ts +14 -0
  108. package/models/events/gridEventLookup.d.ts +5 -0
  109. package/models/gridStateCommunity.d.ts +1 -1
  110. package/models/params/gridCellParams.d.ts +0 -10
  111. package/models/props/DataGridProps.d.ts +13 -6
  112. package/package.json +4 -4
  113. package/utils/keyboardUtils.d.ts +1 -8
  114. package/utils/keyboardUtils.js +1 -13
@@ -49,18 +49,8 @@ function useGridParamsApi(apiRef, props, configuration) {
49
49
  value: forcedValue,
50
50
  formattedValue: forcedFormattedValue
51
51
  }) => {
52
- let value = row[field];
53
- if (forcedValue !== undefined) {
54
- value = forcedValue;
55
- } else if (colDef?.valueGetter) {
56
- value = colDef.valueGetter(value, row, colDef, apiRef);
57
- }
58
- let formattedValue = value;
59
- if (forcedFormattedValue !== undefined) {
60
- formattedValue = forcedFormattedValue;
61
- } else if (colDef?.valueFormatter) {
62
- formattedValue = colDef.valueFormatter(value, row, colDef, apiRef);
63
- }
52
+ const value = forcedValue !== undefined ? forcedValue : apiRef.current.getRowValue(row, colDef);
53
+ const formattedValue = forcedFormattedValue !== undefined ? forcedFormattedValue : apiRef.current.getRowFormattedValue(row, colDef);
64
54
  const params = {
65
55
  id,
66
56
  field,
@@ -16,8 +16,7 @@ var _gridVirtualizationSelectors = require("../virtualization/gridVirtualization
16
16
  var _gridRowSpanningUtils = require("./gridRowSpanningUtils");
17
17
  var _useGridEvent = require("../../utils/useGridEvent");
18
18
  var _utils = require("../../../utils/utils");
19
- var _pagination = require("../pagination");
20
- var _gridRowsSelector = require("./gridRowsSelector");
19
+ var _useRunOncePerLoop = require("../../utils/useRunOncePerLoop");
21
20
  const EMPTY_CACHES = {
22
21
  spannedCells: {},
23
22
  hiddenCells: {},
@@ -31,13 +30,6 @@ const EMPTY_STATE = {
31
30
  caches: EMPTY_CACHES,
32
31
  processedRange: EMPTY_RANGE
33
32
  };
34
-
35
- /**
36
- * Default number of rows to process during state initialization to avoid flickering.
37
- * Number `20` is arbitrarily chosen to be large enough to cover most of the cases without
38
- * compromising performance.
39
- */
40
- const DEFAULT_ROWS_TO_PROCESS = 20;
41
33
  const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToProcess, resetState) => {
42
34
  const virtualizer = apiRef.current.virtualizer;
43
35
  const previousState = resetState ? EMPTY_STATE : _features.Rowspan.selectors.state(virtualizer.store.state);
@@ -135,66 +127,26 @@ const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToPro
135
127
  processedRange
136
128
  };
137
129
  };
138
- const getInitialRangeToProcess = (props, apiRef) => {
139
- const rowCount = (0, _gridRowsSelector.gridDataRowIdsSelector)(apiRef).length;
140
- if (props.pagination) {
141
- const pageSize = (0, _pagination.gridPageSizeSelector)(apiRef);
142
- let paginationLastRowIndex = DEFAULT_ROWS_TO_PROCESS;
143
- if (pageSize > 0) {
144
- paginationLastRowIndex = pageSize - 1;
145
- }
146
- return {
147
- firstRowIndex: 0,
148
- lastRowIndex: Math.min(paginationLastRowIndex, rowCount)
149
- };
150
- }
151
- return {
152
- firstRowIndex: 0,
153
- lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS, rowCount)
154
- };
155
- };
156
130
 
157
131
  /**
158
132
  * @requires columnsStateInitializer (method) - should be initialized before
159
133
  * @requires rowsStateInitializer (method) - should be initialized before
160
134
  * @requires filterStateInitializer (method) - should be initialized before
161
135
  */
162
- const rowSpanningStateInitializer = (state, props, apiRef) => {
163
- if (!props.rowSpanning) {
164
- return (0, _extends2.default)({}, state, {
165
- rowSpanning: EMPTY_STATE
166
- });
167
- }
168
- const rowIds = state.rows.dataRowIds || [];
169
- const orderedFields = state.columns.orderedFields || [];
170
- const dataRowIdToModelLookup = state.rows.dataRowIdToModelLookup;
171
- const columnsLookup = state.columns.lookup;
172
- const isFilteringPending = Boolean(state.filter.filterModel.items.length) || Boolean(state.filter.filterModel.quickFilterValues?.length);
173
- if (!rowIds.length || !orderedFields.length || !dataRowIdToModelLookup || !columnsLookup || isFilteringPending) {
174
- return (0, _extends2.default)({}, state, {
175
- rowSpanning: EMPTY_STATE
176
- });
177
- }
178
- const rangeToProcess = getInitialRangeToProcess(props, apiRef);
179
- const rows = rowIds.map(id => ({
180
- id,
181
- model: dataRowIdToModelLookup[id]
182
- }));
183
- const colDefs = orderedFields.map(field => columnsLookup[field]);
184
- const rowSpanning = computeRowSpanningState(apiRef, colDefs, rows, rangeToProcess, rangeToProcess, true);
136
+ const rowSpanningStateInitializer = state => {
185
137
  return (0, _extends2.default)({}, state, {
186
- rowSpanning
138
+ rowSpanning: EMPTY_STATE
187
139
  });
188
140
  };
189
141
  exports.rowSpanningStateInitializer = rowSpanningStateInitializer;
190
142
  const useGridRowSpanning = (apiRef, props) => {
191
- const store = apiRef.current.virtualizer.store;
192
143
  const updateRowSpanningState = React.useCallback((renderContext, resetState = false) => {
144
+ const store = apiRef.current.virtualizer.store;
193
145
  const {
194
146
  range,
195
147
  rows: visibleRows
196
148
  } = (0, _useGridVisibleRows.getVisibleRows)(apiRef);
197
- if (resetState && store.getSnapshot().rowSpanning !== EMPTY_STATE) {
149
+ if (resetState) {
198
150
  store.set('rowSpanning', EMPTY_STATE);
199
151
  }
200
152
  if (range === null || !(0, _gridRowSpanningUtils.isRowContextInitialized)(renderContext)) {
@@ -220,7 +172,7 @@ const useGridRowSpanning = (apiRef, props) => {
220
172
  return;
221
173
  }
222
174
  store.set('rowSpanning', newState);
223
- }, [apiRef, store]);
175
+ }, [apiRef]);
224
176
 
225
177
  // Reset events trigger a full re-computation of the row spanning state:
226
178
  // - The `rowSpanning` prop is updated (feature flag)
@@ -228,26 +180,37 @@ const useGridRowSpanning = (apiRef, props) => {
228
180
  // - The sorting is applied
229
181
  // - The `paginationModel` is updated
230
182
  // - The rows are updated
183
+ const {
184
+ schedule: deferredUpdateRowSpanningState,
185
+ cancel
186
+ } = (0, _useRunOncePerLoop.useRunOncePerLoop)(updateRowSpanningState);
231
187
  const resetRowSpanningState = React.useCallback(() => {
232
188
  const renderContext = (0, _gridVirtualizationSelectors.gridRenderContextSelector)(apiRef);
233
189
  if (!(0, _gridRowSpanningUtils.isRowContextInitialized)(renderContext)) {
234
190
  return;
235
191
  }
236
- updateRowSpanningState(renderContext, true);
237
- }, [apiRef, updateRowSpanningState]);
238
- (0, _useGridEvent.useGridEvent)(apiRef, 'renderedRowsIntervalChange', (0, _utils.runIf)(props.rowSpanning, updateRowSpanningState));
192
+ deferredUpdateRowSpanningState(renderContext, true);
193
+ }, [apiRef, deferredUpdateRowSpanningState]);
194
+ (0, _useGridEvent.useGridEvent)(apiRef, 'renderedRowsIntervalChange', (0, _utils.runIf)(props.rowSpanning, renderContext => {
195
+ const didHavePendingReset = cancel();
196
+ updateRowSpanningState(renderContext, didHavePendingReset);
197
+ }));
239
198
  (0, _useGridEvent.useGridEvent)(apiRef, 'sortedRowsSet', (0, _utils.runIf)(props.rowSpanning, resetRowSpanningState));
240
199
  (0, _useGridEvent.useGridEvent)(apiRef, 'paginationModelChange', (0, _utils.runIf)(props.rowSpanning, resetRowSpanningState));
241
200
  (0, _useGridEvent.useGridEvent)(apiRef, 'filteredRowsSet', (0, _utils.runIf)(props.rowSpanning, resetRowSpanningState));
242
201
  (0, _useGridEvent.useGridEvent)(apiRef, 'columnsChange', (0, _utils.runIf)(props.rowSpanning, resetRowSpanningState));
243
202
  React.useEffect(() => {
203
+ const store = apiRef.current.virtualizer?.store;
204
+ if (!store) {
205
+ return;
206
+ }
244
207
  if (!props.rowSpanning) {
245
208
  if (store.state.rowSpanning !== EMPTY_STATE) {
246
209
  store.set('rowSpanning', EMPTY_STATE);
247
210
  }
248
- } else if (store.state.rowSpanning.caches === EMPTY_CACHES) {
249
- resetRowSpanningState();
211
+ } else if (store.state.rowSpanning === EMPTY_STATE) {
212
+ updateRowSpanningState((0, _gridVirtualizationSelectors.gridRenderContextSelector)(apiRef));
250
213
  }
251
- }, [apiRef, store, resetRowSpanningState, props.rowSpanning]);
214
+ }, [apiRef, props.rowSpanning, updateRowSpanningState]);
252
215
  };
253
216
  exports.useGridRowSpanning = useGridRowSpanning;
@@ -9,7 +9,6 @@ var React = _interopRequireWildcard(require("react"));
9
9
  var _RtlProvider = require("@mui/system/RtlProvider");
10
10
  var _useGridLogger = require("../../utils/useGridLogger");
11
11
  var _gridColumnsSelector = require("../columns/gridColumnsSelector");
12
- var _useGridSelector = require("../../utils/useGridSelector");
13
12
  var _gridPaginationSelector = require("../pagination/gridPaginationSelector");
14
13
  var _gridRowsSelector = require("../rows/gridRowsSelector");
15
14
  var _gridRowsMetaSelector = require("../rows/gridRowsMetaSelector");
@@ -53,7 +52,6 @@ const useGridScroll = (apiRef, props) => {
53
52
  const logger = (0, _useGridLogger.useGridLogger)(apiRef, 'useGridScroll');
54
53
  const colRef = apiRef.current.columnHeadersContainerRef;
55
54
  const virtualScrollerRef = apiRef.current.virtualScrollerRef;
56
- const visibleSortedRows = (0, _useGridSelector.useGridSelector)(apiRef, _gridFilterSelector.gridExpandedSortedRowEntriesSelector);
57
55
  const scrollToIndexes = React.useCallback(params => {
58
56
  const dimensions = (0, _dimensions.gridDimensionsSelector)(apiRef);
59
57
  const totalRowCount = (0, _gridRowsSelector.gridRowCountSelector)(apiRef);
@@ -68,6 +66,7 @@ const useGridScroll = (apiRef, props) => {
68
66
  const columnPositions = (0, _gridColumnsSelector.gridColumnPositionsSelector)(apiRef);
69
67
  let cellWidth;
70
68
  if (typeof params.rowIndex !== 'undefined') {
69
+ const visibleSortedRows = (0, _gridFilterSelector.gridExpandedSortedRowEntriesSelector)(apiRef);
71
70
  const rowId = visibleSortedRows[params.rowIndex]?.id;
72
71
  const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, params.colIndex);
73
72
  if (cellColSpanInfo && !cellColSpanInfo.spannedByColSpan) {
@@ -104,7 +103,7 @@ const useGridScroll = (apiRef, props) => {
104
103
  return true;
105
104
  }
106
105
  return false;
107
- }, [logger, apiRef, virtualScrollerRef, props.pagination, visibleSortedRows]);
106
+ }, [logger, apiRef, virtualScrollerRef, props.pagination]);
108
107
  const scroll = React.useCallback(params => {
109
108
  if (virtualScrollerRef.current && params.left !== undefined && colRef.current) {
110
109
  const direction = isRtl ? -1 : 1;
@@ -7,4 +7,4 @@ export declare const sortingStateInitializer: GridStateInitializer<Pick<DataGrid
7
7
  * @requires useGridRows (event)
8
8
  * @requires useGridColumns (event)
9
9
  */
10
- export declare const useGridSorting: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "initialState" | "sortModel" | "onSortModelChange" | "sortingOrder" | "sortingMode" | "disableColumnSorting" | "disableMultipleColumnsSorting" | "multipleColumnsSortingMode">) => void;
10
+ export declare const useGridSorting: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "initialState" | "sortModel" | "onSortModelChange" | "sortingOrder" | "sortingMode" | "disableColumnSorting" | "disableMultipleColumnsSorting" | "multipleColumnsSortingMode" | "signature">) => void;
@@ -245,7 +245,9 @@ const useGridSorting = (apiRef, props) => {
245
245
  * 1ST RENDER
246
246
  */
247
247
  (0, _useFirstRender.useFirstRender)(() => {
248
- apiRef.current.applySorting();
248
+ if (props.signature === 'DataGrid') {
249
+ apiRef.current.applySorting();
250
+ }
249
251
  });
250
252
 
251
253
  /**
@@ -39,9 +39,6 @@ const virtualizationStateInitializer = (state, props) => {
39
39
  };
40
40
  exports.virtualizationStateInitializer = virtualizationStateInitializer;
41
41
  function useGridVirtualization(apiRef, rootProps) {
42
- const {
43
- virtualizer
44
- } = apiRef.current;
45
42
  const {
46
43
  autoHeight,
47
44
  disableVirtualization
@@ -52,7 +49,14 @@ function useGridVirtualization(apiRef, rootProps) {
52
49
  */
53
50
 
54
51
  const setVirtualization = enabled => {
52
+ const {
53
+ virtualizer
54
+ } = apiRef.current;
55
55
  enabled && (enabled = HAS_LAYOUT);
56
+ const snapshot = virtualizer.store.getSnapshot();
57
+ if (snapshot.virtualization.enabled === enabled && snapshot.virtualization.enabledForRows === enabled && snapshot.virtualization.enabledForColumns === enabled) {
58
+ return;
59
+ }
56
60
  virtualizer.store.set('virtualization', (0, _extends2.default)({}, virtualizer.store.state.virtualization, {
57
61
  enabled,
58
62
  enabledForColumns: enabled,
@@ -60,7 +64,14 @@ function useGridVirtualization(apiRef, rootProps) {
60
64
  }));
61
65
  };
62
66
  const setColumnVirtualization = enabled => {
67
+ const {
68
+ virtualizer
69
+ } = apiRef.current;
63
70
  enabled && (enabled = HAS_LAYOUT);
71
+ const snapshot = virtualizer.store.getSnapshot();
72
+ if (snapshot.virtualization.enabledForColumns === enabled) {
73
+ return;
74
+ }
64
75
  virtualizer.store.set('virtualization', (0, _extends2.default)({}, virtualizer.store.state.virtualization, {
65
76
  enabledForColumns: enabled
66
77
  }));
@@ -70,7 +81,12 @@ function useGridVirtualization(apiRef, rootProps) {
70
81
  unstable_setColumnVirtualization: setColumnVirtualization
71
82
  };
72
83
  (0, _useGridApiMethod.useGridApiMethod)(apiRef, api, 'public');
73
- const forceUpdateRenderContext = virtualizer.api.forceUpdateRenderContext;
84
+ const forceUpdateRenderContext = () => {
85
+ const {
86
+ virtualizer
87
+ } = apiRef.current;
88
+ virtualizer?.api.scheduleUpdateRenderContext();
89
+ };
74
90
  apiRef.current.register('private', {
75
91
  updateRenderContext: forceUpdateRenderContext
76
92
  });
@@ -85,7 +101,10 @@ function useGridVirtualization(apiRef, rootProps) {
85
101
 
86
102
  /* eslint-disable react-hooks/exhaustive-deps */
87
103
  React.useEffect(() => {
104
+ if (!apiRef.current.virtualizer) {
105
+ return;
106
+ }
88
107
  setVirtualization(!rootProps.disableVirtualization);
89
- }, [disableVirtualization, autoHeight]);
108
+ }, [apiRef, disableVirtualization, autoHeight]);
90
109
  /* eslint-enable react-hooks/exhaustive-deps */
91
110
  }
@@ -1,7 +1,6 @@
1
1
  import { RefObject } from '@mui/x-internals/types';
2
- import { GridApiCommon } from "../../models/index.js";
3
2
  import { GridApiCommunity } from "../../models/api/gridApiCommunity.js";
4
3
  /**
5
4
  * Hook that instantiate a [[GridApiRef]].
6
5
  */
7
- export declare const useGridApiRef: <Api extends GridApiCommon = GridApiCommunity>() => RefObject<Api | null>;
6
+ export declare const useGridApiRef: () => RefObject<GridApiCommunity | null>;
@@ -33,7 +33,9 @@ function useGridEvent(apiRef, eventName, handler, options) {
33
33
  const cleanupTokenRef = React.useRef(null);
34
34
  if (!subscription.current && handlerRef.current) {
35
35
  const enhancedHandler = (params, event, details) => {
36
- if (!event.defaultMuiPrevented) {
36
+ // Check for the existence of the event once more to avoid Safari 26 issue
37
+ // https://github.com/mui/mui-x/issues/20159
38
+ if (event && !event.defaultMuiPrevented) {
37
39
  handlerRef.current?.(params, event, details);
38
40
  }
39
41
  };
@@ -60,7 +62,9 @@ function useGridEvent(apiRef, eventName, handler, options) {
60
62
  React.useEffect(() => {
61
63
  if (!subscription.current && handlerRef.current) {
62
64
  const enhancedHandler = (params, event, details) => {
63
- if (!event.defaultMuiPrevented) {
65
+ // Check for the existence of the event once more to avoid Safari 26 issue
66
+ // https://github.com/mui/mui-x/issues/20159
67
+ if (event && !event.defaultMuiPrevented) {
64
68
  handlerRef.current?.(params, event, details);
65
69
  }
66
70
  };
@@ -1 +1,4 @@
1
- export declare function useRunOncePerLoop<T extends (...args: any[]) => void>(callback: T, nextFrame?: boolean): (...args: Parameters<T>) => void;
1
+ export declare function useRunOncePerLoop<T extends (...args: any[]) => void>(callback: T): {
2
+ schedule: (...args: Parameters<T>) => void;
3
+ cancel: () => boolean;
4
+ };
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ 'use client';
2
3
 
3
4
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
5
  Object.defineProperty(exports, "__esModule", {
@@ -6,28 +7,36 @@ Object.defineProperty(exports, "__esModule", {
6
7
  });
7
8
  exports.useRunOncePerLoop = useRunOncePerLoop;
8
9
  var React = _interopRequireWildcard(require("react"));
9
- function useRunOncePerLoop(callback, nextFrame = false) {
10
- const scheduledRef = React.useRef(false);
10
+ function useRunOncePerLoop(callback) {
11
+ const scheduledCallbackRef = React.useRef(null);
11
12
  const schedule = React.useCallback((...args) => {
12
- if (scheduledRef.current) {
13
- return;
13
+ // for robustness, a fallback in case we don't react to state updates and layoutEffect is not run
14
+ // if we react to state updates, layoutEffect will run before microtasks
15
+ if (!scheduledCallbackRef.current) {
16
+ queueMicrotask(() => {
17
+ if (scheduledCallbackRef.current) {
18
+ scheduledCallbackRef.current();
19
+ }
20
+ });
14
21
  }
15
- scheduledRef.current = true;
16
- const runner = () => {
17
- scheduledRef.current = false;
22
+ scheduledCallbackRef.current = () => {
23
+ scheduledCallbackRef.current = null;
18
24
  callback(...args);
19
25
  };
20
- if (nextFrame) {
21
- if (typeof requestAnimationFrame === 'function') {
22
- requestAnimationFrame(runner);
23
- }
24
- return;
26
+ }, [callback]);
27
+ React.useLayoutEffect(() => {
28
+ if (scheduledCallbackRef.current) {
29
+ scheduledCallbackRef.current();
25
30
  }
26
- if (typeof queueMicrotask === 'function') {
27
- queueMicrotask(runner);
28
- } else {
29
- Promise.resolve().then(runner);
31
+ });
32
+ return {
33
+ schedule,
34
+ cancel: () => {
35
+ if (scheduledCallbackRef.current) {
36
+ scheduledCallbackRef.current = null;
37
+ return true;
38
+ }
39
+ return false;
30
40
  }
31
- }, [callback, nextFrame]);
32
- return schedule;
41
+ };
33
42
  }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.17.0
2
+ * @mui/x-data-grid v8.19.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -257,6 +257,20 @@ export interface GridActionsColDef<R extends GridValidRowModel = any, V = any, F
257
257
  * Function that returns the actions to be shown.
258
258
  * @param {GridRowParams} params The params for each row.
259
259
  * @returns {readonly React.ReactElement<GridActionsCellItemProps>[]} An array of [[GridActionsCell]] elements.
260
+ * @deprecated Use `renderCell` instead
261
+ * @example
262
+ * // Before
263
+ * getActions: (params) => [
264
+ * <GridActionsCellItem icon={...} onClick={...} label="Delete" />,
265
+ * <GridActionsCellItem icon={...} onClick={...} label="Print" showInMenu />,
266
+ * ],
267
+ * // After
268
+ * renderCell: (params) => (
269
+ * <GridActionsCell {...params}>
270
+ * <GridActionsCellItem icon={...} onClick={...} label="Delete" />
271
+ * <GridActionsCellItem icon={...} onClick={...} label="Print" showInMenu />
272
+ * </GridActionsCell>
273
+ * ),
260
274
  */
261
275
  getActions: (params: GridRowParams<R>) => readonly React.ReactElement<GridActionsCellItemProps>[];
262
276
  }
@@ -516,6 +516,11 @@ export interface GridEventLookup extends GridRowEventLookup, GridColumnHeaderEve
516
516
  * @ignore - do not document
517
517
  */
518
518
  sortedRowsSet: {};
519
+ /**
520
+ * Fired when the aggregations are done
521
+ * @ignore - do not document
522
+ */
523
+ aggregationLookupSet: {};
519
524
  /**
520
525
  * Fired when the expansion of a row is changed. Called with a [[GridGroupNode]] object.
521
526
  */
@@ -13,7 +13,7 @@ import type { GridRowReorderState } from "../hooks/features/rowReorder/gridRowRe
13
13
  * Some props are passed on the state to enable grid selectors to select
14
14
  * and react to them.
15
15
  */
16
- export type GridStateProps = Pick<DataGridProcessedProps, 'getRowId' | 'listView' | 'isCellEditable'>;
16
+ export type GridStateProps = Pick<DataGridProcessedProps, 'getRowId' | 'listView' | 'isCellEditable' | 'isRowSelectable'>;
17
17
  /**
18
18
  * The state of Data Grid.
19
19
  */
@@ -1,4 +1,3 @@
1
- import * as React from 'react';
2
1
  import { GridCellMode } from "../gridCell.js";
3
2
  import { GridRowId, GridRowModel, GridTreeNode, GridTreeNodeWithRender, GridValidRowModel } from "../gridRows.js";
4
3
  import type { GridStateColDef } from "../colDef/gridColDef.js";
@@ -58,9 +57,6 @@ export interface GridCellParams<R extends GridValidRowModel = any, V = unknown,
58
57
  */
59
58
  api: GridApiCommunity;
60
59
  }
61
- export interface FocusElement {
62
- focus(): void;
63
- }
64
60
  /**
65
61
  * GridCellParams containing api.
66
62
  */
@@ -69,12 +65,6 @@ export interface GridRenderCellParams<R extends GridValidRowModel = any, V = any
69
65
  * GridApi that let you manipulate the grid.
70
66
  */
71
67
  api: GridApiCommunity;
72
- /**
73
- * A ref allowing to set imperative focus.
74
- * It can be passed to the element that should receive focus.
75
- * @ignore - do not document.
76
- */
77
- focusElementRef?: React.Ref<FocusElement>;
78
68
  }
79
69
  /**
80
70
  * GridEditCellProps containing api.
@@ -79,13 +79,11 @@ export interface DataGridPropsWithComplexDefaultValueBeforeProcessing {
79
79
  */
80
80
  export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = any> {
81
81
  /**
82
- * If `true`, the Data Grid height is dynamic and follows the number of rows in the Data Grid.
82
+ * If `true`, the Data Grid height is dynamic and takes as much space as it needs to display all rows.
83
+ * Use it instead of a flex parent container approach, if:
84
+ * - you don't need to set a minimum or maximum height for the Data Grid
85
+ * - you want to avoid the scrollbar flickering when the content changes
83
86
  * @default false
84
- * @deprecated Use flex parent container instead: https://mui.com/x/react-data-grid/layout/#flex-parent-container
85
- * @example
86
- * <div style={{ display: 'flex', flexDirection: 'column' }}>
87
- * <DataGrid />
88
- * </div>
89
87
  */
90
88
  autoHeight: boolean;
91
89
  /**
@@ -381,6 +379,15 @@ export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = an
381
379
  * @default false
382
380
  */
383
381
  virtualizeColumnsWithAutoRowHeight: boolean;
382
+ /**
383
+ * Sets the tab navigation behavior for the Data Grid.
384
+ * - "none": No Data Grid specific tab navigation. Pressing the tab key will move the focus to the next element in the tab sequence.
385
+ * - "content": Pressing the tab key will move the focus to the next cell in the same row or the first cell in the next row. Shift+Tab will move the focus to the previous cell in the same row or the last cell in the previous row. Tab navigation is not enabled for the header.
386
+ * - "header": Pressing the tab key will move the focus to the next column group, column header or header filter. Shift+Tab will move the focus to the previous column group, column header or header filter. Tab navigation is not enabled for the content.
387
+ * - "all": Combines the "content" and "header" behavior.
388
+ * @default "none"
389
+ */
390
+ tabNavigation: 'none' | 'content' | 'header' | 'all';
384
391
  }
385
392
  /**
386
393
  * The Data Grid props with no default value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "8.17.0",
3
+ "version": "8.19.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The Community plan edition of the MUI X Data Grid components.",
6
6
  "license": "MIT",
@@ -38,12 +38,12 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@babel/runtime": "^7.28.4",
41
- "@mui/utils": "^7.3.3",
41
+ "@mui/utils": "^7.3.5",
42
42
  "clsx": "^2.1.1",
43
43
  "prop-types": "^15.8.1",
44
44
  "use-sync-external-store": "^1.6.0",
45
- "@mui/x-internals": "8.17.0",
46
- "@mui/x-virtualizer": "0.2.7"
45
+ "@mui/x-internals": "8.19.0",
46
+ "@mui/x-virtualizer": "0.2.9"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@emotion/react": "^11.9.0",
@@ -1,14 +1,7 @@
1
1
  import * as React from 'react';
2
2
  export declare function isPrintableKey(event: React.KeyboardEvent<HTMLElement>): boolean;
3
- export declare const GRID_MULTIPLE_SELECTION_KEYS: string[];
4
- export declare const GRID_CELL_EXIT_EDIT_MODE_KEYS: string[];
5
- export declare const GRID_CELL_EDIT_COMMIT_KEYS: string[];
6
- export declare const isMultipleKey: (key: string) => boolean;
7
- export declare const isCellEnterEditModeKeys: (event: React.KeyboardEvent<HTMLElement>) => boolean;
8
- export declare const isCellExitEditModeKeys: (key: string) => boolean;
9
- export declare const isCellEditCommitKeys: (key: string) => boolean;
10
3
  export declare const isNavigationKey: (key: string) => boolean;
11
4
  export declare const isKeyboardEvent: (event: any) => event is React.KeyboardEvent<HTMLElement>;
12
- export declare const isHideMenuKey: (key: React.KeyboardEvent["key"]) => key is "Escape" | "Tab";
5
+ export declare const isHideMenuKey: (key: React.KeyboardEvent["key"]) => key is "Tab" | "Escape";
13
6
  export declare function isPasteShortcut(event: React.KeyboardEvent): boolean;
14
7
  export declare function isCopyShortcut(event: KeyboardEvent): boolean;
@@ -3,9 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isCellExitEditModeKeys = exports.isCellEnterEditModeKeys = exports.isCellEditCommitKeys = exports.GRID_MULTIPLE_SELECTION_KEYS = exports.GRID_CELL_EXIT_EDIT_MODE_KEYS = exports.GRID_CELL_EDIT_COMMIT_KEYS = void 0;
7
6
  exports.isCopyShortcut = isCopyShortcut;
8
- exports.isNavigationKey = exports.isMultipleKey = exports.isKeyboardEvent = exports.isHideMenuKey = void 0;
7
+ exports.isNavigationKey = exports.isKeyboardEvent = exports.isHideMenuKey = void 0;
9
8
  exports.isPasteShortcut = isPasteShortcut;
10
9
  exports.isPrintableKey = isPrintableKey;
11
10
  // Non printable keys have a name, for example "ArrowRight", see the whole list:
@@ -18,17 +17,6 @@ exports.isPrintableKey = isPrintableKey;
18
17
  function isPrintableKey(event) {
19
18
  return event.key.length === 1 && !event.ctrlKey && !event.metaKey;
20
19
  }
21
- const GRID_MULTIPLE_SELECTION_KEYS = exports.GRID_MULTIPLE_SELECTION_KEYS = ['Meta', 'Control', 'Shift'];
22
- const GRID_CELL_EXIT_EDIT_MODE_KEYS = exports.GRID_CELL_EXIT_EDIT_MODE_KEYS = ['Enter', 'Escape', 'Tab'];
23
- const GRID_CELL_EDIT_COMMIT_KEYS = exports.GRID_CELL_EDIT_COMMIT_KEYS = ['Enter', 'Tab'];
24
- const isMultipleKey = key => GRID_MULTIPLE_SELECTION_KEYS.indexOf(key) > -1;
25
- exports.isMultipleKey = isMultipleKey;
26
- const isCellEnterEditModeKeys = event => isPrintableKey(event) || event.key === 'Enter' || event.key === 'Backspace' || event.key === 'Delete';
27
- exports.isCellEnterEditModeKeys = isCellEnterEditModeKeys;
28
- const isCellExitEditModeKeys = key => GRID_CELL_EXIT_EDIT_MODE_KEYS.indexOf(key) > -1;
29
- exports.isCellExitEditModeKeys = isCellExitEditModeKeys;
30
- const isCellEditCommitKeys = key => GRID_CELL_EDIT_COMMIT_KEYS.indexOf(key) > -1;
31
- exports.isCellEditCommitKeys = isCellEditCommitKeys;
32
20
  const isNavigationKey = key => key.indexOf('Arrow') === 0 || key.indexOf('Page') === 0 || key === ' ' || key === 'Home' || key === 'End';
33
21
  exports.isNavigationKey = isNavigationKey;
34
22
  const isKeyboardEvent = event => !!event.key;