@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
package/CHANGELOG.md CHANGED
@@ -3,6 +3,133 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 6.18.0
7
+
8
+ _Nov 3, 2023_
9
+
10
+ We'd like to offer a big thanks to the 7 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 🎁 The Charts package is now officially stable!
13
+ - 🥧 Pie charts are now animated.
14
+ - 📈 Line charts now support partial data, and can interpolate missing data.
15
+
16
+ <img width="380" alt="line charts with partial data" src="https://github.com/mui/mui-x/assets/45398769/385ecf77-19b2-4a03-8aef-5d547db1d9ad">
17
+
18
+ - ✨ Allow to ignore [diacritics](https://en.wikipedia.org/wiki/Diacritic) when filtering
19
+ - 📚 Documentation improvements
20
+
21
+ ### Data Grid
22
+
23
+ #### `@mui/x-data-grid@6.18.0`
24
+
25
+ - [DataGrid] Allow to ignore [diacritics](https://en.wikipedia.org/wiki/Diacritic) when filtering (#10569) @cherniavskii
26
+ - [DataGrid] Fix a typo in `gridFilterApi` (#10786) @vu-dao-93
27
+ - [DataGrid] Fix `undefined` row id (#10670) @romgrk
28
+ - [DataGrid] Make column autosizing work with dynamic row height (#10693) @cherniavskii
29
+ - [l10n] Allow to customize sorting label per column (#10839) @JerryWu1234
30
+
31
+ #### `@mui/x-data-grid-pro@6.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
32
+
33
+ Same changes as in `@mui/x-data-grid@6.18.0`.
34
+
35
+ #### `@mui/x-data-grid-premium@6.18.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
36
+
37
+ Same changes as in `@mui/x-data-grid-pro@6.18.0`.
38
+
39
+ ### Date Pickers
40
+
41
+ #### `@mui/x-date-pickers@6.18.0`
42
+
43
+ - [pickers] Add reference links to calendar components (#10644) @michelengelen
44
+
45
+ #### `@mui/x-date-pickers-pro@6.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
46
+
47
+ Same changes as in `@mui/x-date-pickers@6.18.0`.
48
+
49
+ ### Charts / `@mui/x-charts@6.18.0`
50
+
51
+ - [charts] Add animation on pie chart (#10782) @alexfauquette
52
+ - [charts] Add reference links to shared/misc chart components (#10660) @michelengelen
53
+ - [charts] Allows to connect nulls (#10803) @alexfauquette
54
+ - [charts] Fix axis highlight in dark mode (#10820) @LukasTy
55
+
56
+ ### Docs
57
+
58
+ - [docs] Add a data grid recipe for autosizing columns after fetching row-data (#10822) @michelengelen
59
+ - [docs] Add a data grid recipe showing how to remove cell outline on `focus` (#10843) @michelengelen
60
+ - [docs] Add demo about how to use charts margin (#10886) @alexfauquette
61
+ - [docs] Improve custom field input demos readability (#10559) @LukasTy
62
+
63
+ ### Core
64
+
65
+ - [core] Generate `slot` API descriptions based on `slots` or `components` (#10879) @LukasTy
66
+
67
+ ## 6.17.0
68
+
69
+ _Oct 27, 2023_
70
+
71
+ We'd like to offer a big thanks to the 9 contributors who made this release possible. Here are some highlights ✨:
72
+
73
+ - 🎁 The Tree View package is now officially stable!
74
+
75
+ ![tree-view-example](https://github.com/mui/mui-x/assets/550141/77d1fe66-d912-49ba-b38f-b853fb90446a)
76
+
77
+ - ✨ Improve the handling of non-numeric values by Data Grid aggregation
78
+ - 🚀 Support lines with different domains on the line charts
79
+ - 🐞 Bugfixes
80
+ - 📚 Documentation improvements
81
+
82
+ ### Data Grid
83
+
84
+ #### `@mui/x-data-grid@6.17.0`
85
+
86
+ - [DataGrid] Allow custom debounce time for row positions calculation (#10708) @cherniavskii
87
+ - [DataGrid] Persist stable row index for focused row (#10674) @cherniavskii
88
+
89
+ #### `@mui/x-data-grid-pro@6.17.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
90
+
91
+ Same changes as in `@mui/x-data-grid@6.17.0`, plus:
92
+
93
+ - [DataGridPro] Fix `undefined` values passed to `valueFormatter` for tree leaf nodes (#10748) @cherniavskii
94
+
95
+ #### `@mui/x-data-grid-premium@6.17.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
96
+
97
+ Same changes as in `@mui/x-data-grid-pro@6.17.0`, plus:
98
+
99
+ - [DataGridPremium] Fix `avg` aggregation to ignore non-numeric values (#10787) @cherniavskii
100
+ - [DataGridPremium] Fix `size` aggregation to ignore `undefined` values (#10745) @cherniavskii
101
+ - [DataGridPremium] Fix `sum` aggregation to ignore non-numeric values (#10730) @cherniavskii
102
+ - [DataGridPremium] Fix cell selection throwing index error on second page and beyond (#10784) @MBilalShafi
103
+
104
+ ### Date Pickers
105
+
106
+ #### `@mui/x-date-pickers@6.17.0`
107
+
108
+ - [fields] POC: Use `contentEditable` on `FakeTextField` (#10779) @flaviendelangle
109
+ - [pickers] Fix weekday label localization (#10809) @LukasTy
110
+
111
+ #### `@mui/x-date-pickers-pro@6.17.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
112
+
113
+ Same changes as in `@mui/x-date-pickers@6.17.0`.
114
+
115
+ ### Charts / `@mui/x-charts@6.0.0-alpha.17`
116
+
117
+ - [charts] Fix text position in Safari (#10815) @lhilgert9
118
+ - [charts] Support lines with different domains (#10801) @alexfauquette
119
+
120
+ ### Tree View / `@mui/x-tree-view@6.17.0`
121
+
122
+ No change
123
+
124
+ ### Docs
125
+
126
+ - [docs] Correct editing related props' description (#10798) @MBilalShafi
127
+ - [docs] Fix RTL data grid demo (#10728) @oliviertassinari
128
+ - [docs] Fix unclosed warning (#10796) @flaviendelangle
129
+ - [docs] Improve performance of `Save and restore the state from external storage` recipe (#10811) @michelengelen
130
+
131
+ - [test] Add missing type on `cleanText` utility function (#10780) @flaviendelangle
132
+
6
133
  ## 6.16.3
7
134
 
8
135
  _Oct 20, 2023_
@@ -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.
@@ -596,6 +602,13 @@ DataGridRaw.propTypes = {
596
602
  * Controls the modes of the rows.
597
603
  */
598
604
  rowModesModel: PropTypes.object,
605
+ /**
606
+ * The milliseconds delay to wait after measuring the row height before recalculating row positions.
607
+ * Setting it to a lower value could be useful when using dynamic row height,
608
+ * but might reduce performance when displaying a large number of rows.
609
+ * @default 166
610
+ */
611
+ rowPositionsDebounceMs: PropTypes.number,
599
612
  /**
600
613
  * Set of rows of type [[GridRowsProp]].
601
614
  */
@@ -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,
@@ -68,7 +69,8 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES = {
68
69
  keepNonExistentRowsSelected: false,
69
70
  keepColumnPositionIfDraggedOutside: false,
70
71
  unstable_ignoreValueFormatterDuringExport: false,
71
- clipboardCopyCellDelimiter: '\t'
72
+ clipboardCopyCellDelimiter: '\t',
73
+ rowPositionsDebounceMs: 166
72
74
  };
73
75
  const defaultSlots = uncapitalizeObjectKeys(DATA_GRID_DEFAULT_SLOTS_COMPONENTS);
74
76
  export const useDataGridProps = inProps => {
@@ -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}`]: {
@@ -34,6 +34,10 @@ function GridColumnMenuSortItem(props) {
34
34
  if (!colDef || !colDef.sortable || !sortingOrder.some(item => !!item)) {
35
35
  return null;
36
36
  }
37
+ const getLabel = key => {
38
+ const label = apiRef.current.getLocaleText(key);
39
+ return typeof label === 'function' ? label(colDef) : label;
40
+ };
37
41
  return /*#__PURE__*/_jsxs(React.Fragment, {
38
42
  children: [sortingOrder.includes('asc') && sortDirection !== 'asc' ? /*#__PURE__*/_jsxs(MenuItem, {
39
43
  onClick: onSortMenuItemClick,
@@ -43,7 +47,7 @@ function GridColumnMenuSortItem(props) {
43
47
  fontSize: "small"
44
48
  })
45
49
  }), /*#__PURE__*/_jsx(ListItemText, {
46
- children: apiRef.current.getLocaleText('columnMenuSortAsc')
50
+ children: getLabel('columnMenuSortAsc')
47
51
  })]
48
52
  }) : null, sortingOrder.includes('desc') && sortDirection !== 'desc' ? /*#__PURE__*/_jsxs(MenuItem, {
49
53
  onClick: onSortMenuItemClick,
@@ -53,7 +57,7 @@ function GridColumnMenuSortItem(props) {
53
57
  fontSize: "small"
54
58
  })
55
59
  }), /*#__PURE__*/_jsx(ListItemText, {
56
- children: apiRef.current.getLocaleText('columnMenuSortDesc')
60
+ children: getLabel('columnMenuSortDesc')
57
61
  })]
58
62
  }) : null, sortingOrder.includes(null) && sortDirection != null ? /*#__PURE__*/_jsxs(MenuItem, {
59
63
  onClick: onSortMenuItemClick,
@@ -4,4 +4,4 @@ import { DataGridProcessedProps } from '../../models/props/DataGridProps';
4
4
  /**
5
5
  * Initialize the technical pieces of the DataGrid (logger, state, ...) that any DataGrid implementation needs
6
6
  */
7
- export declare const useGridInitialization: <PrivateApi extends GridPrivateApiCommon, Api extends GridApiCommon<any, any>>(inputApiRef: React.MutableRefObject<Api> | undefined, props: Pick<DataGridProcessedProps, 'signature' | 'logger' | 'logLevel' | 'localeText'>) => React.MutableRefObject<PrivateApi>;
7
+ export declare const useGridInitialization: <PrivateApi extends GridPrivateApiCommon, Api extends GridApiCommon<any, any>>(inputApiRef: React.MutableRefObject<Api> | undefined, props: DataGridProcessedProps) => React.MutableRefObject<PrivateApi>;
@@ -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
  };
@@ -1,38 +1,21 @@
1
1
  import * as React from 'react';
2
- import { GridFilterItem, GridFilterModel, GridRowIdGetter, GridValidRowModel } from '../../../models';
3
- import { GridApiCommunity } from '../../../models/api/gridApiCommunity';
2
+ import { GridFilterItem, GridFilterModel } from '../../../models';
3
+ import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
4
4
  import { GridStateCommunity } from '../../../models/gridStateCommunity';
5
5
  import { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFilterValueResult } from './gridFilterState';
6
- type GridFilterItemApplierNotAggregated = (row: GridValidRowModel, shouldApplyItem?: (field: string) => boolean) => GridFilterItemResult;
7
6
  /**
8
7
  * Adds default values to the optional fields of a filter items.
9
8
  * @param {GridFilterItem} item The raw filter item.
10
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
9
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
11
10
  * @return {GridFilterItem} The clean filter item with an uniq ID and an always-defined operator.
12
11
  * TODO: Make the typing reflect the different between GridFilterInputItem and GridFilterItem.
13
12
  */
14
- export declare const cleanFilterItem: (item: GridFilterItem, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterItem;
15
- export declare const sanitizeFilterModel: (model: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterModel;
16
- export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: React.MutableRefObject<GridApiCommunity>) => (filteringState: GridStateCommunity['filter']) => GridStateCommunity['filter'];
17
- /**
18
- * Generates a method to easily check if a row is matching the current filter model.
19
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
20
- * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
21
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
22
- * @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.
23
- */
24
- export declare const buildAggregatedFilterItemsApplier: (getRowId: GridRowIdGetter | undefined, filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>, disableEval: boolean) => GridFilterItemApplierNotAggregated | null;
25
- /**
26
- * Generates a method to easily check if a row is matching the current quick filter.
27
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
28
- * @param {any[]} filterModel The model with which we want to filter the rows.
29
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
30
- * @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.
31
- */
32
- export declare const buildAggregatedQuickFilterApplier: (getRowId: GridRowIdGetter | undefined, filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterItemApplierNotAggregated | null;
33
- export declare const buildAggregatedFilterApplier: (getRowId: GridRowIdGetter | undefined, filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>, disableEval: boolean) => GridAggregatedFilterItemApplier;
13
+ export declare const cleanFilterItem: (item: GridFilterItem, apiRef: React.MutableRefObject<GridPrivateApiCommunity>) => GridFilterItem;
14
+ export declare const sanitizeFilterModel: (model: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: React.MutableRefObject<GridPrivateApiCommunity>) => GridFilterModel;
15
+ export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: React.MutableRefObject<GridPrivateApiCommunity>) => (filteringState: GridStateCommunity['filter']) => GridStateCommunity['filter'];
16
+ export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridPrivateApiCommunity>, disableEval: boolean) => GridAggregatedFilterItemApplier;
34
17
  type FilterCache = {
35
18
  cleanedFilterItems?: GridFilterItem[];
36
19
  };
37
- export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>, cache: FilterCache) => boolean;
20
+ export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridPrivateApiCommunity>, cache: FilterCache) => boolean;
38
21
  export {};
@@ -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;
@@ -85,6 +91,12 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
85
91
  } else {
86
92
  parsedValue = filterItem.value;
87
93
  }
94
+ const {
95
+ ignoreDiacritics
96
+ } = apiRef.current.rootProps;
97
+ if (ignoreDiacritics) {
98
+ parsedValue = removeDiacritics(parsedValue);
99
+ }
88
100
  const newFilterItem = _extends({}, filterItem, {
89
101
  value: parsedValue
90
102
  });
@@ -107,7 +119,10 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
107
119
  v7: true,
108
120
  item: newFilterItem,
109
121
  fn: row => {
110
- const value = apiRef.current.getRowValue(row, column);
122
+ let value = apiRef.current.getRowValue(row, column);
123
+ if (ignoreDiacritics) {
124
+ value = removeDiacritics(value);
125
+ }
111
126
  return applyFilterOnRow(value, row, column, apiRef);
112
127
  }
113
128
  };
@@ -122,6 +137,9 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
122
137
  fn: rowId => {
123
138
  const params = apiRef.current.getCellParams(rowId, newFilterItem.field);
124
139
  GLOBAL_API_REF.current = apiRef;
140
+ if (ignoreDiacritics) {
141
+ params.value = removeDiacritics(params.value);
142
+ }
125
143
  const result = applyFilterOnRow(params);
126
144
  GLOBAL_API_REF.current = null;
127
145
  return result;
@@ -132,12 +150,11 @@ let filterItemsApplierId = 1;
132
150
 
133
151
  /**
134
152
  * Generates a method to easily check if a row is matching the current filter model.
135
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
136
153
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
137
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
154
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
138
155
  * @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.
139
156
  */
140
- export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef, disableEval) => {
157
+ const buildAggregatedFilterItemsApplier = (filterModel, apiRef, disableEval) => {
141
158
  const {
142
159
  items
143
160
  } = filterModel;
@@ -152,7 +169,7 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
152
169
  for (let i = 0; i < appliers.length; i += 1) {
153
170
  const applier = appliers[i];
154
171
  if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
155
- resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
172
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(apiRef.current.getRowId(row));
156
173
  }
157
174
  }
158
175
  return resultPerItemId;
@@ -168,14 +185,14 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
168
185
  ${appliers.map((applier, i) => `${JSON.stringify(String(applier.item.id))}:
169
186
  !shouldApply${i} ?
170
187
  false :
171
- ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(${getRowId ? 'getRowId(row)' : 'row.id'})`},
188
+ ${applier.v7 ? `appliers[${i}].fn(row)` : `appliers[${i}].fn(getRowId(row))`},
172
189
  `).join('\n')}};
173
190
 
174
191
  return result$$;
175
192
  })`;
176
193
  const filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
177
194
  const filterItem = (row, shouldApplyItem) => {
178
- return filterItemCore(getRowId, appliers, row, shouldApplyItem);
195
+ return filterItemCore(apiRef.current.getRowId, appliers, row, shouldApplyItem);
179
196
  };
180
197
  filterItemsApplierId += 1;
181
198
  return filterItem;
@@ -183,12 +200,11 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
183
200
 
184
201
  /**
185
202
  * Generates a method to easily check if a row is matching the current quick filter.
186
- * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
187
203
  * @param {any[]} filterModel The model with which we want to filter the rows.
188
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
204
+ * @param {React.MutableRefObject<GridPrivateApiCommunity>} apiRef The API of the grid.
189
205
  * @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.
190
206
  */
191
- export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
207
+ const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
192
208
  var _filterModel$quickFil, _filterModel$quickFil2, _filterModel$quickFil3;
193
209
  const quickFilterValues = (_filterModel$quickFil = (_filterModel$quickFil2 = filterModel.quickFilterValues) == null ? void 0 : _filterModel$quickFil2.filter(Boolean)) != null ? _filterModel$quickFil : [];
194
210
  if (quickFilterValues.length === 0) {
@@ -197,6 +213,9 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
197
213
  const quickFilterExcludeHiddenColumns = (_filterModel$quickFil3 = filterModel.quickFilterExcludeHiddenColumns) != null ? _filterModel$quickFil3 : false;
198
214
  const columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
199
215
  const appliersPerField = [];
216
+ const {
217
+ ignoreDiacritics
218
+ } = apiRef.current.rootProps;
200
219
  columnFields.forEach(field => {
201
220
  const column = apiRef.current.getColumn(field);
202
221
  const getApplyQuickFilterFn = column == null ? void 0 : column.getApplyQuickFilterFn;
@@ -206,18 +225,24 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
206
225
  if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
207
226
  appliersPerField.push({
208
227
  column,
209
- appliers: quickFilterValues.map(value => ({
210
- v7: true,
211
- fn: getApplyQuickFilterFnV7(value, column, apiRef)
212
- }))
228
+ appliers: quickFilterValues.map(quickFilterValue => {
229
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
230
+ return {
231
+ v7: true,
232
+ fn: getApplyQuickFilterFnV7(value, column, apiRef)
233
+ };
234
+ })
213
235
  });
214
236
  } else if (getApplyQuickFilterFn) {
215
237
  appliersPerField.push({
216
238
  column,
217
- appliers: quickFilterValues.map(value => ({
218
- v7: false,
219
- fn: getApplyQuickFilterFn(value, column, apiRef)
220
- }))
239
+ appliers: quickFilterValues.map(quickFilterValue => {
240
+ const value = ignoreDiacritics ? removeDiacritics(quickFilterValue) : quickFilterValue;
241
+ return {
242
+ v7: false,
243
+ fn: getApplyQuickFilterFn(value, column, apiRef)
244
+ };
245
+ })
221
246
  });
222
247
  }
223
248
  });
@@ -240,11 +265,14 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
240
265
  continue;
241
266
  }
242
267
  const applier = appliers[v];
243
- const value = apiRef.current.getRowValue(row, column);
268
+ let value = apiRef.current.getRowFormattedValue(row, column);
244
269
  if (applier.fn === null) {
245
270
  continue;
246
271
  }
247
272
  if (applier.v7) {
273
+ if (ignoreDiacritics) {
274
+ value = removeDiacritics(value);
275
+ }
248
276
  const isMatching = applier.fn(value, row, column, apiRef);
249
277
  if (isMatching) {
250
278
  result[filterValue] = true;
@@ -252,7 +280,10 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
252
280
  }
253
281
  } else {
254
282
  var _usedCellParams$field;
255
- const cellParams = (_usedCellParams$field = usedCellParams[field]) != null ? _usedCellParams$field : apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, field);
283
+ const cellParams = (_usedCellParams$field = usedCellParams[field]) != null ? _usedCellParams$field : apiRef.current.getCellParams(apiRef.current.getRowId(row), field);
284
+ if (ignoreDiacritics) {
285
+ cellParams.value = removeDiacritics(cellParams.value);
286
+ }
256
287
  usedCellParams[field] = cellParams;
257
288
  const isMatching = applier.fn(cellParams);
258
289
  if (isMatching) {
@@ -268,9 +299,9 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
268
299
  return result;
269
300
  };
270
301
  };
271
- export const buildAggregatedFilterApplier = (getRowId, filterModel, apiRef, disableEval) => {
272
- const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef, disableEval);
273
- const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
302
+ export const buildAggregatedFilterApplier = (filterModel, apiRef, disableEval) => {
303
+ const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef, disableEval);
304
+ const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
274
305
  return function isRowMatchingFilters(row, shouldApplyFilter, result) {
275
306
  var _isRowMatchingFilterI, _isRowMatchingQuickFi;
276
307
  result.passingFilterItems = (_isRowMatchingFilterI = isRowMatchingFilterItems == null ? void 0 : isRowMatchingFilterItems(row, shouldApplyFilter)) != null ? _isRowMatchingFilterI : null;
@@ -61,7 +61,7 @@ export const useGridFilter = (apiRef, props) => {
61
61
  const updateFilteredRows = React.useCallback(() => {
62
62
  apiRef.current.setState(state => {
63
63
  const filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
64
- const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(props.getRowId, filterModel, apiRef, props.disableEval) : null;
64
+ const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(filterModel, apiRef, props.disableEval) : null;
65
65
  const filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
66
66
  isRowMatchingFilters,
67
67
  filterModel: filterModel != null ? filterModel : getDefaultGridFilterModel()
@@ -75,7 +75,7 @@ export const useGridFilter = (apiRef, props) => {
75
75
  });
76
76
  });
77
77
  apiRef.current.publishEvent('filteredRowsSet');
78
- }, [apiRef, props.filterMode, props.getRowId, props.disableEval]);
78
+ }, [apiRef, props.filterMode, props.disableEval]);
79
79
  const addColumnMenuItem = React.useCallback((columnMenuItems, colDef) => {
80
80
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
81
81
  return columnMenuItems;
@@ -7,4 +7,4 @@ export declare const rowsMetaStateInitializer: GridStateInitializer;
7
7
  * @requires useGridPageSize (method)
8
8
  * @requires useGridPage (method)
9
9
  */
10
- export declare const useGridRowsMeta: (apiRef: React.MutableRefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'getRowHeight' | 'getEstimatedRowHeight' | 'getRowSpacing' | 'pagination' | 'paginationMode' | 'rowHeight'>) => void;
10
+ export declare const useGridRowsMeta: (apiRef: React.MutableRefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'getRowHeight' | 'getEstimatedRowHeight' | 'getRowSpacing' | 'pagination' | 'paginationMode' | 'rowHeight' | 'rowPositionsDebounceMs'>) => void;
@@ -179,7 +179,7 @@ export const useGridRowsMeta = (apiRef, props) => {
179
179
  rowsHeightLookup.current[id].needsFirstMeasurement = false;
180
180
  hydrateRowsMeta();
181
181
  }, [hydrateRowsMeta]);
182
- const debouncedHydrateRowsMeta = React.useMemo(() => debounce(hydrateRowsMeta), [hydrateRowsMeta]);
182
+ const debouncedHydrateRowsMeta = React.useMemo(() => debounce(hydrateRowsMeta, props.rowPositionsDebounceMs), [hydrateRowsMeta, props.rowPositionsDebounceMs]);
183
183
  const storeMeasuredRowHeight = React.useCallback((id, height, position) => {
184
184
  if (!rowsHeightLookup.current[id] || !rowsHeightLookup.current[id].autoHeight) {
185
185
  return;
@@ -468,6 +468,7 @@ export const useGridVirtualScroller = props => {
468
468
  rowStyleCache.current = Object.create(null);
469
469
  }
470
470
  const rows = [];
471
+ let isRowWithFocusedCellRendered = false;
471
472
  for (let i = 0; i < renderedRows.length; i += 1) {
472
473
  var _currentPage$range5;
473
474
  const {
@@ -503,6 +504,13 @@ export const useGridVirtualScroller = props => {
503
504
  const style = _extends({}, rowStyle, rootRowStyle);
504
505
  rowStyleCache.current[id] = style;
505
506
  }
507
+ let index = rowIndexOffset + ((currentPage == null || (_currentPage$range5 = currentPage.range) == null ? void 0 : _currentPage$range5.firstRowIndex) || 0) + firstRowToRender + i;
508
+ if (isRowWithFocusedCellNotInRange && (cellFocus == null ? void 0 : cellFocus.id) === id) {
509
+ index = indexOfRowWithFocusedCell;
510
+ isRowWithFocusedCellRendered = true;
511
+ } else if (isRowWithFocusedCellRendered) {
512
+ index -= 1;
513
+ }
506
514
  rows.push( /*#__PURE__*/_jsx(rootProps.slots.row, _extends({
507
515
  row: model,
508
516
  rowId: id,
@@ -516,7 +524,7 @@ export const useGridVirtualScroller = props => {
516
524
  firstColumnToRender: firstColumnToRender,
517
525
  lastColumnToRender: lastColumnToRender,
518
526
  selected: isSelected,
519
- index: rowIndexOffset + ((currentPage == null || (_currentPage$range5 = currentPage.range) == null ? void 0 : _currentPage$range5.firstRowIndex) || 0) + firstRowToRender + i,
527
+ index: index,
520
528
  containerWidth: availableSpace,
521
529
  isLastVisible: lastVisibleRowIndex,
522
530
  position: position
package/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
@@ -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.
@@ -598,6 +604,13 @@ DataGridRaw.propTypes = {
598
604
  * Controls the modes of the rows.
599
605
  */
600
606
  rowModesModel: PropTypes.object,
607
+ /**
608
+ * The milliseconds delay to wait after measuring the row height before recalculating row positions.
609
+ * Setting it to a lower value could be useful when using dynamic row height,
610
+ * but might reduce performance when displaying a large number of rows.
611
+ * @default 166
612
+ */
613
+ rowPositionsDebounceMs: PropTypes.number,
601
614
  /**
602
615
  * Set of rows of type [[GridRowsProp]].
603
616
  */
@@ -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,
@@ -69,7 +70,8 @@ export var DATA_GRID_PROPS_DEFAULT_VALUES = {
69
70
  keepNonExistentRowsSelected: false,
70
71
  keepColumnPositionIfDraggedOutside: false,
71
72
  unstable_ignoreValueFormatterDuringExport: false,
72
- clipboardCopyCellDelimiter: '\t'
73
+ clipboardCopyCellDelimiter: '\t',
74
+ rowPositionsDebounceMs: 166
73
75
  };
74
76
  var defaultSlots = uncapitalizeObjectKeys(DATA_GRID_DEFAULT_SLOTS_COMPONENTS);
75
77
  export var useDataGridProps = function useDataGridProps(inProps) {
@@ -7,8 +7,7 @@ export var getGridStringQuickFilterFn = tagInternalFilter(function (value) {
7
7
  return null;
8
8
  }
9
9
  var filterRegex = new RegExp(escapeRegExp(value), 'i');
10
- return function (_, row, column, apiRef) {
11
- var columnValue = apiRef.current.getRowFormattedValue(row, column);
10
+ return function (columnValue) {
12
11
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
13
12
  };
14
13
  });
@@ -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), {