@mui/x-data-grid 6.16.3 → 6.18.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 (65) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/DataGrid/DataGrid.js +13 -0
  3. package/DataGrid/useDataGridProps.js +3 -1
  4. package/colDef/gridStringOperators.js +1 -2
  5. package/components/containers/GridRootStyles.js +2 -1
  6. package/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  7. package/hooks/core/useGridInitialization.d.ts +1 -1
  8. package/hooks/core/useGridInitialization.js +3 -0
  9. package/hooks/features/filter/gridFilterUtils.d.ts +8 -25
  10. package/hooks/features/filter/gridFilterUtils.js +55 -24
  11. package/hooks/features/filter/useGridFilter.js +2 -2
  12. package/hooks/features/rows/useGridRowsMeta.d.ts +1 -1
  13. package/hooks/features/rows/useGridRowsMeta.js +1 -1
  14. package/hooks/features/virtualization/useGridVirtualScroller.js +9 -1
  15. package/index.js +1 -1
  16. package/legacy/DataGrid/DataGrid.js +13 -0
  17. package/legacy/DataGrid/useDataGridProps.js +3 -1
  18. package/legacy/colDef/gridStringOperators.js +1 -2
  19. package/legacy/components/containers/GridRootStyles.js +2 -1
  20. package/legacy/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  21. package/legacy/hooks/core/useGridInitialization.js +3 -0
  22. package/legacy/hooks/features/filter/gridFilterUtils.js +40 -17
  23. package/legacy/hooks/features/filter/useGridFilter.js +2 -2
  24. package/legacy/hooks/features/rows/useGridRowsMeta.js +2 -2
  25. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +9 -1
  26. package/legacy/index.js +1 -1
  27. package/legacy/locales/ptBR.js +13 -14
  28. package/legacy/utils/utils.js +1 -1
  29. package/locales/ptBR.js +13 -14
  30. package/models/api/gridApiCommon.d.ts +3 -2
  31. package/models/api/gridApiCommunity.d.ts +2 -1
  32. package/models/api/gridCoreApi.d.ts +7 -1
  33. package/models/api/gridEditingApi.d.ts +2 -2
  34. package/models/api/gridFilterApi.d.ts +1 -1
  35. package/models/api/gridLocaleTextApi.d.ts +3 -2
  36. package/models/props/DataGridProps.d.ts +13 -0
  37. package/modern/DataGrid/DataGrid.js +13 -0
  38. package/modern/DataGrid/useDataGridProps.js +3 -1
  39. package/modern/colDef/gridStringOperators.js +1 -2
  40. package/modern/components/containers/GridRootStyles.js +2 -1
  41. package/modern/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  42. package/modern/hooks/core/useGridInitialization.js +3 -0
  43. package/modern/hooks/features/filter/gridFilterUtils.js +55 -24
  44. package/modern/hooks/features/filter/useGridFilter.js +2 -2
  45. package/modern/hooks/features/rows/useGridRowsMeta.js +1 -1
  46. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +9 -1
  47. package/modern/index.js +1 -1
  48. package/modern/locales/ptBR.js +13 -14
  49. package/modern/utils/utils.js +1 -1
  50. package/node/DataGrid/DataGrid.js +13 -0
  51. package/node/DataGrid/useDataGridProps.js +3 -1
  52. package/node/colDef/gridStringOperators.js +1 -2
  53. package/node/components/containers/GridRootStyles.js +2 -1
  54. package/node/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  55. package/node/hooks/core/useGridInitialization.js +3 -0
  56. package/node/hooks/features/filter/gridFilterUtils.js +56 -27
  57. package/node/hooks/features/filter/useGridFilter.js +2 -2
  58. package/node/hooks/features/rows/useGridRowsMeta.js +1 -1
  59. package/node/hooks/features/virtualization/useGridVirtualScroller.js +9 -1
  60. package/node/index.js +1 -1
  61. package/node/locales/ptBR.js +13 -14
  62. package/node/utils/utils.js +1 -1
  63. package/package.json +2 -2
  64. package/utils/utils.d.ts +1 -1
  65. package/utils/utils.js +1 -1
