@mui/x-data-grid 6.17.0 → 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 (46) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/DataGrid/DataGrid.js +6 -0
  3. package/DataGrid/useDataGridProps.js +1 -0
  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/index.js +1 -1
  13. package/legacy/DataGrid/DataGrid.js +6 -0
  14. package/legacy/DataGrid/useDataGridProps.js +1 -0
  15. package/legacy/colDef/gridStringOperators.js +1 -2
  16. package/legacy/components/containers/GridRootStyles.js +2 -1
  17. package/legacy/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  18. package/legacy/hooks/core/useGridInitialization.js +3 -0
  19. package/legacy/hooks/features/filter/gridFilterUtils.js +40 -17
  20. package/legacy/hooks/features/filter/useGridFilter.js +2 -2
  21. package/legacy/index.js +1 -1
  22. package/models/api/gridApiCommon.d.ts +3 -2
  23. package/models/api/gridApiCommunity.d.ts +2 -1
  24. package/models/api/gridCoreApi.d.ts +7 -1
  25. package/models/api/gridFilterApi.d.ts +1 -1
  26. package/models/api/gridLocaleTextApi.d.ts +3 -2
  27. package/models/props/DataGridProps.d.ts +6 -0
  28. package/modern/DataGrid/DataGrid.js +6 -0
  29. package/modern/DataGrid/useDataGridProps.js +1 -0
  30. package/modern/colDef/gridStringOperators.js +1 -2
  31. package/modern/components/containers/GridRootStyles.js +2 -1
  32. package/modern/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  33. package/modern/hooks/core/useGridInitialization.js +3 -0
  34. package/modern/hooks/features/filter/gridFilterUtils.js +55 -24
  35. package/modern/hooks/features/filter/useGridFilter.js +2 -2
  36. package/modern/index.js +1 -1
  37. package/node/DataGrid/DataGrid.js +6 -0
  38. package/node/DataGrid/useDataGridProps.js +1 -0
  39. package/node/colDef/gridStringOperators.js +1 -2
  40. package/node/components/containers/GridRootStyles.js +2 -1
  41. package/node/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  42. package/node/hooks/core/useGridInitialization.js +3 -0
  43. package/node/hooks/features/filter/gridFilterUtils.js +56 -27
  44. package/node/hooks/features/filter/useGridFilter.js +2 -2
  45. package/node/index.js +1 -1
  46. package/package.json +2 -2
@@ -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
  */
@@ -79,6 +79,12 @@ export var mergeStateWithFilterModel = function mergeStateWithFilterModel(filter
79
79
  });
80
80
  };
81
81
  };
82
+ var removeDiacritics = function removeDiacritics(value) {
83
+ if (typeof value === 'string') {
84
+ return value.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
85
+ }
86
+ return value;
87
+ };
82
88
  var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, apiRef) {
83
89
  if (!filterItem.field || !filterItem.operator) {
84
90
  return null;
@@ -97,6 +103,10 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
97
103
  } else {
98
104
  parsedValue = filterItem.value;
99
105
  }
106
+ var ignoreDiacritics = apiRef.current.rootProps.ignoreDiacritics;
107
+ if (ignoreDiacritics) {
108
+ parsedValue = removeDiacritics(parsedValue);
109
+ }
100
110
  var newFilterItem = _extends({}, filterItem, {
101
111
  value: parsedValue
102
112
  });
@@ -122,6 +132,9 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
122
132
  item: newFilterItem,
123
133
  fn: function fn(row) {
124
134
  var value = apiRef.current.getRowValue(row, column);
135
+ if (ignoreDiacritics) {
136
+ value = removeDiacritics(value);
137
+ }
125
138
  return _applyFilterOnRow(value, row, column, apiRef);
126
139
  }
127
140
  };
