@mui/x-data-grid 6.17.0 → 6.18.1

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 (69) hide show
  1. package/CHANGELOG.md +124 -5
  2. package/DataGrid/DataGrid.js +6 -0
  3. package/DataGrid/useDataGridProps.js +1 -0
  4. package/colDef/gridStringOperators.js +5 -1
  5. package/components/cell/GridActionsCell.js +19 -12
  6. package/components/cell/GridCell.js +4 -4
  7. package/components/containers/GridRootStyles.js +2 -1
  8. package/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  9. package/hooks/core/useGridInitialization.d.ts +1 -1
  10. package/hooks/core/useGridInitialization.js +3 -0
  11. package/hooks/features/filter/gridFilterUtils.d.ts +9 -25
  12. package/hooks/features/filter/gridFilterUtils.js +61 -27
  13. package/hooks/features/filter/useGridFilter.d.ts +1 -1
  14. package/hooks/features/filter/useGridFilter.js +4 -3
  15. package/index.js +1 -1
  16. package/internals/index.d.ts +1 -0
  17. package/internals/index.js +1 -0
  18. package/internals/utils/computeSlots.js +8 -1
  19. package/legacy/DataGrid/DataGrid.js +6 -0
  20. package/legacy/DataGrid/useDataGridProps.js +1 -0
  21. package/legacy/colDef/gridStringOperators.js +4 -0
  22. package/legacy/components/cell/GridActionsCell.js +21 -12
  23. package/legacy/components/cell/GridCell.js +6 -4
  24. package/legacy/components/containers/GridRootStyles.js +2 -1
  25. package/legacy/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  26. package/legacy/hooks/core/useGridInitialization.js +3 -0
  27. package/legacy/hooks/features/filter/gridFilterUtils.js +47 -21
  28. package/legacy/hooks/features/filter/useGridFilter.js +4 -3
  29. package/legacy/index.js +1 -1
  30. package/legacy/internals/index.js +1 -0
  31. package/legacy/internals/utils/computeSlots.js +8 -1
  32. package/legacy/utils/getPublicApiRef.js +5 -0
  33. package/models/api/gridApiCommon.d.ts +3 -2
  34. package/models/api/gridApiCommunity.d.ts +2 -1
  35. package/models/api/gridCoreApi.d.ts +7 -1
  36. package/models/api/gridFilterApi.d.ts +6 -1
  37. package/models/api/gridLocaleTextApi.d.ts +3 -2
  38. package/models/props/DataGridProps.d.ts +6 -0
  39. package/modern/DataGrid/DataGrid.js +6 -0
  40. package/modern/DataGrid/useDataGridProps.js +1 -0
  41. package/modern/colDef/gridStringOperators.js +5 -1
  42. package/modern/components/cell/GridActionsCell.js +18 -12
  43. package/modern/components/cell/GridCell.js +3 -3
  44. package/modern/components/containers/GridRootStyles.js +2 -1
  45. package/modern/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  46. package/modern/hooks/core/useGridInitialization.js +3 -0
  47. package/modern/hooks/features/filter/gridFilterUtils.js +61 -27
  48. package/modern/hooks/features/filter/useGridFilter.js +4 -3
  49. package/modern/index.js +1 -1
  50. package/modern/internals/index.js +1 -0
  51. package/modern/internals/utils/computeSlots.js +8 -1
  52. package/modern/utils/getPublicApiRef.js +5 -0
  53. package/node/DataGrid/DataGrid.js +6 -0
  54. package/node/DataGrid/useDataGridProps.js +1 -0
  55. package/node/colDef/gridStringOperators.js +5 -1
  56. package/node/components/cell/GridActionsCell.js +18 -12
  57. package/node/components/cell/GridCell.js +3 -3
  58. package/node/components/containers/GridRootStyles.js +2 -1
  59. package/node/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +6 -2
  60. package/node/hooks/core/useGridInitialization.js +3 -0
  61. package/node/hooks/features/filter/gridFilterUtils.js +63 -30
  62. package/node/hooks/features/filter/useGridFilter.js +4 -3
  63. package/node/index.js +1 -1
  64. package/node/internals/index.js +12 -0
  65. package/node/internals/utils/computeSlots.js +8 -1
  66. package/node/utils/getPublicApiRef.js +11 -0
  67. package/package.json +2 -2
  68. package/utils/getPublicApiRef.d.ts +3 -0
  69. package/utils/getPublicApiRef.js +5 -0
