@mui/x-data-grid 5.15.1 → 5.15.2

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 (43) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/DataGrid/DataGrid.js +1 -1
  3. package/hooks/features/editRows/useGridCellEditing.new.js +15 -7
  4. package/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  5. package/hooks/features/filter/gridFilterState.d.ts +12 -1
  6. package/hooks/features/filter/gridFilterUtils.d.ts +8 -5
  7. package/hooks/features/filter/gridFilterUtils.js +74 -43
  8. package/hooks/features/filter/useGridFilter.js +16 -3
  9. package/hooks/features/focus/useGridFocus.js +11 -6
  10. package/hooks/features/rows/useGridRows.js +5 -2
  11. package/hooks/features/statePersistence/gridStatePersistenceInterface.d.ts +3 -0
  12. package/index.js +1 -1
  13. package/internals/index.d.ts +1 -0
  14. package/internals/index.js +1 -0
  15. package/legacy/DataGrid/DataGrid.js +1 -1
  16. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +16 -8
  17. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  18. package/legacy/hooks/features/filter/gridFilterUtils.js +84 -55
  19. package/legacy/hooks/features/filter/useGridFilter.js +16 -3
  20. package/legacy/hooks/features/focus/useGridFocus.js +11 -6
  21. package/legacy/hooks/features/rows/useGridRows.js +5 -2
  22. package/legacy/index.js +1 -1
  23. package/legacy/internals/index.js +1 -0
  24. package/models/props/DataGridProps.d.ts +3 -3
  25. package/modern/DataGrid/DataGrid.js +1 -1
  26. package/modern/hooks/features/editRows/useGridCellEditing.new.js +15 -7
  27. package/modern/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  28. package/modern/hooks/features/filter/gridFilterUtils.js +73 -42
  29. package/modern/hooks/features/filter/useGridFilter.js +16 -3
  30. package/modern/hooks/features/focus/useGridFocus.js +11 -6
  31. package/modern/hooks/features/rows/useGridRows.js +5 -2
  32. package/modern/index.js +1 -1
  33. package/modern/internals/index.js +1 -0
  34. package/node/DataGrid/DataGrid.js +1 -1
  35. package/node/hooks/features/editRows/useGridCellEditing.new.js +15 -7
  36. package/node/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  37. package/node/hooks/features/filter/gridFilterUtils.js +81 -47
  38. package/node/hooks/features/filter/useGridFilter.js +15 -2
  39. package/node/hooks/features/focus/useGridFocus.js +11 -6
  40. package/node/hooks/features/rows/useGridRows.js +5 -2
  41. package/node/index.js +1 -1
  42. package/node/internals/index.js +8 -0
  43. package/package.json +1 -1
@@ -12,7 +12,7 @@ import { useFirstRender } from '../../utils/useFirstRender';
12
12
  import { gridRowIdsSelector } from '../rows';
13
13
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
14
14
  import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from '../../core/strategyProcessing';
15
- import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem } from './gridFilterUtils';
15
+ import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem, passFilterLogic } from './gridFilterUtils';
16
16
  import { isDeepEqual } from '../../../utils/utils';
17
17
  import { jsx as _jsx } from "react/jsx-runtime";
