@mui/x-data-grid 6.9.0 → 6.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +136 -8
  2. package/DataGrid/DataGrid.js +4 -1
  3. package/DataGrid/useDataGridComponent.js +1 -1
  4. package/README.md +1 -1
  5. package/colDef/gridActionsColDef.js +2 -1
  6. package/colDef/gridBooleanColDef.js +1 -0
  7. package/colDef/gridBooleanOperators.js +5 -6
  8. package/colDef/gridCheckboxSelectionColDef.js +1 -0
  9. package/colDef/gridDateColDef.js +2 -0
  10. package/colDef/gridDateOperators.js +14 -19
  11. package/colDef/gridNumericColDef.js +3 -1
  12. package/colDef/gridNumericOperators.d.ts +2 -2
  13. package/colDef/gridNumericOperators.js +24 -43
  14. package/colDef/gridSingleSelectOperators.js +9 -14
  15. package/colDef/gridStringColDef.js +3 -1
  16. package/colDef/gridStringOperators.d.ts +2 -2
  17. package/colDef/gridStringOperators.js +22 -36
  18. package/colDef/utils.d.ts +21 -0
  19. package/colDef/utils.js +51 -0
  20. package/components/GridPagination.js +16 -3
  21. package/components/cell/GridCell.js +1 -1
  22. package/components/cell/GridEditDateCell.js +1 -1
  23. package/components/cell/GridEditInputCell.js +3 -3
  24. package/hooks/features/columns/gridColumnsUtils.js +2 -1
  25. package/hooks/features/dimensions/useGridDimensions.js +2 -2
  26. package/hooks/features/editing/useGridEditing.js +2 -1
  27. package/hooks/features/editing/useGridRowEditing.js +2 -2
  28. package/hooks/features/filter/gridFilterState.d.ts +6 -5
  29. package/hooks/features/filter/gridFilterUtils.d.ts +8 -6
  30. package/hooks/features/filter/gridFilterUtils.js +115 -57
  31. package/hooks/features/filter/useGridFilter.d.ts +1 -1
  32. package/hooks/features/filter/useGridFilter.js +34 -25
  33. package/hooks/features/pagination/gridPaginationSelector.js +10 -5
  34. package/hooks/features/rows/gridRowsUtils.d.ts +1 -0
  35. package/hooks/features/rows/gridRowsUtils.js +1 -0
  36. package/hooks/features/rows/useGridParamsApi.d.ts +2 -1
  37. package/hooks/features/rows/useGridParamsApi.js +31 -1
  38. package/hooks/features/rows/useGridRows.js +4 -3
  39. package/index.js +1 -1
  40. package/internals/index.d.ts +2 -1
  41. package/internals/index.js +1 -0
  42. package/joy/joySlots.js +29 -8
  43. package/legacy/DataGrid/DataGrid.js +4 -1
  44. package/legacy/DataGrid/useDataGridComponent.js +1 -1
  45. package/legacy/colDef/gridActionsColDef.js +2 -1
  46. package/legacy/colDef/gridBooleanColDef.js +1 -0
  47. package/legacy/colDef/gridBooleanOperators.js +5 -5
  48. package/legacy/colDef/gridCheckboxSelectionColDef.js +1 -0
  49. package/legacy/colDef/gridDateColDef.js +2 -0
  50. package/legacy/colDef/gridDateOperators.js +14 -16
  51. package/legacy/colDef/gridNumericColDef.js +3 -1
  52. package/legacy/colDef/gridNumericOperators.js +24 -33
  53. package/legacy/colDef/gridSingleSelectOperators.js +9 -11
  54. package/legacy/colDef/gridStringColDef.js +3 -1
  55. package/legacy/colDef/gridStringOperators.js +22 -28
  56. package/legacy/colDef/utils.js +51 -0
  57. package/legacy/components/GridPagination.js +16 -3
  58. package/legacy/components/cell/GridCell.js +2 -1
  59. package/legacy/components/cell/GridEditDateCell.js +1 -1
  60. package/legacy/components/cell/GridEditInputCell.js +3 -3
  61. package/legacy/hooks/features/columns/gridColumnsUtils.js +4 -1
  62. package/legacy/hooks/features/dimensions/useGridDimensions.js +2 -2
  63. package/legacy/hooks/features/editing/useGridEditing.js +2 -1
  64. package/legacy/hooks/features/editing/useGridRowEditing.js +2 -2
  65. package/legacy/hooks/features/filter/gridFilterUtils.js +115 -65
  66. package/legacy/hooks/features/filter/useGridFilter.js +32 -24
  67. package/legacy/hooks/features/pagination/gridPaginationSelector.js +10 -5
  68. package/legacy/hooks/features/rows/gridRowsUtils.js +1 -0
  69. package/legacy/hooks/features/rows/useGridParamsApi.js +29 -1
  70. package/legacy/hooks/features/rows/useGridRows.js +15 -16
  71. package/legacy/index.js +1 -1
  72. package/legacy/internals/index.js +1 -0
  73. package/legacy/joy/joySlots.js +29 -8
  74. package/legacy/locales/esES.js +3 -3
  75. package/legacy/locales/huHU.js +23 -25
  76. package/legacy/locales/roRO.js +34 -38
  77. package/locales/esES.js +3 -3
  78. package/locales/huHU.js +23 -25
  79. package/locales/roRO.js +34 -38
  80. package/models/api/gridEditingApi.d.ts +1 -1
  81. package/models/api/gridParamsApi.d.ts +22 -1
  82. package/models/colDef/gridColDef.d.ts +13 -1
  83. package/models/gridFilterOperator.d.ts +17 -2
  84. package/models/gridRows.d.ts +1 -1
  85. package/models/props/DataGridProps.d.ts +4 -1
  86. package/modern/DataGrid/DataGrid.js +4 -1
  87. package/modern/DataGrid/useDataGridComponent.js +1 -1
  88. package/modern/colDef/gridActionsColDef.js +2 -1
  89. package/modern/colDef/gridBooleanColDef.js +1 -0
  90. package/modern/colDef/gridBooleanOperators.js +5 -6
  91. package/modern/colDef/gridCheckboxSelectionColDef.js +1 -0
  92. package/modern/colDef/gridDateColDef.js +2 -0
  93. package/modern/colDef/gridDateOperators.js +14 -19
  94. package/modern/colDef/gridNumericColDef.js +3 -1
  95. package/modern/colDef/gridNumericOperators.js +24 -43
  96. package/modern/colDef/gridSingleSelectOperators.js +9 -14
  97. package/modern/colDef/gridStringColDef.js +3 -1
  98. package/modern/colDef/gridStringOperators.js +22 -36
  99. package/modern/colDef/utils.js +51 -0
  100. package/modern/components/GridPagination.js +16 -2
  101. package/modern/components/cell/GridCell.js +1 -1
  102. package/modern/components/cell/GridEditDateCell.js +1 -1
  103. package/modern/components/cell/GridEditInputCell.js +3 -3
  104. package/modern/hooks/features/columns/gridColumnsUtils.js +2 -1
  105. package/modern/hooks/features/dimensions/useGridDimensions.js +2 -2
  106. package/modern/hooks/features/editing/useGridEditing.js +1 -1
  107. package/modern/hooks/features/editing/useGridRowEditing.js +2 -2
  108. package/modern/hooks/features/filter/gridFilterUtils.js +110 -54
  109. package/modern/hooks/features/filter/useGridFilter.js +34 -25
  110. package/modern/hooks/features/pagination/gridPaginationSelector.js +9 -5
  111. package/modern/hooks/features/rows/gridRowsUtils.js +1 -0
  112. package/modern/hooks/features/rows/useGridParamsApi.js +29 -1
  113. package/modern/hooks/features/rows/useGridRows.js +4 -3
  114. package/modern/index.js +1 -1
  115. package/modern/internals/index.js +1 -0
  116. package/modern/joy/joySlots.js +29 -7
  117. package/modern/locales/esES.js +3 -3
  118. package/modern/locales/huHU.js +23 -25
  119. package/modern/locales/roRO.js +34 -38
  120. package/node/DataGrid/DataGrid.js +4 -1
  121. package/node/DataGrid/useDataGridComponent.js +1 -1
  122. package/node/colDef/gridActionsColDef.js +2 -1
  123. package/node/colDef/gridBooleanColDef.js +1 -0
  124. package/node/colDef/gridBooleanOperators.js +5 -6
  125. package/node/colDef/gridCheckboxSelectionColDef.js +1 -0
  126. package/node/colDef/gridDateColDef.js +2 -0
  127. package/node/colDef/gridDateOperators.js +14 -19
  128. package/node/colDef/gridNumericColDef.js +3 -1
  129. package/node/colDef/gridNumericOperators.js +24 -43
  130. package/node/colDef/gridSingleSelectOperators.js +9 -14
  131. package/node/colDef/gridStringColDef.js +3 -1
  132. package/node/colDef/gridStringOperators.js +22 -36
  133. package/node/colDef/utils.js +64 -0
  134. package/node/components/GridPagination.js +16 -2
  135. package/node/components/cell/GridCell.js +1 -1
  136. package/node/components/cell/GridEditDateCell.js +1 -1
  137. package/node/components/cell/GridEditInputCell.js +3 -3
  138. package/node/hooks/features/columns/gridColumnsUtils.js +2 -1
  139. package/node/hooks/features/dimensions/useGridDimensions.js +2 -2
  140. package/node/hooks/features/editing/useGridEditing.js +1 -1
  141. package/node/hooks/features/editing/useGridRowEditing.js +1 -1
  142. package/node/hooks/features/filter/gridFilterUtils.js +110 -54
  143. package/node/hooks/features/filter/useGridFilter.js +33 -24
  144. package/node/hooks/features/pagination/gridPaginationSelector.js +9 -5
  145. package/node/hooks/features/rows/gridRowsUtils.js +3 -1
  146. package/node/hooks/features/rows/useGridParamsApi.js +29 -1
  147. package/node/hooks/features/rows/useGridRows.js +3 -2
  148. package/node/index.js +1 -1
  149. package/node/internals/index.js +13 -1
  150. package/node/joy/joySlots.js +29 -7
  151. package/node/locales/esES.js +3 -3
  152. package/node/locales/huHU.js +23 -25
  153. package/node/locales/roRO.js +34 -38
  154. package/package.json +2 -2