@@ -136,6 +149,9 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
136
149
  fn: function fn(rowId) {
137
150
  var params = apiRef.current.getCellParams(rowId, newFilterItem.field);
138
151
  GLOBAL_API_REF.current = apiRef;
152
+ if (ignoreDiacritics) {
153
+ params.value = removeDiacritics(params.value);
154
+ }
139
155
  var result = applyFilterOnRow(params);
140
156
  GLOBAL_API_REF.current = null;
141
157
  return result;
@@ -146,12 +162,11 @@ var filterItemsApplierId = 1;
146
162
 
147
163
  /**
148
164
  * Generates a method to easily check if a row is matching the current filter model.
149
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
150
165
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
151
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
166
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
152
167
  * @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.
153
168
  */
154
- export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval) {
169
+ var buildAggregatedFilterItemsApplier = function buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval) {
155
170
  var items = filterModel.items;
156
171
  var appliers = items.map(function (item) {
157
172
  return getFilterCallbackFromItem(item, apiRef);
@@ -168,7 +183,7 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
168
183
  for (var i = 0; i < appliers.length; i += 1) {
169
184
  var applier = appliers[i];
170
185
  if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
171
- resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
186
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(apiRef.current.getRowId(row));
172
187
  }
173
188
  }
174
189
  return resultPerItemId;
@@ -180,11 +195,11 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
180
195
  var filterItemTemplate = "(function filterItem$$(getRowId, appliers, row, shouldApplyFilter) {\n ".concat(appliers.map(function (applier, i) {
181
196
  return "const shouldApply".concat(i, " = !shouldApplyFilter || shouldApplyFilter(").concat(JSON.stringify(applier.item.field), ");");
182
197
  }).join('\n'), "\n\n const result$$ = {\n ").concat(appliers.map(function (applier, i) {
183
- return "".concat(JSON.stringify(String(applier.item.id)), ":\n !shouldApply").concat(i, " ?\n false :\n ").concat(applier.v7 ? "appliers[".concat(i, "].fn(row)") : "appliers[".concat(i, "].fn(").concat(getRowId ? 'getRowId(row)' : 'row.id', ")"), ",\n ");
198
+ return "".concat(JSON.stringify(String(applier.item.id)), ":\n !shouldApply").concat(i, " ?\n false :\n ").concat(applier.v7 ? "appliers[".concat(i, "].fn(row)") : "appliers[".concat(i, "].fn(getRowId(row))"), ",\n ");
184
199
  }).join('\n'), "};\n\n return result$$;\n })");
185
200
  var filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
186
201
  var filterItem = function filterItem(row, shouldApplyItem) {
187
- return filterItemCore(getRowId, appliers, row, shouldApplyItem);
202
+ return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
188
203
  };
189
204
  filterItemsApplierId += 1;
190
205
  return filterItem;
@@ -192,12 +207,11 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
192
207
 
193
208
  /**
194
209
  * Generates a method to easily check if a row is matching the current quick filter.
195
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
196
210
  * @param {any[]} filterModel The model with which we want to filter the rows.
197
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
211
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
198
212
  * @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.
199
213
  */
200
- export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef) {
214
+ var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilterApplier(filterModel, apiRef) {
201
215
  var _filterModel$quickFil, _filterModel$quickFil2, _filterModel$quickFil3;
202
216
  var quickFilterValues = (_filterModel$quickFil = (_filterModel$quickFil2 = filterModel.quickFilterValues) == null ? void 0 : _filterModel$quickFil2.filter(Boolean)) != null ? _filterModel$quickFil : [];
203
217
  if (quickFilterValues.length === 0) {
@@ -206,6 +220,7 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
206
220
  var quickFilterExcludeHiddenColumns = (_filterModel$quickFil3 = filterModel.quickFilterExcludeHiddenColumns) != null ? _filterModel$quickFil3 : false;
207
221
  var columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
208
222
  var appliersPerField = [];
223
+ var ignoreDiacritics = apiRef.current.rootProps.ignoreDiacritics;
209
224
  columnFields.forEach(function (field) {
210
225
  var column = apiRef.current.getColumn(field);
211
226
  var getApplyQuickFilterFn = column == null ? void 0 : column.getApplyQuickFilterFn;
@@ -215,7 +230,8 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
215
230
  if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
216
231
  appliersPerField.push({
217
232
  column: column,
218
- appliers: quickFilterValues.map(function (value) {
233
+ appliers: quickFilterValues.map(function (quickFilterValue) {
234
+ var value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
219
235
  return {
220
236
  v7: true,
221
237
  fn: getApplyQuickFilterFnV7(value, column, apiRef)
@@ -225,7 +241,8 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
225
241
  } else if (getApplyQuickFilterFn) {
226
242
  appliersPerField.push({
227
243
  column: column,
228
- appliers: quickFilterValues.map(function (value) {
244
+ appliers: quickFilterValues.map(function (quickFilterValue) {
245
+ var value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
229
246
  return {
230
247
  v7: false,
231
248
  fn: getApplyQuickFilterFn(value, column, apiRef)
@@ -250,11 +267,14 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
250
267
  continue;
251
268
  }
252
269
  var applier = appliers[v];
253
- var value = apiRef.current.getRowValue(row, column);
270
+ var value = apiRef.current.getRowFormattedValue(row, column);
254
271
  if (applier.fn === null) {
255
272
  continue;
256
273
  }
257
274
  if (applier.v7) {
275
+ if (ignoreDiacritics) {
276
+ value = removeDiacritics(value);
277
+ }
258
278
  var isMatching = applier.fn(value, row, column, apiRef);
259
279
  if (isMatching) {
260
280
  result[filterValue] = true;
@@ -262,7 +282,10 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
262
282
  }
263
283
  } else {
264
284
  var _usedCellParams$_fiel;
265
- var cellParams = (_usedCellParams$_fiel = usedCellParams[_field]) != null ? _usedCellParams$_fiel : apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, _field);
285
+ var cellParams = (_usedCellParams$_fiel = usedCellParams[_field]) != null ? _usedCellParams$_fiel : apiRef.current.getCellParams(apiRef.current.getRowId(row), _field);
286
+ if (ignoreDiacritics) {
287
+ cellParams.value = removeDiacritics(cellParams.value);
288
+ }
266
289
  usedCellParams[_field] = cellParams;
267
290
  var _isMatching = applier.fn(cellParams);
268
291
  if (_isMatching) {
@@ -278,9 +301,9 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
278
301
  return result;
279
302
  };
280
303
  };
281
- export var buildAggregatedFilterApplier = function buildAggregatedFilterApplier(getRowId, filterModel, apiRef, disableEval) {
282
- var isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval);
283
- var isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
304
+ export var buildAggregatedFilterApplier = function buildAggregatedFilterApplier(filterModel, apiRef, disableEval) {
305
+ var isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval);
306
+ var isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
284
307
  return function isRowMatchingFilters(row, shouldApplyFilter, result) {
285
308
  var _isRowMatchingFilterI, _isRowMatchingQuickFi;
286
309
  result.passingFilterItems = (_isRowMatchingFilterI = isRowMatchingFilterItems == null ? void 0 : isRowMatchingFilterItems(row, shouldApplyFilter)) != null ? _isRowMatchingFilterI : null;
@@ -62,7 +62,7 @@ export var useGridFilter = function useGridFilter(apiRef, props) {
62
62
  var updateFilteredRows = React.useCallback(function () {
63
63
  apiRef.current.setState(function (state) {
64
64
  var filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
65
- var isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(props.getRowId, filterModel, apiRef, props.disableEval) : null;
65
+ var isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(filterModel, apiRef, props.disableEval) : null;
66
66
  var filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
67
67
  isRowMatchingFilters: isRowMatchingFilters,
68
68
  filterModel: filterModel != null ? filterModel : getDefaultGridFilterModel()
@@ -76,7 +76,7 @@ export var useGridFilter = function useGridFilter(apiRef, props) {
76
76
  });
77
77
  });
78
78
  apiRef.current.publishEvent('filteredRowsSet');
79
- }, [apiRef, props.filterMode, props.getRowId, props.disableEval]);
79
+ }, [apiRef, props.filterMode, props.disableEval]);
80
80
  var addColumnMenuItem = React.useCallback(function (columnMenuItems, colDef) {
81
81
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
82
82
  return columnMenuItems;
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.17.0
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
@@ -27,9 +27,10 @@ import type { GridStatePersistenceApi } from '../../hooks/features/statePersiste
27
27
  import { GridColumnGroupingApi } from './gridColumnGroupingApi';
28
28
  import type { GridInitialStateCommunity, GridStateCommunity } from '../gridStateCommunity';
29
29
  import { GridHeaderFilteringApi, GridHeaderFilteringPrivateApi } from './gridHeaderFilteringApi';
30
+ import type { DataGridProcessedProps } from '../props/DataGridProps';
30
31
  export interface GridApiCommon<GridState extends GridStateCommunity = any, GridInitialState extends GridInitialStateCommunity = any> extends GridCoreApi, GridPipeProcessingApi, GridDensityApi, GridDimensionsApi, GridRowApi, GridRowsMetaApi, GridEditingApi, GridParamsApi, GridColumnApi, GridRowSelectionApi, GridSortApi, GridPaginationApi, GridCsvExportApi, GridFocusApi, GridFilterApi, GridColumnMenuApi, GridPreferencesPanelApi, GridPrintExportApi, GridVirtualizationApi, GridLocaleTextApi, GridScrollApi, GridColumnSpanningApi, GridStateApi<GridState>, GridStatePersistenceApi<GridInitialState>, GridColumnGroupingApi, GridHeaderFilteringApi {
31
32
  }
32
- export interface GridPrivateOnlyApiCommon<Api extends GridApiCommon, PrivateApi extends GridPrivateApiCommon> extends GridCorePrivateApi<Api, PrivateApi>, GridStatePrivateApi<PrivateApi['state']>, GridPipeProcessingPrivateApi, GridStrategyProcessingApi, GridColumnSpanningPrivateApi, GridRowsMetaPrivateApi, GridDimensionsPrivateApi, GridEditingPrivateApi, GridLoggerApi, GridFocusPrivateApi, GridHeaderFilteringPrivateApi, GridVirtualizationPrivateApi {
33
+ export interface GridPrivateOnlyApiCommon<Api extends GridApiCommon, PrivateApi extends GridPrivateApiCommon, Props extends DataGridProcessedProps> extends GridCorePrivateApi<Api, PrivateApi, Props>, GridStatePrivateApi<PrivateApi['state']>, GridPipeProcessingPrivateApi, GridStrategyProcessingApi, GridColumnSpanningPrivateApi, GridRowsMetaPrivateApi, GridDimensionsPrivateApi, GridEditingPrivateApi, GridLoggerApi, GridFocusPrivateApi, GridHeaderFilteringPrivateApi, GridVirtualizationPrivateApi {
33
34
  }
34
- export interface GridPrivateApiCommon extends GridApiCommon, GridPrivateOnlyApiCommon<GridApiCommon, GridPrivateApiCommon> {
35
+ export interface GridPrivateApiCommon extends GridApiCommon, GridPrivateOnlyApiCommon<GridApiCommon, GridPrivateApiCommon, DataGridProcessedProps> {
35
36
  }
@@ -1,4 +1,5 @@
1
1
  import type { GridInitialStateCommunity, GridStateCommunity } from '../gridStateCommunity';
2
+ import type { DataGridProcessedProps } from '../props/DataGridProps';
2
3
  import type { GridApiCommon, GridPrivateOnlyApiCommon } from './gridApiCommon';
3
4
  import type { GridColumnReorderApi } from './gridColumnApi';
4
5
  import { GridRowProApi } from './gridRowApi';
@@ -8,5 +9,5 @@ import { GridRowMultiSelectionApi } from './gridRowSelectionApi';
8
9
  */
9
10
  export interface GridApiCommunity extends GridApiCommon<GridStateCommunity, GridInitialStateCommunity> {
10
11
  }
11
- export interface GridPrivateApiCommunity extends GridApiCommunity, GridPrivateOnlyApiCommon<GridApiCommunity, GridPrivateApiCommunity>, GridRowMultiSelectionApi, GridColumnReorderApi, GridRowProApi {
12
+ export interface GridPrivateApiCommunity extends GridApiCommunity, GridPrivateOnlyApiCommon<GridApiCommunity, GridPrivateApiCommunity, DataGridProcessedProps>, GridRowMultiSelectionApi, GridColumnReorderApi, GridRowProApi {
12
13
  }
@@ -4,6 +4,7 @@ import { Store } from '../../utils/Store';
4
4
  import { EventManager, EventListenerOptions } from '../../utils/EventManager';
5
5
  import { GridApiCaches } from '../gridApiCaches';
6
6
  import type { GridApiCommon, GridPrivateApiCommon } from './gridApiCommon';
7
+ import type { DataGridProcessedProps } from '../props/DataGridProps';
7
8
  /**
8
9
  * The core API interface that is available in the grid `apiRef`.
9
10
  */
@@ -41,7 +42,7 @@ export interface GridCoreApi {
41
42
  */
42
43
  store: Store<GridApiCommon['state']>;
43
44
  }
44
- export interface GridCorePrivateApi<GridPublicApi extends GridApiCommon, GridPrivateApi extends GridPrivateApiCommon> {
45
+ export interface GridCorePrivateApi<GridPublicApi extends GridApiCommon, GridPrivateApi extends GridPrivateApiCommon, GridProps extends DataGridProcessedProps> {
45
46
  /**
46
47
  * The caches used by hooks and state initializers.
47
48
  */
@@ -71,6 +72,11 @@ export interface GridCorePrivateApi<GridPublicApi extends GridApiCommon, GridPri
71
72
  * @returns {GridPublicApi} The public api.
72
73
  */
73
74
  getPublicApi: () => GridPublicApi;
75
+ /**
76
+ * Allows to access the root props outside of the React component.
77
+ * Do not use in React components - use the `useGridRootProps` hook instead.
78
+ */
79
+ rootProps: GridProps;
74
80
  /**
75
81
  * The React ref of the grid column container virtualized div element.
76
82
  */
@@ -48,7 +48,7 @@ export interface GridFilterApi {
48
48
  */
49
49
  setFilterModel: (model: GridFilterModel, reason?: GridControlledStateReasonLookup['filter']) => void;
50
50
  /**
51
- * Set the quick filter values ot the one given by `values`
51
+ * Set the quick filter values to the one given by `values`
52
52
  * @param {any[]} values The list of element to quick filter
53
53
  */
54
54
  setQuickFilterValues: (values: any[]) => void;
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentsPropsList } from '@mui/material/styles';
3
+ import { GridColDef } from '../colDef';
3
4
  /**
4
5
  * Set the types of the texts in the grid.
5
6
  */
@@ -88,8 +89,8 @@ export interface GridLocaleText {
88
89
  columnMenuFilter: React.ReactNode;
89
90
  columnMenuHideColumn: React.ReactNode;
90
91
  columnMenuUnsort: React.ReactNode;
91
- columnMenuSortAsc: React.ReactNode;
92
- columnMenuSortDesc: React.ReactNode;
92
+ columnMenuSortAsc: React.ReactNode | ((colDef: GridColDef) => React.ReactNode);
93
+ columnMenuSortDesc: React.ReactNode | ((colDef: GridColDef) => React.ReactNode);
93
94
  columnHeaderFiltersTooltipActive: (count: number) => React.ReactNode;
94
95
  columnHeaderFiltersLabel: string;
95
96
  columnHeaderSortIconLabel: string;
@@ -235,6 +235,12 @@ export interface DataGridPropsWithDefaultValues {
235
235
  * @default false
236
236
  */
237
237
  hideFooterSelectedRowCount: boolean;
238
+ /**
239
+ * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
240
+ * E.g. when filter value is `cafe`, the rows with `café` will be visible.
241
+ * @default false
242
+ */
243
+ ignoreDiacritics: boolean;
238
244
  /**
239
245
  * If `true`, the selection model will retain selected rows that do not exist.
240
246
  * Useful when using server side pagination and row selections need to be retained
@@ -278,6 +278,12 @@ DataGridRaw.propTypes = {
278
278
  * @default false
279
279
  */
280
280
  hideFooterSelectedRowCount: PropTypes.bool,
281
+ /**
282
+ * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
283
+ * E.g. when filter value is `cafe`, the rows with `café` will be visible.
284
+ * @default false
285
+ */
286
+ ignoreDiacritics: PropTypes.bool,
281
287
  /**
282
288
  * The initial state of the DataGrid.
283
289
  * The data in it will be set in the state on initialization but will not be controlled.
@@ -51,6 +51,7 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES = {
51
51
  hideFooterPagination: false,
52
52
  hideFooterRowCount: false,
53
53
  hideFooterSelectedRowCount: false,
54
+ ignoreDiacritics: false,
54
55
  logger: console,
55
56
  logLevel: process.env.NODE_ENV === 'production' ? 'error' : 'warn',
56
57
  pagination: false,
@@ -7,8 +7,7 @@ export const getGridStringQuickFilterFn = tagInternalFilter(value => {
7
7
  return null;
8
8
  }
9
9
  const filterRegex = new RegExp(escapeRegExp(value), 'i');
10
- return (_, row, column, apiRef) => {
11
- const columnValue = apiRef.current.getRowFormattedValue(row, column);
10
+ return columnValue => {
12
11
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
13
12
  };
14
13
  });
@@ -191,7 +191,8 @@ export const GridRootStyles = styled('div', {
191
191
  overflow: 'visible !important'
192
192
  },
193
193
  [`& .${gridClasses.cell} > *`]: {
194
- overflow: 'visible !important'
194
+ overflow: 'visible !important',
195
+ whiteSpace: 'nowrap'
195
196
  }
196
197
  },
197
198
  [`& .${gridClasses['virtualScrollerContent--overflowed']} .${gridClasses['row--lastVisible']} .${gridClasses.cell}`]: {
@@ -33,6 +33,10 @@ function GridColumnMenuSortItem(props) {
33
33
  if (!colDef || !colDef.sortable || !sortingOrder.some(item => !!item)) {
34
34
  return null;
35
35
  }
36
+ const getLabel = key => {
37
+ const label = apiRef.current.getLocaleText(key);
38
+ return typeof label === 'function' ? label(colDef) : label;
39
+ };
36
40
  return /*#__PURE__*/_jsxs(React.Fragment, {
37
41
  children: [sortingOrder.includes('asc') && sortDirection !== 'asc' ? /*#__PURE__*/_jsxs(MenuItem, {
38
42
  onClick: onSortMenuItemClick,
@@ -42,7 +46,7 @@ function GridColumnMenuSortItem(props) {
42
46
  fontSize: "small"
43
47
  })
44
48
  }), /*#__PURE__*/_jsx(ListItemText, {
45
- children: apiRef.current.getLocaleText('columnMenuSortAsc')
49
+ children: getLabel('columnMenuSortAsc')
46
50
  })]
47
51
  }) : null, sortingOrder.includes('desc') && sortDirection !== 'desc' ? /*#__PURE__*/_jsxs(MenuItem, {
48
52
  onClick: onSortMenuItemClick,
@@ -52,7 +56,7 @@ function GridColumnMenuSortItem(props) {
52
56
  fontSize: "small"
53
57
  })
54
58
  }), /*#__PURE__*/_jsx(ListItemText, {
55
- children: apiRef.current.getLocaleText('columnMenuSortDesc')
59
+ children: getLabel('columnMenuSortDesc')
56
60
  })]
57
61
  }) : null, sortingOrder.includes(null) && sortDirection != null ? /*#__PURE__*/_jsxs(MenuItem, {
58
62
  onClick: onSortMenuItemClick,
@@ -15,5 +15,8 @@ export const useGridInitialization = (inputApiRef, props) => {
15
15
  useGridPipeProcessing(privateApiRef);
16
16
  useGridStrategyProcessing(privateApiRef);
17
17
  useGridLocaleText(privateApiRef, props);
18
+ privateApiRef.current.register('private', {
19
+ rootProps: props
20
+ });
18
21
  return privateApiRef;
19
22
  };
@@ -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;
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.17.0
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
@@ -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.
@@ -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,
@@ -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
  });