18
18
  export const filterStateInitializer = (state, props, apiRef) => {
@@ -45,7 +45,8 @@ export const useGridFilter = (apiRef, props) => {
45
45
  const filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
46
46
  const isRowMatchingFilters = props.filterMode === GridFeatureModeConstant.client ? buildAggregatedFilterApplier(filterModel, apiRef) : null;
47
47
  const filteringResult = apiRef.current.unstable_applyStrategyProcessor('filtering', {
48
- isRowMatchingFilters
48
+ isRowMatchingFilters,
49
+ filterModel: filterModel ?? getDefaultGridFilterModel()
49
50
  });
50
51
  return _extends({}, state, {
51
52
  filter: _extends({}, state.filter, filteringResult)
@@ -249,7 +250,19 @@ export const useGridFilter = (apiRef, props) => {
249
250
 
250
251
  for (let i = 0; i < rowIds.length; i += 1) {
251
252
  const rowId = rowIds[i];
252
- filteredRowsLookup[rowId] = params.isRowMatchingFilters(rowId);
253
+ let isRowPassing;
254
+
255
+ if (typeof rowId === 'string' && rowId.startsWith('auto-generated-group-footer')) {
256
+ isRowPassing = true;
257
+ } else {
258
+ const {
259
+ passingFilterItems,
260
+ passingQuickFilterValues
261
+ } = params.isRowMatchingFilters(rowId);
262
+ isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel);
263
+ }
264
+
265
+ filteredRowsLookup[rowId] = isRowPassing;
253
266
  }
254
267
 
255
268
  return {
@@ -60,6 +60,12 @@ export const useGridFocus = (apiRef, props) => {
60
60
  return;
61
61
  }
62
62
 
63
+ if (focusedCell) {
64
+ // There's a focused cell but another cell was clicked
65
+ // Publishes an event to notify that the focus was lost
66
+ apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field));
67
+ }
68
+
63
69
  apiRef.current.publishEvent('cellFocusIn', apiRef.current.getCellParams(id, field));
64
70
  }, [apiRef, logger]);
65
71
  const setColumnHeaderFocus = React.useCallback((field, event = {}) => {
@@ -191,11 +197,7 @@ export const useGridFocus = (apiRef, props) => {
191
197
 
192
198
  if (!apiRef.current.getRow(focusedCell.id)) {
193
199
  return;
194
- } // There's a focused cell but another cell was clicked
195
- // Publishes an event to notify that the focus was lost
196
-
197
-
198
- apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
200
+ }
199
201
 
200
202
  if (cellParams) {
201
203
  apiRef.current.setCellFocus(cellParams.id, cellParams.field);
@@ -206,7 +208,10 @@ export const useGridFocus = (apiRef, props) => {
206
208
  columnHeader: null
207
209
  }
208
210
  }));
209
- apiRef.current.forceUpdate();
211
+ apiRef.current.forceUpdate(); // There's a focused cell but another element (not a cell) was clicked
212
+ // Publishes an event to notify that the focus was lost
213
+
214
+ apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
210
215
  }
211
216
  }, [apiRef]);