@@ -17,7 +17,7 @@ try {
17
17
  /**
18
18
  * Adds default values to the optional fields of a filter items.
19
19
  * @param {GridFilterItem} item The raw filter item.
20
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
20
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
21
21
  * @return {GridFilterItem} The clean filter item with an uniq ID and an always-defined operator.
22
22
  * TODO: Make the typing reflect the different between GridFilterInputItem and GridFilterItem.
23
23
  */
@@ -69,6 +69,12 @@ export const sanitizeFilterModel = (model, disableMultipleColumnsFiltering, apiR
69
69
  export const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFiltering, apiRef) => filteringState => _extends({}, filteringState, {
70
70
  filterModel: sanitizeFilterModel(filterModel, disableMultipleColumnsFiltering, apiRef)
71
71
  });
72
+ const removeDiacritics = value => {
73
+ if (typeof value === 'string') {
74
+ return value.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
75
+ }
76
+ return value;
77
+ };
72
78
  const getFilterCallbackFromItem = (filterItem, apiRef) => {
73
79
  if (!filterItem.field || !filterItem.operator) {
74
80
  return null;
@@ -84,6 +90,12 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
84
90
  } else {
85
91
  parsedValue = filterItem.value;
86
92
  }
93
+ const {
94
+ ignoreDiacritics
95
+ } = apiRef.current.rootProps;
96
+ if (ignoreDiacritics) {
97
+ parsedValue = removeDiacritics(parsedValue);
98
+ }
87
99
  const newFilterItem = _extends({}, filterItem, {
88
100
  value: parsedValue
89
101
  });
@@ -106,7 +118,10 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
106
118
  v7: true,
107
119
  item: newFilterItem,
108
120
  fn: row => {
109
- const value = apiRef.current.getRowValue(row, column);
121
+ let value = apiRef.current.getRowValue(row, column);
122
+ if (ignoreDiacritics) {
123
+ value = removeDiacritics(value);
124
+ }
110
125
  return applyFilterOnRow(value, row, column, apiRef);
111
126
  }
112
127
  };
@@ -121,6 +136,9 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
121
136
  fn: rowId => {
122
137
  const params = apiRef.current.getCellParams(rowId, newFilterItem.field);
123
138
  GLOBAL_API_REF.current = apiRef;
139
+ if (ignoreDiacritics) {
140
+ params.value = removeDiacritics(params.value);
141
+ }
124
142
  const result = applyFilterOnRow(params);
125
143
  GLOBAL_API_REF.current = null;
126
144
  return result;
@@ -131,12 +149,11 @@ let filterItemsApplierId = 1;
131
149
 
132
150
  /**
133
151
  * Generates a method to easily check if a row is matching the current filter model.
134
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
135
152
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
136
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
153
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
137
154
  * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
138
155
  */
139
- export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disableEval) => {
156
+ const buildAggregatedFilterItemsApplier = (filterModel, apiRef, disableEval) => {
140
157
  const {
141
158
  items
142
159
  } = filterModel;
@@ -151,7 +168,7 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
151
168
  for (let i = 0; i < appliers.length; i += 1) {
152
169
  const applier = appliers[i];
153
170
  if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
154
- resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
171
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(apiRef.current.getRowId(row));
155
172
  }
156
173
  }
157
174
  return resultPerItemId;
@@ -167,14 +184,14 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
167
184
  ${appliers.map((applier, i) => `${JSON.stringify(String(applier.item.id))}:
168
185
  !shouldApply${i} ?
169
186
  false :
170
- ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(${getRowId ? 'getRowId(row)' : 'row.id'})`},
187
+ ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(getRowId(row))`},
171
188
  `).join('\n')}};
172
189
 
173
190
  return result$$;