@@ -7,36 +7,34 @@ exports.getGridStringQuickFilterFn = exports.getGridStringOperators = void 0;
7
7
  var _GridFilterInputValue = require("../components/panel/filterPanel/GridFilterInputValue");
8
8
  var _utils = require("../utils/utils");
9
9
  var _GridFilterInputMultipleValue = require("../components/panel/filterPanel/GridFilterInputMultipleValue");
10
- const getGridStringQuickFilterFn = value => {
10
+ var _utils2 = require("./utils");
11
+ const getGridStringQuickFilterFn = (0, _utils2.tagInternalFilter)(value => {
11
12
  if (!value) {
12
13
  return null;
13
14
  }
14
15
  const filterRegex = new RegExp((0, _utils.escapeRegExp)(value), 'i');
15
- return ({
16
- formattedValue: columnValue
17
- }) => {
16
+ return (_, row, column, apiRef) => {
17
+ const columnValue = apiRef.current.getRowFormattedValue(row, column);
18
18
  return columnValue != null ? filterRegex.test(columnValue.toString()) : false;
19
19
  };
20
- };
20
+ });
21
21
  exports.getGridStringQuickFilterFn = getGridStringQuickFilterFn;
22
- const getGridStringOperators = (disableTrim = false) => [{
22
+ const getGridStringOperators = (disableTrim = false) => (0, _utils2.convertLegacyOperators)([{
23
23
  value: 'contains',
24
- getApplyFilterFn: filterItem => {
24
+ getApplyFilterFnV7: filterItem => {
25
25
  if (!filterItem.value) {
26
26
  return null;
27
27
  }
28
28
  const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
29
29
  const filterRegex = new RegExp((0, _utils.escapeRegExp)(filterItemValue), 'i');
30
- return ({
31
- value
32
- }) => {
33
- return value != null ? filterRegex.test(value.toString()) : false;
30
+ return value => {
31
+ return value != null ? filterRegex.test(String(value)) : false;
34
32
  };
35
33
  },
36
34
  InputComponent: _GridFilterInputValue.GridFilterInputValue
37
35
  }, {
38
36
  value: 'equals',
39
- getApplyFilterFn: filterItem => {
37
+ getApplyFilterFnV7: filterItem => {
40
38
  if (!filterItem.value) {
41
39
  return null;
42
40
  }
@@ -45,66 +43,56 @@ const getGridStringOperators = (disableTrim = false) => [{
45
43
  sensitivity: 'base',
46
44
  usage: 'search'
47
45
  });
48
- return ({
49
- value
50
- }) => {
46
+ return value => {
51
47
  return value != null ? collator.compare(filterItemValue, value.toString()) === 0 : false;
52
48
  };
53
49
  },
54
50
  InputComponent: _GridFilterInputValue.GridFilterInputValue
55
51
  }, {
56
52
  value: 'startsWith',
57
- getApplyFilterFn: filterItem => {
53
+ getApplyFilterFnV7: filterItem => {
58
54
  if (!filterItem.value) {
59
55
  return null;
60
56
  }
61
57
  const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
62
58
  const filterRegex = new RegExp(`^${(0, _utils.escapeRegExp)(filterItemValue)}.*$`, 'i');
63
- return ({
64
- value
65
- }) => {
59
+ return value => {
66
60
  return value != null ? filterRegex.test(value.toString()) : false;
67
61
  };
68
62
  },
69
63
  InputComponent: _GridFilterInputValue.GridFilterInputValue
70
64
  }, {
71
65
  value: 'endsWith',
72
- getApplyFilterFn: filterItem => {
66
+ getApplyFilterFnV7: filterItem => {
73
67
  if (!filterItem.value) {
74
68
  return null;
75
69
  }
76
70
  const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
77
71
  const filterRegex = new RegExp(`.*${(0, _utils.escapeRegExp)(filterItemValue)}$`, 'i');
78
- return ({
79
- value
80
- }) => {
72
+ return value => {
81
73
  return value != null ? filterRegex.test(value.toString()) : false;
82
74
  };
83
75
  },
84
76
  InputComponent: _GridFilterInputValue.GridFilterInputValue
85
77
  }, {
86
78
  value: 'isEmpty',
87
- getApplyFilterFn: () => {
88
- return ({
89
- value
90
- }) => {
79
+ getApplyFilterFnV7: () => {
80
+ return value => {
91
81
  return value === '' || value == null;
92
82
  };
93
83
  },
94
84
  requiresFilterValue: false
95
85
  }, {
96
86
  value: 'isNotEmpty',
97
- getApplyFilterFn: () => {
98
- return ({
99
- value
100
- }) => {
87
+ getApplyFilterFnV7: () => {
88
+ return value => {
101
89
  return value !== '' && value != null;
102
90
  };
103
91
  },
104
92
  requiresFilterValue: false
105
93
  }, {
106
94
  value: 'isAnyOf',
107
- getApplyFilterFn: filterItem => {
95
+ getApplyFilterFnV7: filterItem => {
108
96
  if (!Array.isArray(filterItem.value) || filterItem.value.length === 0) {
109
97
  return null;
110
98
  }
@@ -113,12 +101,10 @@ const getGridStringOperators = (disableTrim = false) => [{
113
101
  sensitivity: 'base',
114
102
  usage: 'search'
115
103
  });
116
- return ({
117
- value
118
- }) => value != null ? filterItemValue.some(filterValue => {
104
+ return value => value != null ? filterItemValue.some(filterValue => {
119
105
  return collator.compare(filterValue, value.toString() || '') === 0;
120
106
  }) : false;
121
107
  },
122
108
  InputComponent: _GridFilterInputMultipleValue.GridFilterInputMultipleValue
123
- }];
109
+ }]);
124
110
  exports.getGridStringOperators = getGridStringOperators;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.GLOBAL_API_REF = void 0;
8
+ exports.convertFilterV7ToLegacy = convertFilterV7ToLegacy;
9
+ exports.convertLegacyOperators = convertLegacyOperators;
10
+ exports.convertQuickFilterV7ToLegacy = convertQuickFilterV7ToLegacy;
11
+ exports.isInternalFilter = isInternalFilter;
12
+ exports.tagInternalFilter = tagInternalFilter;
13
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
14
+ /**
15
+ * A global API ref, for v7-to-legacy converter
16
+ */
17
+ const GLOBAL_API_REF = {
18
+ current: null
19
+ };
20
+
21
+ /**
22
+ * A tagger to determine if the filter is internal or custom user-supplied.
23
+ * To be a valid internal filter, the V7 function *must* be defined/redefined at
24
+ * the same time as the legacy one.
25
+ * https://github.com/mui/mui-x/pull/9254#discussion_r1231095551
26
+ */
27
+ exports.GLOBAL_API_REF = GLOBAL_API_REF;
28
+ function tagInternalFilter(fn) {
29
+ fn.isInternal = true;
30
+ return fn;
31
+ }
32
+ function isInternalFilter(fn) {
33
+ return fn !== undefined && fn.isInternal === true;
34
+ }
35
+ function convertFilterV7ToLegacy(fn) {
36
+ return tagInternalFilter((filterItem, column) => {
37
+ const filterFn = fn(filterItem, column);
38
+ if (!filterFn) {
39
+ return filterFn;
40
+ }
41
+ return cellParams => {
42
+ return filterFn(cellParams.value, cellParams.row, column, GLOBAL_API_REF.current);
43
+ };
44
+ });
45
+ }
46
+ function convertLegacyOperators(ops) {
47
+ return ops.map(op => {
48
+ return (0, _extends2.default)({}, op, {
49
+ getApplyFilterFn: convertFilterV7ToLegacy(op.getApplyFilterFnV7),
50
+ getApplyFilterFnV7: tagInternalFilter(op.getApplyFilterFnV7)
51
+ });
52
+ });
53
+ }
54
+ function convertQuickFilterV7ToLegacy(fn) {
55
+ return tagInternalFilter((filterItem, column, apiRef) => {
56
+ const filterFn = fn(filterItem, column, apiRef);
57
+ if (!filterFn) {
58
+ return filterFn;
59
+ }
60
+ return cellParams => {
61
+ return filterFn(cellParams.value, cellParams.row, column, apiRef);
62
+ };
63
+ });
64
+ }
@@ -47,21 +47,35 @@ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(pro
47
47
  const handlePageChange = React.useCallback((_, page) => {
48
48
  apiRef.current.setPage(page);
49
49
  }, [apiRef]);
50
+ const isPageSizeIncludedInPageSizeOptions = pageSize => {
51
+ for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
52
+ const option = rootProps.pageSizeOptions[i];
53
+ if (typeof option === 'number') {
54
+ if (option === pageSize) {
55
+ return true;
56
+ }
57
+ } else if (option.value === pageSize) {
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ };
50
63
  if (process.env.NODE_ENV !== 'production') {
51
64
  // eslint-disable-next-line react-hooks/rules-of-hooks
52
65
  const warnedOnceMissingInPageSizeOptions = React.useRef(false);
53
66
  const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
54
- if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !rootProps.pageSizeOptions.includes(pageSize)) {
67
+ if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
55
68
  console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\``, `Add it to show the pagination select.`].join('\n'));
56
69
  warnedOnceMissingInPageSizeOptions.current = true;
57
70
  }
58
71
  }
72
+ const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
59
73
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridPaginationRoot, (0, _extends2.default)({
60
74
  ref: ref,
61
75
  component: "div",
62
76
  count: rowCount,
63
77
  page: paginationModel.page <= lastPage ? paginationModel.page : lastPage,
64
- rowsPerPageOptions: rootProps.pageSizeOptions?.includes(paginationModel.pageSize) ? rootProps.pageSizeOptions : [],
78
+ rowsPerPageOptions: pageSizeOptions,
65
79
  rowsPerPage: paginationModel.pageSize,
66
80
  onPageChange: handlePageChange,
67
81
  onRowsPerPageChange: handlePageSizeChange
@@ -22,7 +22,7 @@ var _gridFocusStateSelector = require("../../hooks/features/focus/gridFocusState
22
22
  var _useGridParamsApi = require("../../hooks/features/rows/useGridParamsApi");
23
23
  var _jsxRuntime = require("react/jsx-runtime");
24
24
  const _excluded = ["changeReason", "unstable_updateValueOnRender"],
25
- _excluded2 = ["align", "children", "colIndex", "column", "cellMode", "field", "formattedValue", "hasFocus", "height", "isEditable", "isSelected", "rowId", "tabIndex", "value", "width", "className", "showRightBorder", "extendRowFullWidth", "row", "colSpan", "disableDragEvents", "onClick", "onDoubleClick", "onMouseDown", "onMouseUp", "onMouseOver", "onKeyDown", "onKeyUp", "onDragEnter", "onDragOver"],
25
+ _excluded2 = ["align", "children", "editCellState", "colIndex", "column", "cellMode", "field", "formattedValue", "hasFocus", "height", "isEditable", "isSelected", "rowId", "tabIndex", "value", "width", "className", "showRightBorder", "extendRowFullWidth", "row", "colSpan", "disableDragEvents", "onClick", "onDoubleClick", "onMouseDown", "onMouseUp", "onMouseOver", "onKeyDown", "onKeyUp", "onDragEnter", "onDragOver"],
26
26
  _excluded3 = ["column", "rowId", "editCellState", "align", "children", "colIndex", "height", "width", "className", "showRightBorder", "extendRowFullWidth", "row", "colSpan", "disableDragEvents", "onClick", "onDoubleClick", "onMouseDown", "onMouseUp", "onMouseOver", "onKeyDown", "onKeyUp", "onDragEnter", "onDragOver"],
27
27
  _excluded4 = ["changeReason", "unstable_updateValueOnRender"];
28
28
  /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
@@ -121,7 +121,7 @@ function GridEditDateCell(props) {
121
121
  const meta = apiRef.current.unstable_getEditCellMeta(id, field);
122
122
  const handleInputRef = el => {
123
123
  inputRef.current = el;
124
- if (meta.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
124
+ if (meta?.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
125
125
  const inputValue = inputRef.current.value;
126
126
  const parsedDate = parseValueToDate(inputValue);
127
127
  setValueState({
@@ -77,12 +77,12 @@ const GridEditInputCell = /*#__PURE__*/React.forwardRef((props, ref) => {
77
77
  unstable_skipValueParser: true
78
78
  }, event);
79
79
  }, [apiRef, debounceMs, field, id, onValueChange]);
80
- const meta = apiRef.current.unstable_getEditCellMeta ? apiRef.current.unstable_getEditCellMeta(id, field) : {};
80
+ const meta = apiRef.current.unstable_getEditCellMeta(id, field);
81
81
  React.useEffect(() => {
82
- if (meta.changeReason !== 'debouncedSetEditCellValue') {
82
+ if (meta?.changeReason !== 'debouncedSetEditCellValue') {
83
83
  setValueState(value);
84
84
  }
85
- }, [meta.changeReason, value]);
85
+ }, [meta, value]);
86
86
  (0, _utils.unstable_useEnhancedEffect)(() => {
87
87
  if (hasFocus) {
88
88
  inputRef.current.focus();
@@ -29,6 +29,7 @@ function computeFlexColumnsWidth({
29
29
  totalFlexUnits,
30
30
  flexColumns
31
31
  }) {
32
+ const uniqueFlexColumns = new Set(flexColumns.map(col => col.field));
32
33
  const flexColumnsLookup = {
33
34
  all: {},
34
35
  frozenFields: [],
@@ -44,7 +45,7 @@ function computeFlexColumnsWidth({
44
45
  // Step 5 of https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
45
46
  function loopOverFlexItems() {
46
47
  // 5a: If all the flex items on the line are frozen, free space has been distributed.
47
- if (flexColumnsLookup.frozenFields.length === flexColumns.length) {
48
+ if (flexColumnsLookup.frozenFields.length === uniqueFlexColumns.size) {
48
49
  return;
49
50
  }
50
51
  const violationsLookup = {
@@ -80,7 +80,7 @@ function useGridDimensions(apiRef, props) {
80
80
  let hasScrollY;
81
81
  if (props.autoHeight) {
82
82
  hasScrollY = false;
83
- hasScrollX = Math.round(columnsTotalWidth) > rootDimensionsRef.current.width;
83
+ hasScrollX = Math.round(columnsTotalWidth) > Math.round(rootDimensionsRef.current.width);
84
84
  viewportOuterSize = {
85
85
  width: rootDimensionsRef.current.width,
86
86
  height: rowsMeta.currentPageTotalHeight + (hasScrollX ? scrollBarSize : 0)
@@ -96,7 +96,7 @@ function useGridDimensions(apiRef, props) {
96
96
  height: rowsMeta.currentPageTotalHeight
97
97
  },
98
98
  container: {
99
- width: viewportOuterSize.width,
99
+ width: Math.round(viewportOuterSize.width),
100
100
  height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
101
101
  },
102
102
  scrollBarSize
@@ -117,7 +117,7 @@ const useGridEditing = (apiRef, props) => {
117
117
  }, [apiRef, props.editMode]);
118
118
  const getEditCellMeta = React.useCallback((id, field) => {
119
119
  const editingState = (0, _gridEditingSelectors.gridEditRowsStateSelector)(apiRef.current.state);
120
- return editingState[id][field];
120
+ return editingState[id]?.[field] ?? null;
121
121
  }, [apiRef]);
122
122
  const editingSharedApi = {
123
123
  isCellEditable,
@@ -123,7 +123,7 @@ const useGridRowEditing = (apiRef, props) => {
123
123
  } else if (event.key === 'Enter') {
124
124
  reason = _gridRowParams.GridRowEditStopReasons.enterKeyDown;
125
125
  } else if (event.key === 'Tab') {
126
- const columnFields = (0, _gridColumnsSelector.gridColumnFieldsSelector)(apiRef).filter(field => {
126
+ const columnFields = (0, _gridColumnsSelector.gridVisibleColumnFieldsSelector)(apiRef).filter(field => {
127
127
  const column = apiRef.current.getColumn(field);
128
128
  if (column.type === _colDef.GRID_ACTIONS_COLUMN_TYPE) {
129
129
  return true;
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.sanitizeFilterModel = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedQuickFilterApplier = exports.buildAggregatedFilterItemsApplier = exports.buildAggregatedFilterApplier = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _models = require("../../../models");
10
+ var _utils = require("../../../colDef/utils");
10
11
  var _gridFilterState = require("./gridFilterState");
11
12
  var _warning = require("../../../utils/warning");
12
13
  var _columns = require("../columns");
@@ -94,27 +95,47 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
94
95
  if (!filterOperator) {
95
96
  throw new Error(`MUI: No filter operator found for column '${column.field}' and operator value '${newFilterItem.operator}'.`);
96
97
  }
98
+ const hasUserFunctionLegacy = !(0, _utils.isInternalFilter)(filterOperator.getApplyFilterFn);
99
+ const hasUserFunctionV7 = !(0, _utils.isInternalFilter)(filterOperator.getApplyFilterFnV7);
100
+ if (filterOperator.getApplyFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
101
+ const applyFilterOnRow = filterOperator.getApplyFilterFnV7(newFilterItem, column);
102
+ if (typeof applyFilterOnRow !== 'function') {
103
+ return null;
104
+ }
105
+ return {
106
+ v7: true,
107
+ item: newFilterItem,
108
+ fn: row => {
109
+ const value = apiRef.current.getRowValue(row, column);
110
+ return applyFilterOnRow(value, row, column, apiRef);
111
+ }
112
+ };
113
+ }
97
114
  const applyFilterOnRow = filterOperator.getApplyFilterFn(newFilterItem, column);
98
115
  if (typeof applyFilterOnRow !== 'function') {
99
116
  return null;
100
117
  }
101
- const fn = rowId => {
102
- const cellParams = apiRef.current.getCellParams(rowId, newFilterItem.field);
103
- return applyFilterOnRow(cellParams);
104
- };
105
118
  return {
106
- fn,
107
- item: newFilterItem
119
+ v7: false,
120
+ item: newFilterItem,
121
+ fn: rowId => {
122
+ const params = apiRef.current.getCellParams(rowId, newFilterItem.field);
123
+ _utils.GLOBAL_API_REF.current = apiRef;
124
+ const result = applyFilterOnRow(params);
125
+ _utils.GLOBAL_API_REF.current = null;
126
+ return result;
127
+ }
108
128
  };
109
129
  };
110
130
 
111
131
  /**
112
132
  * Generates a method to easily check if a row is matching the current filter model.
133
+ * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
113
134
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
114
135
  * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
115
136
  * @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.
116
137
  */
117
- const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
138
+ const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef) => {
118
139
  const {
119
140
  items
120
141
  } = filterModel;
@@ -122,76 +143,111 @@ const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
122
143
  if (appliers.length === 0) {
123
144
  return null;
124
145
  }
125
- return (rowId, shouldApplyFilter) => {
146
+ return (row, shouldApplyFilter) => {
126
147
  const resultPerItemId = {};
127
- const filteredAppliers = shouldApplyFilter ? appliers.filter(applier => shouldApplyFilter(applier.item.field)) : appliers;
128
- filteredAppliers.forEach(applier => {
129
- resultPerItemId[applier.item.id] = applier.fn(rowId);
130
- });
148
+ for (let i = 0; i < appliers.length; i += 1) {
149
+ const applier = appliers[i];
150
+ if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
151
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
152
+ }
153
+ }
131
154
  return resultPerItemId;
132
155
  };
133
156
  };
134
157
 
135
158
  /**
136
159
  * Generates a method to easily check if a row is matching the current quick filter.
137
- * @param {any[]} values The model with which we want to filter the rows.
160
+ * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
161
+ * @param {any[]} filterModel The model with which we want to filter the rows.
138
162
  * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
139
163
  * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
140
164
  */
141
165
  exports.buildAggregatedFilterItemsApplier = buildAggregatedFilterItemsApplier;
142
- const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
143
- const {
144
- quickFilterValues = []
145
- } = filterModel;
166
+ const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
167
+ const quickFilterValues = filterModel.quickFilterValues?.filter(Boolean) ?? [];
146
168
  if (quickFilterValues.length === 0) {
147
169
  return null;
148
170
  }
149
- const columnsFields = (0, _columns.gridColumnFieldsSelector)(apiRef);
150
- const appliersPerField = {};
151
- columnsFields.forEach(field => {
171
+ const columnFields = (0, _columns.gridColumnFieldsSelector)(apiRef);
172
+ const appliersPerField = [];
173
+ columnFields.forEach(field => {
152
174
  const column = apiRef.current.getColumn(field);
153
175
  const getApplyQuickFilterFn = column?.getApplyQuickFilterFn;
154
- if (!getApplyQuickFilterFn) {
155
- return;
176
+ const getApplyQuickFilterFnV7 = column?.getApplyQuickFilterFnV7;
177
+ const hasUserFunctionLegacy = !(0, _utils.isInternalFilter)(getApplyQuickFilterFn);
178
+ const hasUserFunctionV7 = !(0, _utils.isInternalFilter)(getApplyQuickFilterFnV7);
179
+ if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
180
+ appliersPerField.push({
181
+ column,
182
+ appliers: quickFilterValues.map(value => ({
183
+ v7: true,
184
+ fn: getApplyQuickFilterFnV7(value, column, apiRef)
185
+ }))
186
+ });
187
+ } else if (getApplyQuickFilterFn) {
188
+ appliersPerField.push({
189
+ column,
190
+ appliers: quickFilterValues.map(value => ({
191
+ v7: false,
192
+ fn: getApplyQuickFilterFn(value, column, apiRef)
193
+ }))
194
+ });
156
195
  }
157
- appliersPerField[field] = quickFilterValues.map(value => getApplyQuickFilterFn(value, column, apiRef));
158
196
  });
159
-
160
- // If some value does not have an applier we ignore them
161
- const sanitizedQuickFilterValues = quickFilterValues.filter((value, index) => Object.keys(appliersPerField).some(field => appliersPerField[field][index] != null));
162
- if (sanitizedQuickFilterValues.length === 0) {
163
- return null;
164
- }
165
- return (rowId, shouldApplyFilter) => {
197
+ return function isRowMatchingQuickFilter(row, shouldApplyFilter) {
198
+ const result = {};
166
199
  const usedCellParams = {};
167
- const fieldsToFilter = [];
168
- Object.keys(appliersPerField).forEach(field => {
169
- if (!shouldApplyFilter || shouldApplyFilter(field)) {
170
- usedCellParams[field] = apiRef.current.getCellParams(rowId, field);
171
- fieldsToFilter.push(field);
172
- }
173
- });
174
- const quickFilterValueResult = {};
175
- sanitizedQuickFilterValues.forEach((value, index) => {
176
- const isPassing = fieldsToFilter.some(field => {
177
- if (appliersPerField[field][index] == null) {
178
- return false;
200
+
201
+ /* eslint-disable no-restricted-syntax, no-labels, no-continue */
202
+ outer: for (let v = 0; v < quickFilterValues.length; v += 1) {
203
+ const filterValue = quickFilterValues[v];
204
+ for (let i = 0; i < appliersPerField.length; i += 1) {
205
+ const {
206
+ column,
207
+ appliers
208
+ } = appliersPerField[i];
209
+ const {
210
+ field
211
+ } = column;
212
+ if (shouldApplyFilter && !shouldApplyFilter(field)) {
213
+ continue;
179
214
  }
180
- return appliersPerField[field][index]?.(usedCellParams[field]);
181
- });
182
- quickFilterValueResult[value] = isPassing;
183
- });
184
- return quickFilterValueResult;
215
+ const applier = appliers[v];
216
+ const value = apiRef.current.getRowValue(row, column);
217
+ if (applier.fn === null) {
218
+ continue;
219
+ }
220
+ if (applier.v7) {
221
+ const isMatching = applier.fn(value, row, column, apiRef);
222
+ if (isMatching) {
223
+ result[filterValue] = true;
224
+ continue outer;
225
+ }
226
+ } else {
227
+ const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, field);
228
+ usedCellParams[field] = cellParams;
229
+ const isMatching = applier.fn(cellParams);
230
+ if (isMatching) {
231
+ result[filterValue] = true;
232
+ continue outer;
233
+ }
234
+ }
235
+ }
236
+ result[filterValue] = false;
237
+ }
238
+ /* eslint-enable no-restricted-syntax, no-labels, no-continue */
239
+
240
+ return result;
185
241
  };
186
242
  };
187
243
  exports.buildAggregatedQuickFilterApplier = buildAggregatedQuickFilterApplier;
188
- const buildAggregatedFilterApplier = (filterModel, apiRef) => {
189
- const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef);
190
- const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
191
- return (rowId, shouldApplyFilter) => ({
192
- passingFilterItems: isRowMatchingFilterItems && isRowMatchingFilterItems(rowId, shouldApplyFilter),
193
- passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
194
- });
244
+ const buildAggregatedFilterApplier = (getRowId, filterModel, apiRef) => {
245
+ const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef);
246
+ const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
247
+ return function isRowMatchingFilters(row, shouldApplyFilter, result) {
248
+ result.passingFilterItems = isRowMatchingFilterItems?.(row, shouldApplyFilter) ?? null;
249
+ result.passingQuickFilterValues = isRowMatchingQuickFilter?.(row, shouldApplyFilter) ?? null;
250
+ };
195
251
  };
196
252
  exports.buildAggregatedFilterApplier = buildAggregatedFilterApplier;
197
253
  const isNotNull = result => result != null;
@@ -63,7 +63,7 @@ const useGridFilter = (apiRef, props) => {
63
63
  const updateFilteredRows = React.useCallback(() => {
64
64
  apiRef.current.setState(state => {
65
65
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(state, apiRef.current.instanceId);
66
- const isRowMatchingFilters = props.filterMode === 'client' ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(filterModel, apiRef) : null;
66
+ const isRowMatchingFilters = props.filterMode === 'client' ? (0, _gridFilterUtils.buildAggregatedFilterApplier)(props.getRowId, filterModel, apiRef) : null;
67
67
  const filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
68
68
  isRowMatchingFilters,
69
69
  filterModel: filterModel ?? (0, _gridFilterState.getDefaultGridFilterModel)()
@@ -77,7 +77,7 @@ const useGridFilter = (apiRef, props) => {
77
77
  });
78
78
  });
79
79
  apiRef.current.publishEvent('filteredRowsSet');
80
- }, [props.filterMode, apiRef]);
80
+ }, [apiRef, props.filterMode, props.getRowId]);
81
81
  const addColumnMenuItem = React.useCallback((columnMenuItems, colDef) => {
82
82
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
83
83
  return columnMenuItems;
@@ -260,36 +260,45 @@ const useGridFilter = (apiRef, props) => {
260
260
  }
261
261
  return initialValue;
262
262
  }, [props.slots.filterPanel, props.slotProps?.filterPanel]);
263
+ const dataRowIdToIdLookup = apiRef.current.state.rows.dataRowIdToModelLookup;
264
+ const rows = React.useMemo(() => Object.values(dataRowIdToIdLookup), [dataRowIdToIdLookup]);
265
+ const {
266
+ getRowId
267
+ } = props;
263
268
  const flatFilteringMethod = React.useCallback(params => {
264
- if (props.filterMode === 'client' && params.isRowMatchingFilters) {
265
- const tree = (0, _rows.gridRowTreeSelector)(apiRef);
266
- const rowIds = tree[_rows.GRID_ROOT_GROUP_ID].children;
267
- const filteredRowsLookup = {};
268
- const filterCache = {};
269
- for (let i = 0; i < rowIds.length; i += 1) {
270
- const rowId = rowIds[i];
271
- let isRowPassing;
272
- if (typeof rowId === 'string' && rowId.startsWith('auto-generated-group-footer')) {
273
- isRowPassing = true;
274
- } else {
275
- const {
276
- passingFilterItems,
277
- passingQuickFilterValues
278
- } = params.isRowMatchingFilters(rowId);
279
- isRowPassing = (0, _gridFilterUtils.passFilterLogic)([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef, filterCache);
280
- }
281
- filteredRowsLookup[rowId] = isRowPassing;
282
- }
269
+ if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
283
270
  return {
284
- filteredRowsLookup,
271
+ filteredRowsLookup: {},
285
272
  filteredDescendantCountLookup: {}
286
273
  };
287
274
  }
275
+ const dataRowIdToModelLookup = (0, _rows.gridRowsLookupSelector)(apiRef);
276
+ const filteredRowsLookup = {};
277
+ const {
278
+ isRowMatchingFilters
279
+ } = params;
280
+ const filterCache = {};
281
+ const result = {
282
+ passingFilterItems: null,
283
+ passingQuickFilterValues: null
284
+ };
285
+ for (let i = 0; i < rows.length; i += 1) {
286
+ const row = rows[i];
287
+ const id = getRowId ? getRowId(row) : row.id;
288
+ isRowMatchingFilters(row, undefined, result);
289
+ const isRowPassing = (0, _gridFilterUtils.passFilterLogic)([result.passingFilterItems], [result.passingQuickFilterValues], params.filterModel, apiRef, filterCache);
290
+ filteredRowsLookup[id] = isRowPassing;
291
+ }
292
+ const footerId = 'auto-generated-group-footer-root';
293
+ const footer = dataRowIdToModelLookup[footerId];
294
+ if (footer) {
295
+ filteredRowsLookup[footerId] = true;
296
+ }
288
297
  return {
289
- filteredRowsLookup: {},
298
+ filteredRowsLookup,
290
299
  filteredDescendantCountLookup: {}
291
300
  };
292
- }, [apiRef, props.filterMode]);
301
+ }, [apiRef, rows, props.filterMode, getRowId]);
293
302
  (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'columnMenu', addColumnMenuItem);
294
303
  (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
295
304
  (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);