212
217
  const handleCellModeChange = React.useCallback(params => {
@@ -26,8 +26,11 @@ export const rowsStateInitializer = (state, props, apiRef) => {
26
26
  };
27
27
  export const useGridRows = (apiRef, props) => {
28
28
  if (process.env.NODE_ENV !== 'production') {
29
- // Freeze rows for immutability
30
- Object.freeze(props.rows);
29
+ try {
30
+ // Freeze the `rows` prop so developers have a fast failure if they try to use Array.prototype.push().
31
+ Object.freeze(props.rows);
32
+ } catch (error) {// Sometimes, it's impossible to freeze, so we give up on it.
33
+ }
31
34
  }
32
35
 
33
36
  const logger = useGridLogger(apiRef, 'useGridRows');
package/modern/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.15.1
1
+ /** @license MUI v5.15.2
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -15,6 +15,7 @@ export { useGridDensity, densityStateInitializer } from '../hooks/features/densi
15
15
  export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
16
16
  export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
17
17
  export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
18
+ export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
18
19
  export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
19
20
  export { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
20
21
  export { useGridPagination, paginationStateInitializer } from '../hooks/features/pagination/useGridPagination';
@@ -668,7 +668,7 @@ DataGridRaw.propTypes = {
668
668
  * @param {GridState} state The new state.
669
669
  * @param {MuiEvent<{}>} event The event object.
670
670
  * @param {GridCallbackDetails} details Additional details for this callback.
671
- * @internal
671
+ * @ignore - do not document.
672
672
  */
673
673
  onStateChange: _propTypes.default.func,
674
674
 
@@ -42,6 +42,7 @@ const missingOnProcessRowUpdateErrorWarning = (0, _warning.buildWarning)(['MUI:
42
42
 
43
43
  const useGridCellEditing = (apiRef, props) => {
44
44
  const [cellModesModel, setCellModesModel] = React.useState({});
45
+ const cellModesModelRef = React.useRef(cellModesModel);
45
46
  const prevCellModesModel = React.useRef({});
46
47
  const {
47
48
  processRowUpdate,
@@ -88,6 +89,10 @@ const useGridCellEditing = (apiRef, props) => {
88
89
  return;
89
90
  }
90
91
 
92
+ if (apiRef.current.getCellMode(params.id, params.field) === _gridEditRowModel.GridCellModes.View) {
93
+ return;
94
+ }
95
+
91
96
  const newParams = (0, _extends2.default)({}, params, {
92
97
  reason: _gridEditCellParams.GridCellEditStopReasons.cellFocusOut
93
98
  });
@@ -217,18 +222,21 @@ const useGridCellEditing = (apiRef, props) => {
217
222
  }
218
223
 
219
224
  setCellModesModel(newModel);
225
+ cellModesModelRef.current = newModel;
220
226
  apiRef.current.publishEvent('cellModesModelChange', newModel);
221
227
  }, [apiRef, onCellModesModelChange, props.cellModesModel, signature]);
222
228
  const updateFieldInCellModesModel = React.useCallback((id, field, newProps) => {
223
- const newModel = (0, _extends2.default)({}, cellModesModel);
229
+ // We use the ref because it always contain the up-to-date value, different from the state
230
+ // that needs a rerender to reflect the new value
231
+ const newModel = (0, _extends2.default)({}, cellModesModelRef.current);
224
232
 
225
233
  if (newProps !== null) {
226
234
  newModel[id] = (0, _extends2.default)({}, newModel[id], {
227
235
  [field]: (0, _extends2.default)({}, newProps)
228
236
  });
229
237
  } else {
230
- const _cellModesModel$id = cellModesModel[id],
231
- otherFields = (0, _objectWithoutPropertiesLoose2.default)(_cellModesModel$id, [field].map(_toPropertyKey2.default)); // Ensure that we have a new object, not a reference
238
+ const _newModel$id = newModel[id],
239
+ otherFields = (0, _objectWithoutPropertiesLoose2.default)(_newModel$id, [field].map(_toPropertyKey2.default)); // Ensure that we have a new object, not a reference
232
240
 
233
241
  newModel[id] = otherFields;
234
242
 
@@ -238,7 +246,7 @@ const useGridCellEditing = (apiRef, props) => {
238
246
  }
239
247
 
240
248
  updateCellModesModel(newModel);
241
- }, [cellModesModel, updateCellModesModel]);
249
+ }, [updateCellModesModel]);
242
250
  const updateOrDeleteFieldState = React.useCallback((id, field, newProps) => {
243
251
  apiRef.current.setState(state => {
244
252
  const newEditingState = (0, _extends2.default)({}, state.editRows);
@@ -309,12 +317,12 @@ const useGridCellEditing = (apiRef, props) => {
309
317
  apiRef.current.unstable_runPendingEditCellValueMutation(id, field);
310
318
 
311
319
  const finishCellEditMode = () => {
320
+ updateOrDeleteFieldState(id, field, null);
321
+ updateFieldInCellModesModel(id, field, null);
322
+
312
323
  if (cellToFocusAfter !== 'none') {
313
324
  apiRef.current.unstable_moveFocusToRelativeCell(id, field, cellToFocusAfter);
314
325
  }
315
-
316
- updateOrDeleteFieldState(id, field, null);
317
- updateFieldInCellModesModel(id, field, null);
318
326
  };
319
327
 
320
328
  if (ignoreModifications) {
@@ -44,6 +44,7 @@ const missingOnProcessRowUpdateErrorWarning = (0, _warning.buildWarning)(['MUI:
44
44
 
45
45
  const useGridRowEditing = (apiRef, props) => {
46
46
  const [rowModesModel, setRowModesModel] = React.useState({});
47
+ const rowModesModelRef = React.useRef(rowModesModel);
47
48
  const prevRowModesModel = React.useRef({});
48
49
  const focusTimeout = React.useRef(null);
49
50
  const nextFocusedCell = React.useRef(null);
@@ -116,6 +117,11 @@ const useGridRowEditing = (apiRef, props) => {
116
117
  // The row might have been deleted during the click
117
118
  if (!apiRef.current.getRow(params.id)) {
118
119
  return;
120
+ } // The row may already changed its mode
121
+
122
+
123
+ if (apiRef.current.getRowMode(params.id) === _gridEditRowModel.GridRowModes.View) {
124
+ return;
119
125
  }
120
126
 
121
127
  const rowParams = apiRef.current.getRowParams(params.id);
@@ -280,10 +286,11 @@ const useGridRowEditing = (apiRef, props) => {
280
286
  }
281
287
 
282
288
  setRowModesModel(newModel);
289
+ rowModesModelRef.current = newModel;
283
290
  apiRef.current.publishEvent('rowModesModelChange', newModel);
284
291
  }, [apiRef, onRowModesModelChange, props.rowModesModel, signature]);
285
292
  const updateRowInRowModesModel = React.useCallback((id, newProps) => {
286
- const newModel = (0, _extends2.default)({}, rowModesModel);
293
+ const newModel = (0, _extends2.default)({}, rowModesModelRef.current);
287
294
 
288
295
  if (newProps !== null) {
289
296
  newModel[id] = (0, _extends2.default)({}, newProps);
@@ -292,7 +299,7 @@ const useGridRowEditing = (apiRef, props) => {
292
299
  }
293
300
 
294
301
  updateRowModesModel(newModel);
295
- }, [rowModesModel, updateRowModesModel]);
302
+ }, [updateRowModesModel]);
296
303
  const updateOrDeleteRowState = React.useCallback((id, newProps) => {
297
304
  apiRef.current.setState(state => {
298
305
  const newEditingState = (0, _extends2.default)({}, state.editRows);
@@ -5,18 +5,18 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.sanitizeFilterModel = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedQuickFilterApplier = exports.buildAggregatedFilterItemsApplier = exports.buildAggregatedFilterApplier = void 0;
8
+ exports.sanitizeFilterModel = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedQuickFilterApplier = exports.buildAggregatedFilterItemsApplier = exports.buildAggregatedFilterApplier = void 0;
9
9
 
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
 
12
12
  var _models = require("../../../models");
13
13
 
14
+ var _gridFilterState = require("./gridFilterState");
15
+
14
16
  var _warning = require("../../../utils/warning");
15
17
 
16
18
  var _columns = require("../columns");
17
19
 
18
- var _gridRowsSelector = require("../rows/gridRowsSelector");
19
-
20
20
  /**
21
21
  * Adds default values to the optional fields of a filter items.
22
22
  * @param {GridFilterItem} item The raw filter item.
@@ -100,10 +100,8 @@ exports.mergeStateWithFilterModel = mergeStateWithFilterModel;
100
100
 
101
101
  const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
102
102
  const {
103
- items,
104
- linkOperator = _models.GridLinkOperator.And
103
+ items
105
104
  } = filterModel;
106
- const tree = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef);
107
105
 
108
106
  const getFilterCallbackFromItem = filterItem => {
109
107
  if (!filterItem.columnField || !filterItem.operatorValue) {
@@ -166,18 +164,12 @@ const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
166
164
  }
167
165
 
168
166
  return (rowId, shouldApplyFilter) => {
169
- if (tree[rowId].position === 'footer') {
170
- return true;
171
- }
172
-
173
- const filteredAppliers = shouldApplyFilter ? appliers.filter(applier => shouldApplyFilter(applier.item.columnField)) : appliers; // Return `false` as soon as we have a failing filter
174
-
175
- if (linkOperator === _models.GridLinkOperator.And) {
176
- return filteredAppliers.every(applier => applier.fn(rowId));
177
- } // Return `true` as soon as we have a passing filter
178
-
179
-
180
- return filteredAppliers.some(applier => applier.fn(rowId));
167
+ const resultPerItemId = {};
168
+ const filteredAppliers = shouldApplyFilter ? appliers.filter(applier => shouldApplyFilter(applier.item.columnField)) : appliers;
169
+ filteredAppliers.forEach(applier => {
170
+ resultPerItemId[applier.item.id] = applier.fn(rowId);
171
+ });
172
+ return resultPerItemId;
181
173
  };
182
174
  };
183
175
  /**
@@ -192,8 +184,7 @@ exports.buildAggregatedFilterItemsApplier = buildAggregatedFilterItemsApplier;
192
184
 
193
185
  const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
194
186
  const {
195
- quickFilterValues = [],
196
- quickFilterLogicOperator = _models.GridLinkOperator.And
187
+ quickFilterValues = []
197
188
  } = filterModel;
198
189
 
199
190
  if (quickFilterValues.length === 0) {
@@ -214,6 +205,11 @@ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
214
205
  }); // If some value does not have an applier we ignore them
215
206
 
216
207
  const sanitizedQuickFilterValues = quickFilterValues.filter((value, index) => Object.keys(appliersPerColumnField).some(field => appliersPerColumnField[field][index] != null));
208
+
209
+ if (sanitizedQuickFilterValues.length === 0) {
210
+ return null;
211
+ }
212
+
217
213
  return (rowId, shouldApplyFilter) => {
218
214
  const usedCellParams = {};
219
215
  const columnsFieldsToFilter = [];
@@ -222,10 +218,10 @@ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
222
218
  usedCellParams[columnField] = apiRef.current.getCellParams(rowId, columnField);
223
219
  columnsFieldsToFilter.push(columnField);
224
220
  }
225
- }); // Return `false` as soon as we have a quick filter value that does not match any column
226
-
227
- if (quickFilterLogicOperator === _models.GridLinkOperator.And) {
228
- return sanitizedQuickFilterValues.every((value, index) => columnsFieldsToFilter.some(field => {
221
+ });
222
+ const quickFilterValueResult = {};
223
+ sanitizedQuickFilterValues.forEach((value, index) => {
224
+ const isPassing = columnsFieldsToFilter.some(field => {
229
225
  var _appliersPerColumnFie, _appliersPerColumnFie2;
230
226
 
231
227
  if (appliersPerColumnField[field][index] == null) {
@@ -233,19 +229,10 @@ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
233
229
  }
234
230
 
235
231
  return (_appliersPerColumnFie = (_appliersPerColumnFie2 = appliersPerColumnField[field])[index]) == null ? void 0 : _appliersPerColumnFie.call(_appliersPerColumnFie2, usedCellParams[field]);
236
- }));
237
- } // Return `true` as soon as we have have a quick filter value that match any column
238
-
239
-
240
- return sanitizedQuickFilterValues.some((value, index) => columnsFieldsToFilter.some(field => {
241
- var _appliersPerColumnFie3, _appliersPerColumnFie4;
242
-
243
- if (appliersPerColumnField[field][index] == null) {
244
- return false;
245
- }
246
-
247
- return (_appliersPerColumnFie3 = (_appliersPerColumnFie4 = appliersPerColumnField[field])[index]) == null ? void 0 : _appliersPerColumnFie3.call(_appliersPerColumnFie4, usedCellParams[field]);
248
- }));
232
+ });
233
+ quickFilterValueResult[value] = isPassing;
234
+ });
235
+ return quickFilterValueResult;
249
236
  };
250
237
  };
251
238
 
@@ -254,20 +241,67 @@ exports.buildAggregatedQuickFilterApplier = buildAggregatedQuickFilterApplier;
254
241
  const buildAggregatedFilterApplier = (filterModel, apiRef) => {
255
242
  const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef);
256
243
  const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
244
+ return (rowId, shouldApplyFilter) => ({
245
+ passingFilterItems: isRowMatchingFilterItems && isRowMatchingFilterItems(rowId, shouldApplyFilter),
246
+ passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
247
+ });
248
+ };
257
249
 
258
- if (isRowMatchingFilterItems == null && isRowMatchingQuickFilter == null) {
259
- return null;
260
- }
250
+ exports.buildAggregatedFilterApplier = buildAggregatedFilterApplier;
261
251
 
262
- if (isRowMatchingFilterItems == null) {
263
- return isRowMatchingQuickFilter;
264
- }
252
+ const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel) => {
253
+ var _filterModel$quickFil, _filterModel$linkOper;
265
254
 
266
- if (isRowMatchingQuickFilter == null) {
267
- return isRowMatchingFilterItems;
255
+ const cleanedAllFilterItemResults = allFilterItemResults.filter(result => result != null);
256
+ const cleanedAllQuickFilterResults = allQuickFilterResults.filter(result => result != null); // Defaultize operators
257
+
258
+ const quickFilterLogicOperator = (_filterModel$quickFil = filterModel.quickFilterLogicOperator) != null ? _filterModel$quickFil : (0, _gridFilterState.getDefaultGridFilterModel)().quickFilterLogicOperator;
259
+ const linkOperator = (_filterModel$linkOper = filterModel.linkOperator) != null ? _filterModel$linkOper : (0, _gridFilterState.getDefaultGridFilterModel)().linkOperator; // get result for filter items model
260
+
261
+ if (cleanedAllFilterItemResults.length > 0) {
262
+ // Return true if the item pass with one of the rows
263
+ const filterItemPredicate = item => {
264
+ return cleanedAllFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
265
+ };
266
+
267
+ if (linkOperator === _models.GridLinkOperator.And) {
268
+ const passesAllFilters = filterModel.items.every(filterItemPredicate);
269
+
270
+ if (!passesAllFilters) {
271
+ return false;
272
+ }
273
+ } else {
274
+ const passesSomeFilters = filterModel.items.some(filterItemPredicate);
275
+
276
+ if (!passesSomeFilters) {
277
+ return false;
278
+ }
279
+ }
280
+ } // get result for quick filter model
281
+
282
+
283
+ if (cleanedAllQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
284
+ // Return true if the item pass with one of the rows
285
+ const quickFilterValuePredicate = value => {
286
+ return cleanedAllQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
287
+ };
288
+
289
+ if (quickFilterLogicOperator === _models.GridLinkOperator.And) {
290
+ const passesAllQuickFilterValues = filterModel.quickFilterValues.every(quickFilterValuePredicate);
291
+
292
+ if (!passesAllQuickFilterValues) {
293
+ return false;
294
+ }
295
+ } else {
296
+ const passesSomeQuickFilterValues = filterModel.quickFilterValues.some(quickFilterValuePredicate);
297
+
298
+ if (!passesSomeQuickFilterValues) {
299
+ return false;
300
+ }
301
+ }
268
302
  }
269
303
 
270
- return (rowId, shouldApplyFilter) => isRowMatchingFilterItems(rowId, shouldApplyFilter) && isRowMatchingQuickFilter(rowId, shouldApplyFilter);
304
+ return true;
271
305
  };
272
306
 
273
- exports.buildAggregatedFilterApplier = buildAggregatedFilterApplier;
307
+ exports.passFilterLogic = passFilterLogic;
@@ -82,7 +82,8 @@ const useGridFilter = (apiRef, props) => {
82
82
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(state, apiRef.current.instanceId);
83
83
  const isRowMatchingFilters = props.filterMode === _gridFeatureMode.GridFeatureModeConstant.client ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(filterModel, apiRef) : null;
84
84
  const filteringResult = apiRef.current.unstable_applyStrategyProcessor('filtering', {
85
- isRowMatchingFilters
85
+ isRowMatchingFilters,
86
+ filterModel: filterModel != null ? filterModel : (0, _gridFilterState.getDefaultGridFilterModel)()
86
87
  });
87
88
  return (0, _extends2.default)({}, state, {
88
89
  filter: (0, _extends2.default)({}, state.filter, filteringResult)
@@ -294,7 +295,19 @@ const useGridFilter = (apiRef, props) => {
294
295
 
295
296
  for (let i = 0; i < rowIds.length; i += 1) {
296
297
  const rowId = rowIds[i];
297
- filteredRowsLookup[rowId] = params.isRowMatchingFilters(rowId);
298
+ let isRowPassing;
299
+
300
+ if (typeof rowId === 'string' && rowId.startsWith('auto-generated-group-footer')) {
301
+ isRowPassing = true;
302
+ } else {
303
+ const {
304
+ passingFilterItems,
305
+ passingQuickFilterValues
306
+ } = params.isRowMatchingFilters(rowId);
307
+ isRowPassing = (0, _gridFilterUtils.passFilterLogic)([passingFilterItems], [passingQuickFilterValues], params.filterModel);
308
+ }
309
+
310
+ filteredRowsLookup[rowId] = isRowPassing;
298
311
  }
299
312
 
300
313
  return {
@@ -87,6 +87,12 @@ const useGridFocus = (apiRef, props) => {
87
87
  return;
88
88
  }
89
89
 
90
+ if (focusedCell) {
91
+ // There's a focused cell but another cell was clicked
92
+ // Publishes an event to notify that the focus was lost
93
+ apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field));
94
+ }
95
+
90
96
  apiRef.current.publishEvent('cellFocusIn', apiRef.current.getCellParams(id, field));
91
97
  }, [apiRef, logger]);
92
98
  const setColumnHeaderFocus = React.useCallback((field, event = {}) => {
@@ -218,11 +224,7 @@ const useGridFocus = (apiRef, props) => {
218
224
 
219
225
  if (!apiRef.current.getRow(focusedCell.id)) {
220
226
  return;
221
- } // There's a focused cell but another cell was clicked
222
- // Publishes an event to notify that the focus was lost
223
-
224
-
225
- apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
227
+ }
226
228
 
227
229
  if (cellParams) {
228
230
  apiRef.current.setCellFocus(cellParams.id, cellParams.field);
@@ -233,7 +235,10 @@ const useGridFocus = (apiRef, props) => {
233
235
  columnHeader: null
234
236
  }
235
237
  }));
236
- apiRef.current.forceUpdate();
238
+ apiRef.current.forceUpdate(); // There's a focused cell but another element (not a cell) was clicked
239
+ // Publishes an event to notify that the focus was lost
240
+
241
+ apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
237
242
  }
238
243
  }, [apiRef]);
239
244
  const handleCellModeChange = React.useCallback(params => {
@@ -53,8 +53,11 @@ exports.rowsStateInitializer = rowsStateInitializer;
53
53
 
54
54
  const useGridRows = (apiRef, props) => {
55
55
  if (process.env.NODE_ENV !== 'production') {
56
- // Freeze rows for immutability
57
- Object.freeze(props.rows);
56
+ try {
57
+ // Freeze the `rows` prop so developers have a fast failure if they try to use Array.prototype.push().
58
+ Object.freeze(props.rows);
59
+ } catch (error) {// Sometimes, it's impossible to freeze, so we give up on it.
60
+ }
58
61
  }
59
62
 
60
63
  const logger = (0, _useGridLogger.useGridLogger)(apiRef, 'useGridRows');
package/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.15.1
1
+ /** @license MUI v5.15.2
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -177,6 +177,12 @@ Object.defineProperty(exports, "paginationStateInitializer", {
177
177
  return _useGridPagination.paginationStateInitializer;
178
178
  }
179
179
  });
180
+ Object.defineProperty(exports, "passFilterLogic", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _gridFilterUtils.passFilterLogic;
184
+ }
185
+ });
180
186
  Object.defineProperty(exports, "preferencePanelStateInitializer", {
181
187
  enumerable: true,
182
188
  get: function () {
@@ -440,6 +446,8 @@ var _useGridPrintExport = require("../hooks/features/export/useGridPrintExport")
440
446
 
441
447
  var _useGridFilter = require("../hooks/features/filter/useGridFilter");
442
448
 
449
+ var _gridFilterUtils = require("../hooks/features/filter/gridFilterUtils");
450
+
443
451
  var _useGridFocus = require("../hooks/features/focus/useGridFocus");
444
452
 
445
453
  var _useGridKeyboardNavigation = require("../hooks/features/keyboardNavigation/useGridKeyboardNavigation");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "5.15.1",
3
+ "version": "5.15.2",
4
4
  "description": "The community edition of the data grid component (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",