@@ -72,6 +72,7 @@ export { isNavigationKey } from '../utils/keyboardUtils';
72
72
  export { clamp, isDeepEqual, isNumber, isFunction, isObject } from '../utils/utils';
73
73
  export { buildWarning } from '../utils/warning';
74
74
  export { exportAs } from '../utils/exportAs';
75
+ export * from '../utils/getPublicApiRef';
75
76
  export type { GridPrivateOnlyApiCommon } from '../models/api/gridApiCommon';
76
77
  export { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
77
78
  export * from '../hooks/utils/useOnMount';
@@ -59,6 +59,7 @@ export { isNavigationKey } from '../utils/keyboardUtils';
59
59
  export { clamp, isDeepEqual, isNumber, isFunction, isObject } from '../utils/utils';
60
60
  export { buildWarning } from '../utils/warning';
61
61
  export { exportAs } from '../utils/exportAs';
62
+ export * from '../utils/getPublicApiRef';
62
63
  export { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
63
64
  export * from '../hooks/utils/useOnMount';
64
65
  export { serializeCellValue } from '../hooks/features/export/serializers/csvSerializer';
@@ -13,5 +13,12 @@ export function computeSlots({
13
13
  if (!overrides || Object.keys(overrides).length === 0) {
14
14
  return defaultSlots;
15
15
  }
16
- return _extends({}, defaultSlots, overrides);
16
+ const result = _extends({}, defaultSlots);
17
+ Object.keys(overrides).forEach(key => {
18
+ const k = key;
19
+ if (overrides[k] !== undefined) {
20
+ result[k] = overrides[k];
21
+ }
22
+ });
23
+ return result;
17
24
  }
@@ -280,6 +280,12 @@ DataGridRaw.propTypes = {
280
280
  * @default false
281
281
  */
282
282
  hideFooterSelectedRowCount: PropTypes.bool,
283
+ /**
284
+ * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
285
+ * E.g. when filter value is `cafe`, the rows with `café` will be visible.
286
+ * @default false
287
+ */
288
+ ignoreDiacritics: PropTypes.bool,
283
289
  /**
284
290
  * The initial state of the DataGrid.
285
291
  * The data in it will be set in the state on initialization but will not be controlled.
@@ -52,6 +52,7 @@ export var DATA_GRID_PROPS_DEFAULT_VALUES = {
52
52
  hideFooterPagination: false,
53
53
  hideFooterRowCount: false,
54
54
  hideFooterSelectedRowCount: false,
55
+ ignoreDiacritics: false,
55
56
  logger: console,
56
57
  logLevel: process.env.NODE_ENV === 'production' ? 'error' : 'warn',
57
58
  pagination: false,
@@ -2,6 +2,7 @@ import { GridFilterInputValue } from '../components/panel/filterPanel/GridFilter
2
2
  import { escapeRegExp } from '../utils/utils';
3
3
  import { GridFilterInputMultipleValue } from '../components/panel/filterPanel/GridFilterInputMultipleValue';
4
4
  import { convertLegacyOperators, tagInternalFilter } from './utils';
5
+ import { removeDiacritics } from '../hooks/features/filter/gridFilterUtils';
5
6
  export var getGridStringQuickFilterFn = tagInternalFilter(function (value) {
6
7
  if (!value) {
7
8
  return null;
@@ -9,6 +10,9 @@ export var getGridStringQuickFilterFn = tagInternalFilter(function (value) {
9
10
  var filterRegex = new RegExp(escapeRegExp(value), 'i');
10
11
  return function (_, row, column, apiRef) {
11
12
  var columnValue = apiRef.current.getRowFormattedValue(row, column);
13
+ if (apiRef.current.ignoreDiacritics) {
14
+ columnValue = removeDiacritics(columnValue);
15
+ }
12
16
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
13
17
  };
14
18
  });
@@ -97,11 +97,15 @@ function GridActionsCell(props) {
97
97
  focus: function focus() {
98
98
  // If ignoreCallToFocus is true, then one of the buttons was clicked and the focus is already set
99
99
  if (!ignoreCallToFocus.current) {
100
- setFocusedButtonIndex(0);
100
+ // find the first focusable button and pass the index to the state
101
+ var focusableButtonIndex = options.findIndex(function (o) {
102
+ return !o.props.disabled;
103
+ });
104
+ setFocusedButtonIndex(focusableButtonIndex);
101
105
  }
102
106
  }
103
107
  };
104
- }, []);
108
+ }, [options]);
105
109
  React.useEffect(function () {
106
110
  if (focusedButtonIndex >= numberOfButtons) {
107
111
  setFocusedButtonIndex(numberOfButtons - 1);
@@ -133,19 +137,24 @@ function GridActionsCell(props) {
133
137
  if (numberOfButtons <= 1) {
134
138
  return;
135
139
  }
140
+ var getNewIndex = function getNewIndex(index, direction) {
141
+ var _options;
142
+ if (index < 0 || index > options.length) {
143
+ return index;
144
+ }
145
+
146
+ // for rtl mode we need to reverse the direction
147
+ var rtlMod = theme.direction === 'rtl' ? -1 : 1;
148
+ var indexMod = (direction === 'left' ? -1 : 1) * rtlMod;
149
+
150
+ // if the button that should receive focus is disabled go one more step
151
+ return (_options = options[index + indexMod]) != null && _options.props.disabled ? getNewIndex(index + indexMod, direction) : index + indexMod;
152
+ };
136
153
  var newIndex = focusedButtonIndex;
137
154
  if (event.key === 'ArrowRight') {
138
- if (theme.direction === 'rtl') {
139
- newIndex -= 1;
140
- } else {
141
- newIndex += 1;
142
- }
155
+ newIndex = getNewIndex(focusedButtonIndex, 'right');
143
156
  } else if (event.key === 'ArrowLeft') {
144
- if (theme.direction === 'rtl') {
145
- newIndex += 1;
146
- } else {
147
- newIndex -= 1;
148
- }
157
+ newIndex = getNewIndex(focusedButtonIndex, 'left');
149
158
  }
150
159
  if (newIndex < 0 || newIndex >= numberOfButtons) {
151
160
  return; // We're already in the first or last item = do nothing and let the grid listen the event
@@ -387,7 +387,7 @@ process.env.NODE_ENV !== "production" ? GridCell.propTypes = {
387
387
  } : void 0;
388
388
  export { MemoizedCellWrapper as GridCellWrapper, GridCell };
389
389
  var GridCellV7 = /*#__PURE__*/React.forwardRef(function (props, ref) {
390
- var _rootProps$unstable_c, _rootProps$experiment3, _rootProps$experiment4;
390
+ var _getActions, _ref, _rootProps$unstable_c, _rootProps$experiment3, _rootProps$experiment4;
391
391
  var column = props.column,
392
392
  rowId = props.rowId,
393
393
  editCellState = props.editCellState,
@@ -443,8 +443,10 @@ var GridCellV7 = /*#__PURE__*/React.forwardRef(function (props, ref) {
443
443
  isEditable = cellParamsWithAPI.isEditable,
444
444
  value = cellParamsWithAPI.value,
445
445
  formattedValue = cellParamsWithAPI.formattedValue;
446
- var managesOwnFocus = column.type === 'actions';
447
- var tabIndex = (cellMode === 'view' || !isEditable) && !managesOwnFocus ? cellParamsWithAPI.tabIndex : -1;
446
+ var canManageOwnFocus = column.type === 'actions' && ((_getActions = (_ref = column).getActions) == null ? void 0 : _getActions.call(_ref, apiRef.current.getRowParams(rowId)).some(function (action) {
447
+ return !action.props.disabled;
448
+ }));
449
+ var tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParamsWithAPI.tabIndex : -1;
448
450
  var rootClasses = rootProps.classes,
449
451
  getCellClassName = rootProps.getCellClassName;
450
452
  var classNames = apiRef.current.unstable_applyPipeProcessors('cellClassName', [], {
@@ -588,7 +590,7 @@ var GridCellV7 = /*#__PURE__*/React.forwardRef(function (props, ref) {
588
590
  children: valueString
589
591
  });
590
592
  }
591
- if ( /*#__PURE__*/React.isValidElement(children) && managesOwnFocus) {
593
+ if ( /*#__PURE__*/React.isValidElement(children) && canManageOwnFocus) {
592
594
  children = /*#__PURE__*/React.cloneElement(children, {
593
595
  focusElementRef: focusElementRef
594
596
  });
@@ -64,7 +64,8 @@ export var GridRootStyles = styled('div', {
64
64
  })), _defineProperty(_extends2, "&.".concat(gridClasses.autosizing), (_$concat2 = {}, _defineProperty(_$concat2, "& .".concat(gridClasses.columnHeaderTitleContainerContent, " > *"), {
65
65
  overflow: 'visible !important'
66
66
  }), _defineProperty(_$concat2, "& .".concat(gridClasses.cell, " > *"), {
67
- overflow: 'visible !important'
67
+ overflow: 'visible !important',
68
+ whiteSpace: 'nowrap'
68
69
  }), _$concat2)), _defineProperty(_extends2, "& .".concat(gridClasses['virtualScrollerContent--overflowed'], " .").concat(gridClasses['row--lastVisible'], " .").concat(gridClasses.cell), {
69
70
  borderBottomColor: 'transparent'
70
71
  }), _defineProperty(_extends2, "& .".concat(gridClasses.columnHeader, ", & .").concat(gridClasses.cell), {
@@ -36,6 +36,10 @@ function GridColumnMenuSortItem(props) {
36
36
  })) {
37
37
  return null;
38
38
  }
39
+ var getLabel = function getLabel(key) {
40
+ var label = apiRef.current.getLocaleText(key);
41
+ return typeof label === 'function' ? label(colDef) : label;
42
+ };
39
43
  return /*#__PURE__*/_jsxs(React.Fragment, {
40
44
  children: [sortingOrder.includes('asc') && sortDirection !== 'asc' ? /*#__PURE__*/_jsxs(MenuItem, {
41
45
  onClick: onSortMenuItemClick,
@@ -45,7 +49,7 @@ function GridColumnMenuSortItem(props) {
45
49
  fontSize: "small"
46
50
  })
47
51
  }), /*#__PURE__*/_jsx(ListItemText, {
48
- children: apiRef.current.getLocaleText('columnMenuSortAsc')
52
+ children: getLabel('columnMenuSortAsc')
49
53
  })]
50
54
  }) : null, sortingOrder.includes('desc') && sortDirection !== 'desc' ? /*#__PURE__*/_jsxs(MenuItem, {
51
55
  onClick: onSortMenuItemClick,
@@ -55,7 +59,7 @@ function GridColumnMenuSortItem(props) {
55
59
  fontSize: "small"
56
60
  })
57
61
  }), /*#__PURE__*/_jsx(ListItemText, {
58
- children: apiRef.current.getLocaleText('columnMenuSortDesc')
62
+ children: getLabel('columnMenuSortDesc')
59
63
  })]
60
64
  }) : null, sortingOrder.includes(null) && sortDirection != null ? /*#__PURE__*/_jsxs(MenuItem, {
61
65
  onClick: onSortMenuItemClick,
@@ -15,5 +15,8 @@ export var useGridInitialization = function useGridInitialization(inputApiRef, p
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
  };
@@ -3,6 +3,7 @@ import { GridLogicOperator } from '../../../models';
3
3
  import { GLOBAL_API_REF, isInternalFilter } from '../../../colDef/utils';
4
4
  import { getDefaultGridFilterModel } from './gridFilterState';
5
5
  import { buildWarning } from '../../../utils/warning';
6
+ import { getPublicApiRef } from '../../../utils/getPublicApiRef';
6
7
  import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from '../columns';
7
8
 
8
9
  // Fixes https://github.com/mui/mui-x/issues/10056
@@ -17,7 +18,7 @@ try {
17
18
  /**
18
19
  * Adds default values to the optional fields of a filter items.
19
20
  * @param {GridFilterItem} item The raw filter item.
20
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
21
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
21
22
  * @return {GridFilterItem} The clean filter item with an uniq ID and an always-defined operator.
22
23
  * TODO: Make the typing reflect the different between GridFilterInputItem and GridFilterItem.
23
24
  */
@@ -79,6 +80,12 @@ export var mergeStateWithFilterModel = function mergeStateWithFilterModel(filter
79
80
  });
80
81
  };
81
82
  };
83
+ export var removeDiacritics = function removeDiacritics(value) {
84
+ if (typeof value === 'string') {
85
+ return value.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
86
+ }
87
+ return value;
88
+ };
82
89
  var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, apiRef) {
83
90
  if (!filterItem.field || !filterItem.operator) {
84
91
  return null;
@@ -97,6 +104,10 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
97
104
  } else {
98
105
  parsedValue = filterItem.value;
99
106
  }
107
+ var ignoreDiacritics = apiRef.current.rootProps.ignoreDiacritics;
108
+ if (ignoreDiacritics) {
109
+ parsedValue = removeDiacritics(parsedValue);
110
+ }
100
111
  var newFilterItem = _extends({}, filterItem, {
101
112
  value: parsedValue
102
113
  });
@@ -112,6 +123,7 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
112
123
  }
113
124
  var hasUserFunctionLegacy = !isInternalFilter(filterOperator.getApplyFilterFn);
114
125
  var hasUserFunctionV7 = !isInternalFilter(filterOperator.getApplyFilterFnV7);
126
+ var publicApiRef = getPublicApiRef(apiRef);
115
127
  if (filterOperator.getApplyFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
116
128
  var _applyFilterOnRow = filterOperator.getApplyFilterFnV7(newFilterItem, column);
117
129
  if (typeof _applyFilterOnRow !== 'function') {
@@ -122,7 +134,10 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
122
134
  item: newFilterItem,
123
135
  fn: function fn(row) {
124
136
  var value = apiRef.current.getRowValue(row, column);
125
- return _applyFilterOnRow(value, row, column, apiRef);
137
+ if (ignoreDiacritics) {
138
+ value = removeDiacritics(value);
139
+ }
140
+ return _applyFilterOnRow(value, row, column, publicApiRef);
126
141
  }
127
142
  };
128
143
  }
@@ -135,7 +150,10 @@ var getFilterCallbackFromItem = function getFilterCallbackFromItem(filterItem, a
135
150
  item: newFilterItem,
136
151
  fn: function fn(rowId) {
137
152
  var params = apiRef.current.getCellParams(rowId, newFilterItem.field);
138
- GLOBAL_API_REF.current = apiRef;
153
+ GLOBAL_API_REF.current = publicApiRef;
154
+ if (ignoreDiacritics) {
155
+ params.value = removeDiacritics(params.value);
156
+ }
139
157
  var result = applyFilterOnRow(params);
140
158
  GLOBAL_API_REF.current = null;
141
159
  return result;
@@ -146,12 +164,11 @@ var filterItemsApplierId = 1;
146
164
 
147
165
  /**
148
166
  * 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
167
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
151
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
168
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
152
169
  * @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
170
  */
154
- export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval) {
171
+ var buildAggregatedFilterItemsApplier = function buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval) {
155
172
  var items = filterModel.items;
156
173
  var appliers = items.map(function (item) {
157
174
  return getFilterCallbackFromItem(item, apiRef);
@@ -168,7 +185,7 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
168
185
  for (var i = 0; i < appliers.length; i += 1) {
169
186
  var applier = appliers[i];
170
187
  if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
171
- resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
188
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(apiRef.current.getRowId(row));
172
189
  }
173
190
  }
174
191
  return resultPerItemId;
@@ -180,11 +197,11 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
180
197
  var filterItemTemplate = "(function filterItem$$(getRowId, appliers, row, shouldApplyFilter) {\n ".concat(appliers.map(function (applier, i) {
181
198
  return "const shouldApply".concat(i, " = !shouldApplyFilter || shouldApplyFilter(").concat(JSON.stringify(applier.item.field), ");");
182
199
  }).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 ");
200
+ 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
201
  }).join('\n'), "};\n\n return result$$;\n })");
185
202
  var filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
186
203
  var filterItem = function filterItem(row, shouldApplyItem) {
187
- return filterItemCore(getRowId, appliers, row, shouldApplyItem);
204
+ return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
188
205
  };
189
206
  filterItemsApplierId += 1;
190
207
  return filterItem;
@@ -192,12 +209,11 @@ export var buildAggregatedFilterItemsApplier = function buildAggregatedFilterIte
192
209
 
193
210
  /**
194
211
  * 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
212
  * @param {any[]} filterModel The model with which we want to filter the rows.
197
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
213
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
198
214
  * @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
215
  */
200
- export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef) {
216
+ var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilterApplier(filterModel, apiRef) {
201
217
  var _filterModel$quickFil, _filterModel$quickFil2, _filterModel$quickFil3;
202
218
  var quickFilterValues = (_filterModel$quickFil = (_filterModel$quickFil2 = filterModel.quickFilterValues) == null ? void 0 : _filterModel$quickFil2.filter(Boolean)) != null ? _filterModel$quickFil : [];
203
219
  if (quickFilterValues.length === 0) {
@@ -206,6 +222,8 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
206
222
  var quickFilterExcludeHiddenColumns = (_filterModel$quickFil3 = filterModel.quickFilterExcludeHiddenColumns) != null ? _filterModel$quickFil3 : false;
207
223
  var columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
208
224
  var appliersPerField = [];
225
+ var ignoreDiacritics = apiRef.current.rootProps.ignoreDiacritics;
226
+ var publicApiRef = getPublicApiRef(apiRef);
209
227
  columnFields.forEach(function (field) {
210
228
  var column = apiRef.current.getColumn(field);
211
229
  var getApplyQuickFilterFn = column == null ? void 0 : column.getApplyQuickFilterFn;
@@ -215,20 +233,22 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
215
233
  if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
216
234
  appliersPerField.push({
217
235
  column: column,
218
- appliers: quickFilterValues.map(function (value) {
236
+ appliers: quickFilterValues.map(function (quickFilterValue) {
237
+ var value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
219
238
  return {
220
239
  v7: true,
221
- fn: getApplyQuickFilterFnV7(value, column, apiRef)
240
+ fn: getApplyQuickFilterFnV7(value, column, publicApiRef)
222
241
  };
223
242
  })
224
243
  });
225
244
  } else if (getApplyQuickFilterFn) {
226
245
  appliersPerField.push({
227
246
  column: column,
228
- appliers: quickFilterValues.map(function (value) {
247
+ appliers: quickFilterValues.map(function (quickFilterValue) {
248
+ var value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
229
249
  return {
230
250
  v7: false,
231
- fn: getApplyQuickFilterFn(value, column, apiRef)
251
+ fn: getApplyQuickFilterFn(value, column, publicApiRef)
232
252
  };
233
253
  })
234
254
  });
@@ -255,14 +275,20 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
255
275
  continue;
256
276
  }
257
277
  if (applier.v7) {
258
- var isMatching = applier.fn(value, row, column, apiRef);
278
+ if (ignoreDiacritics) {
279
+ value = removeDiacritics(value);
280
+ }
281
+ var isMatching = applier.fn(value, row, column, publicApiRef);
259
282
  if (isMatching) {
260
283
  result[filterValue] = true;
261
284
  continue outer;
262
285
  }
263
286
  } else {
264
287
  var _usedCellParams$_fiel;
265
- var cellParams = (_usedCellParams$_fiel = usedCellParams[_field]) != null ? _usedCellParams$_fiel : apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, _field);
288
+ var cellParams = (_usedCellParams$_fiel = usedCellParams[_field]) != null ? _usedCellParams$_fiel : apiRef.current.getCellParams(apiRef.current.getRowId(row), _field);
289
+ if (ignoreDiacritics) {
290
+ cellParams.value = removeDiacritics(cellParams.value);
291
+ }
266
292
  usedCellParams[_field] = cellParams;
267
293
  var _isMatching = applier.fn(cellParams);
268
294
  if (_isMatching) {
@@ -278,9 +304,9 @@ export var buildAggregatedQuickFilterApplier = function buildAggregatedQuickFilt
278
304
  return result;
279
305
  };
280
306
  };
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);
307
+ export var buildAggregatedFilterApplier = function buildAggregatedFilterApplier(filterModel, apiRef, disableEval) {
308
+ var isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval);
309
+ var isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
284
310
  return function isRowMatchingFilters(row, shouldApplyFilter, result) {
285
311
  var _isRowMatchingFilterI, _isRowMatchingQuickFi;
286
312
  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;
@@ -226,7 +226,8 @@ export var useGridFilter = function useGridFilter(apiRef, props) {
226
226
  setFilterModel: setFilterModel,
227
227
  showFilterPanel: showFilterPanel,
228
228
  hideFilterPanel: hideFilterPanel,
229
- setQuickFilterValues: setQuickFilterValues
229
+ setQuickFilterValues: setQuickFilterValues,
230
+ ignoreDiacritics: props.ignoreDiacritics
230
231
  };
231
232
  useGridApiMethod(apiRef, filterApi, 'public');
232
233
 
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.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -59,6 +59,7 @@ export { isNavigationKey } from '../utils/keyboardUtils';
59
59
  export { clamp, isDeepEqual, isNumber, isFunction, isObject } from '../utils/utils';
60
60
  export { buildWarning } from '../utils/warning';
61
61
  export { exportAs } from '../utils/exportAs';
62
+ export * from '../utils/getPublicApiRef';
62
63
  export { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
63
64
  export * from '../hooks/utils/useOnMount';
64
65
  export { serializeCellValue } from '../hooks/features/export/serializers/csvSerializer';
@@ -12,5 +12,12 @@ export function computeSlots(_ref) {
12
12
  if (!overrides || Object.keys(overrides).length === 0) {
13
13
  return defaultSlots;
14
14
  }
15
- return _extends({}, defaultSlots, overrides);
15
+ var result = _extends({}, defaultSlots);
16
+ Object.keys(overrides).forEach(function (key) {
17
+ var k = key;
18
+ if (overrides[k] !== undefined) {
19
+ result[k] = overrides[k];
20
+ }
21
+ });
22
+ return result;
16
23
  }
@@ -0,0 +1,5 @@
1
+ export function getPublicApiRef(apiRef) {
2
+ return {
3
+ current: apiRef.current.getPublicApi()
4
+ };
5
+ }
@@ -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
  */
@@ -1,6 +1,7 @@
1
1
  import { GridFilterModel } from '../gridFilterModel';
2
2
  import { GridFilterItem, GridLogicOperator } from '../gridFilterItem';
3
3
  import { GridControlledStateReasonLookup } from '../events';
4
+ import { DataGridProcessedProps } from '../props/DataGridProps';
4
5
  /**
5
6
  * The filter API interface that is available in the grid [[apiRef]].
6
7
  */
@@ -48,8 +49,12 @@ export interface GridFilterApi {
48
49
  */
49
50
  setFilterModel: (model: GridFilterModel, reason?: GridControlledStateReasonLookup['filter']) => void;
50
51
  /**
51
- * Set the quick filter values ot the one given by `values`
52
+ * Set the quick filter values to the one given by `values`
52
53
  * @param {any[]} values The list of element to quick filter
53
54
  */
54
55
  setQuickFilterValues: (values: any[]) => void;
56
+ /**
57
+ * Returns the value of the `ignoreDiacritics` prop.
58
+ */
59
+ ignoreDiacritics: DataGridProcessedProps['ignoreDiacritics'];
55
60
  }
@@ -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,
@@ -2,13 +2,17 @@ import { GridFilterInputValue } from '../components/panel/filterPanel/GridFilter
2
2
  import { escapeRegExp } from '../utils/utils';
3
3
  import { GridFilterInputMultipleValue } from '../components/panel/filterPanel/GridFilterInputMultipleValue';
4
4
  import { convertLegacyOperators, tagInternalFilter } from './utils';
5
+ import { removeDiacritics } from '../hooks/features/filter/gridFilterUtils';
5
6
  export const getGridStringQuickFilterFn = tagInternalFilter(value => {
6
7
  if (!value) {
7
8
  return null;
8
9
  }
9
10
  const filterRegex = new RegExp(escapeRegExp(value), 'i');
10
11
  return (_, row, column, apiRef) => {
11
- const columnValue = apiRef.current.getRowFormattedValue(row, column);
12
+ let columnValue = apiRef.current.getRowFormattedValue(row, column);
13
+ if (apiRef.current.ignoreDiacritics) {
14
+ columnValue = removeDiacritics(columnValue);
15
+ }
12
16
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
13
17
  };
14
18
  });