174
191
  })`;
175
192
  const filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
176
193
  const filterItem = (row, shouldApplyItem) => {
177
- return filterItemCore(getRowId, appliers, row, shouldApplyItem);
194
+ return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
178
195
  };
179
196
  filterItemsApplierId += 1;
180
197
  return filterItem;
@@ -182,12 +199,11 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
182
199
 
183
200
  /**
184
201
  * Generates a method to easily check if a row is matching the current quick filter.
185
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
186
202
  * @param {any[]} filterModel The model with which we want to filter the rows.
187
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
203
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
188
204
  * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
189
205
  */
190
- export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
206
+ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
191
207
  const quickFilterValues = filterModel.quickFilterValues?.filter(Boolean) ?? [];
192
208
  if (quickFilterValues.length === 0) {
193
209
  return null;
@@ -195,6 +211,9 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
195
211
  const quickFilterExcludeHiddenColumns = filterModel.quickFilterExcludeHiddenColumns ?? false;
196
212
  const columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
197
213
  const appliersPerField = [];
214
+ const {
215
+ ignoreDiacritics
216
+ } = apiRef.current.rootProps;
198
217
  columnFields.forEach(field => {
199
218
  const column = apiRef.current.getColumn(field);
200
219
  const getApplyQuickFilterFn = column?.getApplyQuickFilterFn;
@@ -204,18 +223,24 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
204
223
  if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
205
224
  appliersPerField.push({
206
225
  column,
207
- appliers: quickFilterValues.map(value => ({
208
- v7: true,
209
- fn: getApplyQuickFilterFnV7(value, column, apiRef)
210
- }))
226
+ appliers: quickFilterValues.map(quickFilterValue => {
227
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
228
+ return {
229
+ v7: true,
230
+ fn: getApplyQuickFilterFnV7(value, column, apiRef)
231
+ };
232
+ })
211
233
  });
212
234
  } else if (getApplyQuickFilterFn) {
213
235
  appliersPerField.push({
214
236
  column,
215
- appliers: quickFilterValues.map(value => ({
216
- v7: false,
217
- fn: getApplyQuickFilterFn(value, column, apiRef)
218
- }))
237
+ appliers: quickFilterValues.map(quickFilterValue => {
238
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
239
+ return {
240
+ v7: false,
241
+ fn: getApplyQuickFilterFn(value, column, apiRef)
242
+ };
243
+ })
219
244
  });
220
245
  }
221
246
  });
@@ -238,18 +263,24 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
238
263
  continue;
239
264
  }
240
265
  const applier = appliers[v];
241
- const value = apiRef.current.getRowValue(row, column);
266
+ let value = apiRef.current.getRowFormattedValue(row, column);
242
267
  if (applier.fn === null) {
243
268
  continue;
244
269
  }
245
270
  if (applier.v7) {
271
+ if (ignoreDiacritics) {
272
+ value = removeDiacritics(value);
273
+ }
246
274
  const isMatching = applier.fn(value, row, column, apiRef);
247
275
  if (isMatching) {
248
276
  result[filterValue] = true;
249
277
  continue outer;
250
278
  }
251
279
  } else {
252
- const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, field);
280
+ const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(apiRef.current.getRowId(row), field);
281
+ if (ignoreDiacritics) {
282
+ cellParams.value = removeDiacritics(cellParams.value);
283
+ }
253
284
  usedCellParams[field] = cellParams;
254
285
  const isMatching = applier.fn(cellParams);
255
286
  if (isMatching) {
@@ -265,9 +296,9 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
265
296
  return result;
266
297
  };
267
298
  };
268
- export const buildAggregatedFilterApplier = (getRowId, filterModel, apiRef, disableEval) => {
269
- const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval);
270
- const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
299
+ export const buildAggregatedFilterApplier = (filterModel, apiRef, disableEval) => {
300
+ const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval);
301
+ const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
271
302
  return function isRowMatchingFilters(row, shouldApplyFilter, result) {
272
303
  result.passingFilterItems = isRowMatchingFilterItems?.(row, shouldApplyFilter) ?? null;
273
304
  result.passingQuickFilterValues = isRowMatchingQuickFilter?.(row, shouldApplyFilter) ?? null;
@@ -59,7 +59,7 @@ export const useGridFilter = (apiRef, props) => {
59
59
  const updateFilteredRows = React.useCallback(() => {
60
60
  apiRef.current.setState(state => {
61
61
  const filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
62
- const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(props.getRowId, filterModel, apiRef, props.disableEval) : null;
62
+ const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(filterModel, apiRef, props.disableEval) : null;
63
63
  const filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
64
64
  isRowMatchingFilters,
65
65
  filterModel: filterModel ?? getDefaultGridFilterModel()
@@ -73,7 +73,7 @@ export const useGridFilter = (apiRef, props) => {
73
73
  });
74
74
  });
75
75
  apiRef.current.publishEvent('filteredRowsSet');
76
- }, [apiRef, props.filterMode, props.getRowId, props.disableEval]);
76
+ }, [apiRef, props.filterMode, props.disableEval]);
77
77
  const addColumnMenuItem = React.useCallback((columnMenuItems, colDef) => {
78
78
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
79
79
  return columnMenuItems;
@@ -174,7 +174,7 @@ export const useGridRowsMeta = (apiRef, props) => {
174
174
  rowsHeightLookup.current[id].needsFirstMeasurement = false;
175
175
  hydrateRowsMeta();
176
176
  }, [hydrateRowsMeta]);
177
- const debouncedHydrateRowsMeta = React.useMemo(() => debounce(hydrateRowsMeta), [hydrateRowsMeta]);
177
+ const debouncedHydrateRowsMeta = React.useMemo(() => debounce(hydrateRowsMeta, props.rowPositionsDebounceMs), [hydrateRowsMeta, props.rowPositionsDebounceMs]);
178
178
  const storeMeasuredRowHeight = React.useCallback((id, height, position) => {
179
179
  if (!rowsHeightLookup.current[id] || !rowsHeightLookup.current[id].autoHeight) {
180
180
  return;
@@ -464,6 +464,7 @@ export const useGridVirtualScroller = props => {
464
464
  rowStyleCache.current = Object.create(null);
465
465
  }
466
466
  const rows = [];
467
+ let isRowWithFocusedCellRendered = false;
467
468
  for (let i = 0; i < renderedRows.length; i += 1) {
468
469
  const {
469
470
  id,
@@ -498,6 +499,13 @@ export const useGridVirtualScroller = props => {
498
499
  const style = _extends({}, rowStyle, rootRowStyle);
499
500
  rowStyleCache.current[id] = style;
500
501
  }
502
+ let index = rowIndexOffset + (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i;
503
+ if (isRowWithFocusedCellNotInRange && cellFocus?.id === id) {
504
+ index = indexOfRowWithFocusedCell;
505
+ isRowWithFocusedCellRendered = true;
506
+ } else if (isRowWithFocusedCellRendered) {
507
+ index -= 1;
508
+ }
501
509
  rows.push( /*#__PURE__*/_jsx(rootProps.slots.row, _extends({
502
510
  row: model,
503
511
  rowId: id,
@@ -511,7 +519,7 @@ export const useGridVirtualScroller = props => {
511
519
  firstColumnToRender: firstColumnToRender,
512
520
  lastColumnToRender: lastColumnToRender,
513
521
  selected: isSelected,
514
- index: rowIndexOffset + (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i,
522
+ index: index,
515
523
  containerWidth: availableSpace,
516
524
  isLastVisible: lastVisibleRowIndex,
517
525
  position: position
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.16.3
2
+ * @mui/x-data-grid v6.18.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -60,13 +60,12 @@ const ptBRGrid = {
60
60
  filterOperatorIsEmpty: 'está vazio',
61
61
  filterOperatorIsNotEmpty: 'não está vazio',
62
62
  filterOperatorIsAnyOf: 'é qualquer um dos',
63
- // 'filterOperator=': '=',
64
- // 'filterOperator!=': '!=',
65
- // 'filterOperator>': '>',
66
- // 'filterOperator>=': '>=',
67
- // 'filterOperator<': '<',
68
- // 'filterOperator<=': '<=',
69
-
63
+ 'filterOperator=': 'igual à',
64
+ 'filterOperator!=': 'diferente de',
65
+ 'filterOperator>': 'maior que',
66
+ 'filterOperator>=': 'maior ou igual que',
67
+ 'filterOperator<': 'menor que',
68
+ 'filterOperator<=': 'menor ou igual que',
70
69
  // Header filter operators text
71
70
  headerFilterOperatorContains: 'Contém',
72
71
  headerFilterOperatorEquals: 'Igual',
@@ -74,13 +73,13 @@ const ptBRGrid = {
74
73
  headerFilterOperatorEndsWith: 'Termina com',
75
74
  headerFilterOperatorIs: 'É',
76
75
  headerFilterOperatorNot: 'Não é',
77
- // headerFilterOperatorAfter: 'Is after',
78
- // headerFilterOperatorOnOrAfter: 'Is on or after',
79
- // headerFilterOperatorBefore: 'Is before',
80
- // headerFilterOperatorOnOrBefore: 'Is on or before',
81
- // headerFilterOperatorIsEmpty: 'Is empty',
82
- // headerFilterOperatorIsNotEmpty: 'Is not empty',
83
- // headerFilterOperatorIsAnyOf: 'Is any of',
76
+ headerFilterOperatorAfter: 'Depois de',
77
+ headerFilterOperatorOnOrAfter: 'Está entre ou depois de',
78
+ headerFilterOperatorBefore: 'Antes de',
79
+ headerFilterOperatorOnOrBefore: 'Está entre ou antes de',
80
+ headerFilterOperatorIsEmpty: 'É vazio',
81
+ headerFilterOperatorIsNotEmpty: 'Não é vazio',
82
+ headerFilterOperatorIsAnyOf: 'É algum',
84
83
  'headerFilterOperator=': 'Igual',
85
84
  'headerFilterOperator!=': 'Não igual',
86
85
  'headerFilterOperator>': 'Maior que',
@@ -1,5 +1,5 @@
1
1
  export function isNumber(value) {
2
- return typeof value === 'number';
2
+ return typeof value === 'number' && !Number.isNaN(value);
3
3
  }
4
4
  export function isFunction(value) {
5
5
  return typeof value === 'function';
@@ -286,6 +286,12 @@ DataGridRaw.propTypes = {
286
286
  * @default false
287
287
  */
288
288
  hideFooterSelectedRowCount: _propTypes.default.bool,
289
+ /**
290
+ * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
291
+ * E.g. when filter value is `cafe`, the rows with `café` will be visible.
292
+ * @default false
293
+ */
294
+ ignoreDiacritics: _propTypes.default.bool,
289
295
  /**
290
296
  * The initial state of the DataGrid.
291
297
  * The data in it will be set in the state on initialization but will not be controlled.
@@ -604,6 +610,13 @@ DataGridRaw.propTypes = {
604
610
  * Controls the modes of the rows.
605
611
  */
606
612
  rowModesModel: _propTypes.default.object,
613
+ /**
614
+ * The milliseconds delay to wait after measuring the row height before recalculating row positions.
615
+ * Setting it to a lower value could be useful when using dynamic row height,
616
+ * but might reduce performance when displaying a large number of rows.
617
+ * @default 166
618
+ */
619
+ rowPositionsDebounceMs: _propTypes.default.number,
607
620
  /**
608
621
  * Set of rows of type [[GridRowsProp]].
609
622
  */
@@ -60,6 +60,7 @@ const DATA_GRID_PROPS_DEFAULT_VALUES = exports.DATA_GRID_PROPS_DEFAULT_VALUES =
60
60
  hideFooterPagination: false,
61
61
  hideFooterRowCount: false,
62
62
  hideFooterSelectedRowCount: false,
63
+ ignoreDiacritics: false,
63
64
  logger: console,
64
65
  logLevel: process.env.NODE_ENV === 'production' ? 'error' : 'warn',
65
66
  pagination: false,
@@ -77,7 +78,8 @@ const DATA_GRID_PROPS_DEFAULT_VALUES = exports.DATA_GRID_PROPS_DEFAULT_VALUES =
77
78
  keepNonExistentRowsSelected: false,
78
79
  keepColumnPositionIfDraggedOutside: false,
79
80
  unstable_ignoreValueFormatterDuringExport: false,
80
- clipboardCopyCellDelimiter: '\t'
81
+ clipboardCopyCellDelimiter: '\t',
82
+ rowPositionsDebounceMs: 166
81
83
  };
82
84
  const defaultSlots = (0, _utils.uncapitalizeObjectKeys)(_defaultGridSlotsComponents.DATA_GRID_DEFAULT_SLOTS_COMPONENTS);
83
85
  const useDataGridProps = inProps => {
@@ -13,8 +13,7 @@ const getGridStringQuickFilterFn = exports.getGridStringQuickFilterFn = (0, _uti
13
13
  return null;
14
14
  }
15
15
  const filterRegex = new RegExp((0, _utils.escapeRegExp)(value), 'i');
16
- return (_, row, column, apiRef) => {
17
- const columnValue = apiRef.current.getRowFormattedValue(row, column);
16
+ return columnValue => {
18
17
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
19
18
  };
20
19
  });
@@ -198,7 +198,8 @@ const GridRootStyles = exports.GridRootStyles = (0, _styles.styled)('div', {
198
198
  overflow: 'visible !important'
199
199
  },
200
200
  [`& .${_gridClasses.gridClasses.cell} > *`]: {
201
- overflow: 'visible !important'
201
+ overflow: 'visible !important',
202
+ whiteSpace: 'nowrap'
202
203
  }
203
204
  },
204
205
  [`& .${_gridClasses.gridClasses['virtualScrollerContent--overflowed']} .${_gridClasses.gridClasses['row--lastVisible']} .${_gridClasses.gridClasses.cell}`]: {
@@ -41,6 +41,10 @@ function GridColumnMenuSortItem(props) {
41
41
  if (!colDef || !colDef.sortable || !sortingOrder.some(item => !!item)) {
42
42
  return null;
43
43
  }
44
+ const getLabel = key => {
45
+ const label = apiRef.current.getLocaleText(key);
46
+ return typeof label === 'function' ? label(colDef) : label;
47
+ };
44
48
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
45
49
  children: [sortingOrder.includes('asc') && sortDirection !== 'asc' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
46
50
  onClick: onSortMenuItemClick,
@@ -50,7 +54,7 @@ function GridColumnMenuSortItem(props) {
50
54
  fontSize: "small"
51
55
  })
52
56
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
53
- children: apiRef.current.getLocaleText('columnMenuSortAsc')
57
+ children: getLabel('columnMenuSortAsc')
54
58
  })]
55
59
  }) : null, sortingOrder.includes('desc') && sortDirection !== 'desc' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
56
60
  onClick: onSortMenuItemClick,
@@ -60,7 +64,7 @@ function GridColumnMenuSortItem(props) {
60
64
  fontSize: "small"
61
65
  })
62
66
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
63
- children: apiRef.current.getLocaleText('columnMenuSortDesc')
67
+ children: getLabel('columnMenuSortDesc')
64
68
  })]
65
69
  }) : null, sortingOrder.includes(null) && sortDirection != null ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
66
70
  onClick: onSortMenuItemClick,
@@ -20,6 +20,9 @@ const useGridInitialization = (inputApiRef, props) => {
20
20
  (0, _pipeProcessing.useGridPipeProcessing)(privateApiRef);
21
21
  (0, _strategyProcessing.useGridStrategyProcessing)(privateApiRef);
22
22
  (0, _useGridLocaleText.useGridLocaleText)(privateApiRef, props);
23
+ privateApiRef.current.register('private', {
24
+ rootProps: props
25
+ });
23
26
  return privateApiRef;
24
27
  };
25
28
  exports.useGridInitialization = useGridInitialization;
@@ -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.sanitizeFilterModel = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedQuickFilterApplier = exports.buildAggregatedFilterItemsApplier = exports.buildAggregatedFilterApplier = void 0;
7
+ exports.sanitizeFilterModel = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedFilterApplier = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _models = require("../../../models");
10
10
  var _utils = require("../../../colDef/utils");
@@ -23,7 +23,7 @@ try {
23
23
  /**
24
24
  * Adds default values to the optional fields of a filter items.
25
25
  * @param {GridFilterItem} item The raw filter item.
26
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
26
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
27
27
  * @return {GridFilterItem} The clean filter item with an uniq ID and an always-defined operator.
28
28
  * TODO: Make the typing reflect the different between GridFilterInputItem and GridFilterItem.
29
29
  */
@@ -78,6 +78,12 @@ const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFiltering,
78
78
  filterModel: sanitizeFilterModel(filterModel, disableMultipleColumnsFiltering, apiRef)
79
79
  });
80
80
  exports.mergeStateWithFilterModel = mergeStateWithFilterModel;
81
+ const removeDiacritics = value => {
82
+ if (typeof value === 'string') {
83
+ return value.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
84
+ }
85
+ return value;
86
+ };
81
87
  const getFilterCallbackFromItem = (filterItem, apiRef) => {
82
88
  if (!filterItem.field || !filterItem.operator) {
83
89
  return null;
@@ -93,6 +99,12 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
93
99
  } else {
94
100
  parsedValue = filterItem.value;
95
101
  }
102
+ const {
103
+ ignoreDiacritics
104
+ } = apiRef.current.rootProps;
105
+ if (ignoreDiacritics) {
106
+ parsedValue = removeDiacritics(parsedValue);
107
+ }
96
108
  const newFilterItem = (0, _extends2.default)({}, filterItem, {
97
109
  value: parsedValue
98
110
  });
@@ -115,7 +127,10 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
115
127
  v7: true,
116
128
  item: newFilterItem,
117
129
  fn: row => {
118
- const value = apiRef.current.getRowValue(row, column);
130
+ let value = apiRef.current.getRowValue(row, column);
131
+ if (ignoreDiacritics) {
132
+ value = removeDiacritics(value);
133
+ }
119
134
  return applyFilterOnRow(value, row, column, apiRef);
120
135
  }
121
136
  };
@@ -130,6 +145,9 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
130
145
  fn: rowId => {
131
146
  const params = apiRef.current.getCellParams(rowId, newFilterItem.field);
132
147
  _utils.GLOBAL_API_REF.current = apiRef;
148
+ if (ignoreDiacritics) {
149
+ params.value = removeDiacritics(params.value);
150
+ }
133
151
  const result = applyFilterOnRow(params);
134
152
  _utils.GLOBAL_API_REF.current = null;
135
153
  return result;
@@ -140,12 +158,11 @@ let filterItemsApplierId = 1;
140
158
 
141
159
  /**
142
160
  * Generates a method to easily check if a row is matching the current filter model.
143
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
144
161
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
145
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
162
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
146
163
  * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
147
164
  */
148
- const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disableEval) => {
165
+ const buildAggregatedFilterItemsApplier = (filterModel, apiRef, disableEval) => {
149
166
  const {
150
167
  items
151
168
  } = filterModel;
@@ -160,7 +177,7 @@ const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disabl
160
177
  for (let i = 0; i < appliers.length; i += 1) {
161
178
  const applier = appliers[i];
162
179
  if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
163
- resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
180
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(apiRef.current.getRowId(row));
164
181
  }
165
182
  }
166
183
  return resultPerItemId;
@@ -176,14 +193,14 @@ const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disabl
176
193
  ${appliers.map((applier, i) => `${JSON.stringify(String(applier.item.id))}:
177
194
  !shouldApply${i} ?
178
195
  false :
179
- ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(${getRowId ? 'getRowId(row)' : 'row.id'})`},
196
+ ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(getRowId(row))`},
180
197
  `).join('\n')}};
181
198
 
182
199
  return result$$;
183
200
  })`;
184
201
  const filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
185
202
  const filterItem = (row, shouldApplyItem) => {
186
- return filterItemCore(getRowId, appliers, row, shouldApplyItem);
203
+ return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
187
204
  };
188
205
  filterItemsApplierId += 1;
189
206
  return filterItem;
@@ -191,13 +208,11 @@ const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disabl
191
208
 
192
209
  /**
193
210
  * Generates a method to easily check if a row is matching the current quick filter.
194
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
195
211
  * @param {any[]} filterModel The model with which we want to filter the rows.
196
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
212
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
197
213
  * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
198
214
  */
199
- exports.buildAggregatedFilterItemsApplier = buildAggregatedFilterItemsApplier;
200
- const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
215
+ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
201
216
  const quickFilterValues = filterModel.quickFilterValues?.filter(Boolean) ?? [];
202
217
  if (quickFilterValues.length === 0) {
203
218
  return null;
@@ -205,6 +220,9 @@ const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
205
220
  const quickFilterExcludeHiddenColumns = filterModel.quickFilterExcludeHiddenColumns ?? false;
206
221
  const columnFields = quickFilterExcludeHiddenColumns ? (0, _columns.gridVisibleColumnFieldsSelector)(apiRef) : (0, _columns.gridColumnFieldsSelector)(apiRef);
207
222
  const appliersPerField = [];
223
+ const {
224
+ ignoreDiacritics
225
+ } = apiRef.current.rootProps;
208
226
  columnFields.forEach(field => {
209
227
  const column = apiRef.current.getColumn(field);
210
228
  const getApplyQuickFilterFn = column?.getApplyQuickFilterFn;
@@ -214,18 +232,24 @@ const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
214
232
  if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
215
233
  appliersPerField.push({
216
234
  column,
217
- appliers: quickFilterValues.map(value => ({
218
- v7: true,
219
- fn: getApplyQuickFilterFnV7(value, column, apiRef)
220
- }))
235
+ appliers: quickFilterValues.map(quickFilterValue => {
236
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
237
+ return {
238
+ v7: true,
239
+ fn: getApplyQuickFilterFnV7(value, column, apiRef)
240
+ };
241
+ })
221
242
  });
222
243
  } else if (getApplyQuickFilterFn) {
223
244
  appliersPerField.push({
224
245
  column,
225
- appliers: quickFilterValues.map(value => ({
226
- v7: false,
227
- fn: getApplyQuickFilterFn(value, column, apiRef)
228
- }))
246
+ appliers: quickFilterValues.map(quickFilterValue => {
247
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
248
+ return {
249
+ v7: false,
250
+ fn: getApplyQuickFilterFn(value, column, apiRef)
251
+ };
252
+ })
229
253
  });
230
254
  }
231
255
  });
@@ -248,18 +272,24 @@ const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
248
272
  continue;
249
273
  }
250
274
  const applier = appliers[v];
251
- const value = apiRef.current.getRowValue(row, column);
275
+ let value = apiRef.current.getRowFormattedValue(row, column);
252
276
  if (applier.fn === null) {
253
277
  continue;
254
278
  }
255
279
  if (applier.v7) {
280
+ if (ignoreDiacritics) {
281
+ value = removeDiacritics(value);
282
+ }
256
283
  const isMatching = applier.fn(value, row, column, apiRef);
257
284
  if (isMatching) {
258
285
  result[filterValue] = true;
259
286
  continue outer;
260
287
  }
261
288
  } else {
262
- const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, field);
289
+ const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(apiRef.current.getRowId(row), field);
290
+ if (ignoreDiacritics) {
291
+ cellParams.value = removeDiacritics(cellParams.value);
292
+ }
263
293
  usedCellParams[field] = cellParams;
264
294
  const isMatching = applier.fn(cellParams);
265
295
  if (isMatching) {
@@ -275,10 +305,9 @@ const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
275
305
  return result;
276
306
  };
277
307
  };
278
- exports.buildAggregatedQuickFilterApplier = buildAggregatedQuickFilterApplier;
279
- const buildAggregatedFilterApplier = (getRowId, filterModel, apiRef, disableEval) => {
280
- const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval);
281
- const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
308
+ const buildAggregatedFilterApplier = (filterModel, apiRef, disableEval) => {
309
+ const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval);
310
+ const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
282
311
  return function isRowMatchingFilters(row, shouldApplyFilter, result) {
283
312
  result.passingFilterItems = isRowMatchingFilterItems?.(row, shouldApplyFilter) ?? null;
284
313
  result.passingQuickFilterValues = isRowMatchingQuickFilter?.(row, shouldApplyFilter) ?? null;
@@ -69,7 +69,7 @@ const useGridFilter = (apiRef, props) => {
69
69
  const updateFilteredRows = React.useCallback(() => {
70
70
  apiRef.current.setState(state => {
71
71
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(state, apiRef.current.instanceId);
72
- const isRowMatchingFilters = props.filterMode === 'client' ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(props.getRowId, filterModel, apiRef, props.disableEval) : null;
72
+ const isRowMatchingFilters = props.filterMode === 'client' ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(filterModel, apiRef, props.disableEval) : null;
73
73
  const filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
74
74
  isRowMatchingFilters,
75
75
  filterModel: filterModel ?? (0, _gridFilterState.getDefaultGridFilterModel)()
@@ -83,7 +83,7 @@ const useGridFilter = (apiRef, props) => {
83
83
  });
84
84
  });
85
85
  apiRef.current.publishEvent('filteredRowsSet');
86
- }, [apiRef, props.filterMode, props.getRowId, props.disableEval]);
86
+ }, [apiRef, props.filterMode, props.disableEval]);
87
87
  const addColumnMenuItem = React.useCallback((columnMenuItems, colDef) => {
88
88
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
89
89
  return columnMenuItems;
@@ -184,7 +184,7 @@ const useGridRowsMeta = (apiRef, props) => {
184
184
  rowsHeightLookup.current[id].needsFirstMeasurement = false;
185
185
  hydrateRowsMeta();
186
186
  }, [hydrateRowsMeta]);
187
- const debouncedHydrateRowsMeta = React.useMemo(() => (0, _utils.unstable_debounce)(hydrateRowsMeta), [hydrateRowsMeta]);
187
+ const debouncedHydrateRowsMeta = React.useMemo(() => (0, _utils.unstable_debounce)(hydrateRowsMeta, props.rowPositionsDebounceMs), [hydrateRowsMeta, props.rowPositionsDebounceMs]);
188
188
  const storeMeasuredRowHeight = React.useCallback((id, height, position) => {
189
189
  if (!rowsHeightLookup.current[id] || !rowsHeightLookup.current[id].autoHeight) {
190
190
  return;