@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
@@ -15,6 +15,7 @@ export function computeFlexColumnsWidth({
15
15
  totalFlexUnits,
16
16
  flexColumns
17
17
  }) {
18
+ const uniqueFlexColumns = new Set(flexColumns.map(col => col.field));
18
19
  const flexColumnsLookup = {
19
20
  all: {},
20
21
  frozenFields: [],
@@ -30,7 +31,7 @@ export function computeFlexColumnsWidth({
30
31
  // Step 5 of https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
31
32
  function loopOverFlexItems() {
32
33
  // 5a: If all the flex items on the line are frozen, free space has been distributed.
33
- if (flexColumnsLookup.frozenFields.length === flexColumns.length) {
34
+ if (flexColumnsLookup.frozenFields.length === uniqueFlexColumns.size) {
34
35
  return;
35
36
  }
36
37
  const violationsLookup = {
@@ -72,7 +72,7 @@ export function useGridDimensions(apiRef, props) {
72
72
  let hasScrollY;
73
73
  if (props.autoHeight) {
74
74
  hasScrollY = false;
75
- hasScrollX = Math.round(columnsTotalWidth) > rootDimensionsRef.current.width;
75
+ hasScrollX = Math.round(columnsTotalWidth) > Math.round(rootDimensionsRef.current.width);
76
76
  viewportOuterSize = {
77
77
  width: rootDimensionsRef.current.width,
78
78
  height: rowsMeta.currentPageTotalHeight + (hasScrollX ? scrollBarSize : 0)
@@ -88,7 +88,7 @@ export function useGridDimensions(apiRef, props) {
88
88
  height: rowsMeta.currentPageTotalHeight
89
89
  },
90
90
  container: {
91
- width: viewportOuterSize.width,
91
+ width: Math.round(viewportOuterSize.width),
92
92
  height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
93
93
  },
94
94
  scrollBarSize
@@ -107,7 +107,7 @@ export const useGridEditing = (apiRef, props) => {
107
107
  }, [apiRef, props.editMode]);
108
108
  const getEditCellMeta = React.useCallback((id, field) => {
109
109
  const editingState = gridEditRowsStateSelector(apiRef.current.state);
110
- return editingState[id][field];
110
+ return editingState[id]?.[field] ?? null;
111
111
  }, [apiRef]);
112
112
  const editingSharedApi = {
113
113
  isCellEditable,
@@ -10,7 +10,7 @@ import { GridEditModes, GridRowModes } from '../../../models/gridEditRowModel';
10
10
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
11
11
  import { gridEditRowsStateSelector } from './gridEditingSelectors';
12
12
  import { isPrintableKey } from '../../../utils/keyboardUtils';
13
- import { gridColumnFieldsSelector } from '../columns/gridColumnsSelector';
13
+ import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from '../columns/gridColumnsSelector';
14
14
  import { buildWarning } from '../../../utils/warning';
15
15
  import { gridRowsDataRowIdToIdLookupSelector } from '../rows/gridRowsSelector';
16
16
  import { deepClone } from '../../../utils/utils';
@@ -114,7 +114,7 @@ export const useGridRowEditing = (apiRef, props) => {
114
114
  } else if (event.key === 'Enter') {
115
115
  reason = GridRowEditStopReasons.enterKeyDown;
116
116
  } else if (event.key === 'Tab') {
117
- const columnFields = gridColumnFieldsSelector(apiRef).filter(field => {
117
+ const columnFields = gridVisibleColumnFieldsSelector(apiRef).filter(field => {
118
118
  const column = apiRef.current.getColumn(field);
119
119
  if (column.type === GRID_ACTIONS_COLUMN_TYPE) {
120
120
  return true;
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { GridLogicOperator } from '../../../models';
3
+ import { GLOBAL_API_REF, isInternalFilter } from '../../../colDef/utils';
3
4
  import { getDefaultGridFilterModel } from './gridFilterState';
4
5
  import { buildWarning } from '../../../utils/warning';
5
6
  import { gridColumnFieldsSelector, gridColumnLookupSelector } from '../columns';
@@ -84,27 +85,47 @@ const getFilterCallbackFromItem = (filterItem, apiRef) => {
84
85
  if (!filterOperator) {
85
86
  throw new Error(`MUI: No filter operator found for column '${column.field}' and operator value '${newFilterItem.operator}'.`);
86
87
  }
88
+ const hasUserFunctionLegacy = !isInternalFilter(filterOperator.getApplyFilterFn);
89
+ const hasUserFunctionV7 = !isInternalFilter(filterOperator.getApplyFilterFnV7);
90
+ if (filterOperator.getApplyFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
91
+ const applyFilterOnRow = filterOperator.getApplyFilterFnV7(newFilterItem, column);
92
+ if (typeof applyFilterOnRow !== 'function') {
93
+ return null;
94
+ }
95
+ return {
96
+ v7: true,
97
+ item: newFilterItem,
98
+ fn: row => {
99
+ const value = apiRef.current.getRowValue(row, column);
100
+ return applyFilterOnRow(value, row, column, apiRef);
101
+ }
102
+ };
103
+ }
87
104
  const applyFilterOnRow = filterOperator.getApplyFilterFn(newFilterItem, column);
88
105
  if (typeof applyFilterOnRow !== 'function') {
89
106
  return null;
90
107
  }
91
- const fn = rowId => {
92
- const cellParams = apiRef.current.getCellParams(rowId, newFilterItem.field);
93
- return applyFilterOnRow(cellParams);
94
- };
95
108
  return {
96
- fn,
97
- item: newFilterItem
109
+ v7: false,
110
+ item: newFilterItem,
111
+ fn: rowId => {
112
+ const params = apiRef.current.getCellParams(rowId, newFilterItem.field);
113
+ GLOBAL_API_REF.current = apiRef;
114
+ const result = applyFilterOnRow(params);
115
+ GLOBAL_API_REF.current = null;
116
+ return result;
117
+ }
98
118
  };
99
119
  };
100
120
 
101
121
  /**
102
122
  * Generates a method to easily check if a row is matching the current filter model.
123
+ * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
103
124
  * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
104
125
  * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
105
126
  * @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.
106
127
  */
107
- export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
128
+ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef) => {
108
129
  const {
109
130
  items
110
131
  } = filterModel;
@@ -112,74 +133,109 @@ export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
112
133
  if (appliers.length === 0) {
113
134
  return null;
114
135
  }
115
- return (rowId, shouldApplyFilter) => {
136
+ return (row, shouldApplyFilter) => {
116
137
  const resultPerItemId = {};
117
- const filteredAppliers = shouldApplyFilter ? appliers.filter(applier => shouldApplyFilter(applier.item.field)) : appliers;
118
- filteredAppliers.forEach(applier => {
119
- resultPerItemId[applier.item.id] = applier.fn(rowId);
120
- });
138
+ for (let i = 0; i < appliers.length; i += 1) {
139
+ const applier = appliers[i];
140
+ if (!shouldApplyFilter || shouldApplyFilter(applier.item.field)) {
141
+ resultPerItemId[applier.item.id] = applier.v7 ? applier.fn(row) : applier.fn(getRowId ? getRowId(row) : row.id);
142
+ }
143
+ }
121
144
  return resultPerItemId;
122
145
  };
123
146
  };
124
147
 
125
148
  /**
126
149
  * Generates a method to easily check if a row is matching the current quick filter.
127
- * @param {any[]} values The model with which we want to filter the rows.
150
+ * @param {GridRowIdGetter | undefined} getRowId The getter for row's id.
151
+ * @param {any[]} filterModel The model with which we want to filter the rows.
128
152
  * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
129
153
  * @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.
130
154
  */
131
- export const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
132
- const {
133
- quickFilterValues = []
134
- } = filterModel;
155
+ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef) => {
156
+ const quickFilterValues = filterModel.quickFilterValues?.filter(Boolean) ?? [];
135
157
  if (quickFilterValues.length === 0) {
136
158
  return null;
137
159
  }
138
- const columnsFields = gridColumnFieldsSelector(apiRef);
139
- const appliersPerField = {};
140
- columnsFields.forEach(field => {
160
+ const columnFields = gridColumnFieldsSelector(apiRef);
161
+ const appliersPerField = [];
162
+ columnFields.forEach(field => {
141
163
  const column = apiRef.current.getColumn(field);
142
164
  const getApplyQuickFilterFn = column?.getApplyQuickFilterFn;
143
- if (!getApplyQuickFilterFn) {
144
- return;
165
+ const getApplyQuickFilterFnV7 = column?.getApplyQuickFilterFnV7;
166
+ const hasUserFunctionLegacy = !isInternalFilter(getApplyQuickFilterFn);
167
+ const hasUserFunctionV7 = !isInternalFilter(getApplyQuickFilterFnV7);
168
+ if (getApplyQuickFilterFnV7 && !(hasUserFunctionLegacy && !hasUserFunctionV7)) {
169
+ appliersPerField.push({
170
+ column,
171
+ appliers: quickFilterValues.map(value => ({
172
+ v7: true,
173
+ fn: getApplyQuickFilterFnV7(value, column, apiRef)
174
+ }))
175
+ });
176
+ } else if (getApplyQuickFilterFn) {
177
+ appliersPerField.push({
178
+ column,
179
+ appliers: quickFilterValues.map(value => ({
180
+ v7: false,
181
+ fn: getApplyQuickFilterFn(value, column, apiRef)
182
+ }))
183
+ });
145
184
  }
146
- appliersPerField[field] = quickFilterValues.map(value => getApplyQuickFilterFn(value, column, apiRef));
147
185
  });
148
-
149
- // If some value does not have an applier we ignore them
150
- const sanitizedQuickFilterValues = quickFilterValues.filter((value, index) => Object.keys(appliersPerField).some(field => appliersPerField[field][index] != null));
151
- if (sanitizedQuickFilterValues.length === 0) {
152
- return null;
153
- }
154
- return (rowId, shouldApplyFilter) => {
186
+ return function isRowMatchingQuickFilter(row, shouldApplyFilter) {
187
+ const result = {};
155
188
  const usedCellParams = {};
156
- const fieldsToFilter = [];
157
- Object.keys(appliersPerField).forEach(field => {
158
- if (!shouldApplyFilter || shouldApplyFilter(field)) {
159
- usedCellParams[field] = apiRef.current.getCellParams(rowId, field);
160
- fieldsToFilter.push(field);
161
- }
162
- });
163
- const quickFilterValueResult = {};
164
- sanitizedQuickFilterValues.forEach((value, index) => {
165
- const isPassing = fieldsToFilter.some(field => {
166
- if (appliersPerField[field][index] == null) {
167
- return false;
189
+
190
+ /* eslint-disable no-restricted-syntax, no-labels, no-continue */
191
+ outer: for (let v = 0; v < quickFilterValues.length; v += 1) {
192
+ const filterValue = quickFilterValues[v];
193
+ for (let i = 0; i < appliersPerField.length; i += 1) {
194
+ const {
195
+ column,
196
+ appliers
197
+ } = appliersPerField[i];
198
+ const {
199
+ field
200
+ } = column;
201
+ if (shouldApplyFilter && !shouldApplyFilter(field)) {
202
+ continue;
168
203
  }
169
- return appliersPerField[field][index]?.(usedCellParams[field]);
170
- });
171
- quickFilterValueResult[value] = isPassing;
172
- });
173
- return quickFilterValueResult;
204
+ const applier = appliers[v];
205
+ const value = apiRef.current.getRowValue(row, column);
206
+ if (applier.fn === null) {
207
+ continue;
208
+ }
209
+ if (applier.v7) {
210
+ const isMatching = applier.fn(value, row, column, apiRef);
211
+ if (isMatching) {
212
+ result[filterValue] = true;
213
+ continue outer;
214
+ }
215
+ } else {
216
+ const cellParams = usedCellParams[field] ?? apiRef.current.getCellParams(getRowId ? getRowId(row) : row.id, field);
217
+ usedCellParams[field] = cellParams;
218
+ const isMatching = applier.fn(cellParams);
219
+ if (isMatching) {
220
+ result[filterValue] = true;
221
+ continue outer;
222
+ }
223
+ }
224
+ }
225
+ result[filterValue] = false;
226
+ }
227
+ /* eslint-enable no-restricted-syntax, no-labels, no-continue */
228
+
229
+ return result;
174
230
  };
175
231
  };
176
- export const buildAggregatedFilterApplier = (filterModel, apiRef) => {
177
- const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef);
178
- const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
179
- return (rowId, shouldApplyFilter) => ({
180
- passingFilterItems: isRowMatchingFilterItems && isRowMatchingFilterItems(rowId, shouldApplyFilter),
181
- passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
182
- });
232
+ export const buildAggregatedFilterApplier = (getRowId, filterModel, apiRef) => {
233
+ const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(getRowId, filterModel, apiRef);
234
+ const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(getRowId, filterModel, apiRef);
235
+ return function isRowMatchingFilters(row, shouldApplyFilter, result) {
236
+ result.passingFilterItems = isRowMatchingFilterItems?.(row, shouldApplyFilter) ?? null;
237
+ result.passingQuickFilterValues = isRowMatchingQuickFilter?.(row, shouldApplyFilter) ?? null;
238
+ };
183
239
  };
184
240
  const isNotNull = result => result != null;
185
241
  const filterModelItems = (cache, apiRef, items) => {
@@ -9,7 +9,7 @@ import { GridPreferencePanelsValue } from '../preferencesPanel/gridPreferencePan
9
9
  import { getDefaultGridFilterModel } from './gridFilterState';
10
10
  import { gridFilterModelSelector } from './gridFilterSelector';
11
11
  import { useFirstRender } from '../../utils/useFirstRender';
12
- import { GRID_ROOT_GROUP_ID, gridRowTreeSelector } from '../rows';
12
+ import { gridRowsLookupSelector } from '../rows';
13
13
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
14
14
  import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from '../../core/strategyProcessing';
15
15
  import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem, passFilterLogic } from './gridFilterUtils';
@@ -53,7 +53,7 @@ export const useGridFilter = (apiRef, props) => {
53
53
  const updateFilteredRows = React.useCallback(() => {
54
54
  apiRef.current.setState(state => {
55
55
  const filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
56
- const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(filterModel, apiRef) : null;
56
+ const isRowMatchingFilters = props.filterMode === 'client' ? buildAggregatedFilterApplier(props.getRowId, filterModel, apiRef) : null;
57
57
  const filteringResult = apiRef.current.applyStrategyProcessor('filtering', {
58
58
  isRowMatchingFilters,
59
59
  filterModel: filterModel ?? getDefaultGridFilterModel()
@@ -67,7 +67,7 @@ export const useGridFilter = (apiRef, props) => {
67
67
  });
68
68
  });
69
69
  apiRef.current.publishEvent('filteredRowsSet');
70
- }, [props.filterMode, apiRef]);
70
+ }, [apiRef, props.filterMode, props.getRowId]);
71
71
  const addColumnMenuItem = React.useCallback((columnMenuItems, colDef) => {
72
72
  if (colDef == null || colDef.filterable === false || props.disableColumnFilter) {
73
73
  return columnMenuItems;
@@ -250,36 +250,45 @@ export const useGridFilter = (apiRef, props) => {
250
250
  }
251
251
  return initialValue;
252
252
  }, [props.slots.filterPanel, props.slotProps?.filterPanel]);
253
+ const dataRowIdToIdLookup = apiRef.current.state.rows.dataRowIdToModelLookup;
254
+ const rows = React.useMemo(() => Object.values(dataRowIdToIdLookup), [dataRowIdToIdLookup]);
255
+ const {
256
+ getRowId
257
+ } = props;
253
258
  const flatFilteringMethod = React.useCallback(params => {
254
- if (props.filterMode === 'client' && params.isRowMatchingFilters) {
255
- const tree = gridRowTreeSelector(apiRef);
256
- const rowIds = tree[GRID_ROOT_GROUP_ID].children;
257
- const filteredRowsLookup = {};
258
- const filterCache = {};
259
- for (let i = 0; i < rowIds.length; i += 1) {
260
- const rowId = rowIds[i];
261
- let isRowPassing;
262
- if (typeof rowId === 'string' && rowId.startsWith('auto-generated-group-footer')) {
263
- isRowPassing = true;
264
- } else {
265
- const {
266
- passingFilterItems,
267
- passingQuickFilterValues
268
- } = params.isRowMatchingFilters(rowId);
269
- isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef, filterCache);
270
- }
271
- filteredRowsLookup[rowId] = isRowPassing;
272
- }
259
+ if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
273
260
  return {
274
- filteredRowsLookup,
261
+ filteredRowsLookup: {},
275
262
  filteredDescendantCountLookup: {}
276
263
  };
277
264
  }
265
+ const dataRowIdToModelLookup = gridRowsLookupSelector(apiRef);
266
+ const filteredRowsLookup = {};
267
+ const {
268
+ isRowMatchingFilters
269
+ } = params;
270
+ const filterCache = {};
271
+ const result = {
272
+ passingFilterItems: null,
273
+ passingQuickFilterValues: null
274
+ };
275
+ for (let i = 0; i < rows.length; i += 1) {
276
+ const row = rows[i];
277
+ const id = getRowId ? getRowId(row) : row.id;
278
+ isRowMatchingFilters(row, undefined, result);
279
+ const isRowPassing = passFilterLogic([result.passingFilterItems], [result.passingQuickFilterValues], params.filterModel, apiRef, filterCache);
280
+ filteredRowsLookup[id] = isRowPassing;
281
+ }
282
+ const footerId = 'auto-generated-group-footer-root';
283
+ const footer = dataRowIdToModelLookup[footerId];
284
+ if (footer) {
285
+ filteredRowsLookup[footerId] = true;
286
+ }
278
287
  return {
279
- filteredRowsLookup: {},
288
+ filteredRowsLookup,
280
289
  filteredDescendantCountLookup: {}
281
290
  };
282
- }, [apiRef, props.filterMode]);
291
+ }, [apiRef, rows, props.filterMode, getRowId]);
283
292
  useGridRegisterPipeProcessor(apiRef, 'columnMenu', addColumnMenuItem);
284
293
  useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
285
294
  useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
@@ -61,12 +61,16 @@ export const gridPaginationRowRangeSelector = createSelectorMemoized(gridPaginat
61
61
  let topLevelRowAdded = 0;
62
62
  while (lastRowIndex < visibleSortedRowEntries.length && topLevelRowAdded <= topLevelRowsInCurrentPageCount) {
63
63
  const row = visibleSortedRowEntries[lastRowIndex];
64
- const depth = rowTree[row.id].depth;
65
- if (topLevelRowAdded < topLevelRowsInCurrentPageCount || depth > 0) {
64
+ const depth = rowTree[row.id]?.depth;
65
+ if (depth === undefined) {
66
66
  lastRowIndex += 1;
67
- }
68
- if (depth === 0) {
69
- topLevelRowAdded += 1;
67
+ } else {
68
+ if (topLevelRowAdded < topLevelRowsInCurrentPageCount || depth > 0) {
69
+ lastRowIndex += 1;
70
+ }
71
+ if (depth === 0) {
72
+ topLevelRowAdded += 1;
73
+ }
70
74
  }
71
75
  }
72
76
  return {
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { gridPinnedRowsSelector } from './gridRowsSelector';
3
3
  import { gridDensityFactorSelector } from '../density/densitySelector';
4
4
  export const GRID_ROOT_GROUP_ID = `auto-generated-group-node-root`;
5
+ export const GRID_ID_AUTOGENERATED = Symbol('mui-autogenerated-id');
5
6
  export const buildRootGroup = () => ({
6
7
  type: 'group',
7
8
  id: GRID_ROOT_GROUP_ID,
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { getGridCellElement, getGridColumnHeaderElement, getGridRowElement } from '../../../utils/domUtils';
3
+ import { GRID_ID_AUTOGENERATED } from './gridRowsUtils';
3
4
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
4
5
  import { gridFocusCellSelector, gridTabIndexCellSelector } from '../focus/gridFocusStateSelector';
5
6
  export class MissingRowIdError extends Error {}
@@ -12,7 +13,10 @@ export class MissingRowIdError extends Error {}
12
13
  * TODO: Impossible priority - useGridEditing also needs to be after useGridParamsApi
13
14
  * TODO: Impossible priority - useGridFocus also needs to be after useGridParamsApi
14
15
  */
15
- export function useGridParamsApi(apiRef) {
16
+ export function useGridParamsApi(apiRef, props) {
17
+ const {
18
+ getRowId
19
+ } = props;
16
20
  const getColumnHeaderParams = React.useCallback(field => ({
17
21
  field,
18
22
  colDef: apiRef.current.getColumn(field)
@@ -96,6 +100,28 @@ export function useGridParamsApi(apiRef) {
96
100
  }
97
101
  return colDef.valueGetter(getBaseCellParams(id, field));
98
102
  }, [apiRef, getBaseCellParams]);
103
+ const getRowValue = React.useCallback((row, colDef) => {
104
+ const id = GRID_ID_AUTOGENERATED in row ? row[GRID_ID_AUTOGENERATED] : getRowId?.(row) ?? row.id;
105
+ const field = colDef.field;
106
+ if (!colDef || !colDef.valueGetter) {
107
+ return row[field];
108
+ }
109
+ return colDef.valueGetter(getBaseCellParams(id, field));
110
+ }, [getBaseCellParams, getRowId]);
111
+ const getRowFormattedValue = React.useCallback((row, colDef) => {
112
+ const value = getRowValue(row, colDef);
113
+ if (!colDef || !colDef.valueFormatter) {
114
+ return value;
115
+ }
116
+ const id = (getRowId ? getRowId(row) : row.id) ?? row[GRID_ID_AUTOGENERATED];
117
+ const field = colDef.field;
118
+ return colDef.valueFormatter({
119
+ id,
120
+ field,
121
+ value,
122
+ api: apiRef.current
123
+ });
124
+ }, [apiRef, getRowId, getRowValue]);
99
125
  const getColumnHeaderElement = React.useCallback(field => {
100
126
  if (!apiRef.current.rootElementRef.current) {
101
127
  return null;
@@ -121,6 +147,8 @@ export function useGridParamsApi(apiRef) {
121
147
  getCellValue,
122
148
  getCellParams,
123
149
  getCellElement,
150
+ getRowValue,
151
+ getRowFormattedValue,
124
152
  getRowParams,
125
153
  getRowElement,
126
154
  getColumnHeaderParams,
@@ -7,7 +7,7 @@ import { GridSignature, useGridApiEventHandler } from '../../utils/useGridApiEve
7
7
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
8
8
  import { gridSortedRowIdsSelector } from '../sorting/gridSortingSelector';
9
9
  import { gridFilteredRowsLookupSelector } from '../filter/gridFilterSelector';
10
- import { getTreeNodeDescendants, createRowsInternalCache, getRowsStateFromCache, isAutoGeneratedRow, GRID_ROOT_GROUP_ID, updateCacheWithNewRows, getTopLevelRowCount, getRowIdFromRowModel } from './gridRowsUtils';
10
+ import { getTreeNodeDescendants, createRowsInternalCache, getRowsStateFromCache, isAutoGeneratedRow, GRID_ROOT_GROUP_ID, GRID_ID_AUTOGENERATED, updateCacheWithNewRows, getTopLevelRowCount, getRowIdFromRowModel } from './gridRowsUtils';
11
11
  import { useGridRegisterPipeApplier } from '../../core/pipeProcessing';
12
12
  export const rowsStateInitializer = (state, props, apiRef) => {
13
13
  apiRef.current.caches.rows = createRowsInternalCache({
@@ -46,8 +46,9 @@ export const useGridRows = (apiRef, props) => {
46
46
  }
47
47
  const node = apiRef.current.getRowNode(id);
48
48
  if (node && isAutoGeneratedRow(node)) {
49
- // TODO rows v6: Is it the best approach ?
50
- return {};
49
+ return {
50
+ [GRID_ID_AUTOGENERATED]: id
51
+ };
51
52
  }
52
53
  return null;
53
54
  }, [apiRef]);
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.9.0
2
+ * @mui/x-data-grid v6.9.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -56,4 +56,5 @@ export { buildWarning } from '../utils/warning';
56
56
  export { exportAs } from '../utils/exportAs';
57
57
  export { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
58
58
  export { serializeCellValue } from '../hooks/features/export/serializers/csvSerializer';
59
+ export * from '../colDef/utils';
59
60
  export * from './utils';
@@ -20,11 +20,14 @@ import JoySelect from '@mui/joy/Select';
20
20
  import JoyOption from '@mui/joy/Option';
21
21
  import JoyBox from '@mui/joy/Box';
22
22
  import JoyTypography from '@mui/joy/Typography';
23
+ import JoyCircularProgress from '@mui/joy/CircularProgress';
24
+ import JoyTooltip from '@mui/joy/Tooltip';
23
25
  import { unstable_useForkRef as useForkRef } from '@mui/utils';
24
26
  import joyIconSlots, { GridKeyboardArrowRight, GridKeyboardArrowLeft } from './icons';
25
27
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
26
28
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
27
29
  import { gridFilteredTopLevelRowCountSelector, gridPaginationModelSelector } from '../hooks';
30
+ import { GridOverlay } from '../components/containers/GridOverlay';
28
31
  import { jsx as _jsx } from "react/jsx-runtime";
29
32
  import { jsxs as _jsxs } from "react/jsx-runtime";
30
33
  function convertColor(color) {
@@ -296,7 +299,20 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
296
299
  }, [apiRef]);
297
300
  const page = paginationModel.page <= lastPage ? paginationModel.page : lastPage;
298
301
  const pageSize = paginationModel.pageSize;
299
- const pageSizeOptions = rootProps.pageSizeOptions?.includes(pageSize) ? rootProps.pageSizeOptions : [];
302
+ const isPageSizeIncludedInPageSizeOptions = () => {
303
+ for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
304
+ const option = rootProps.pageSizeOptions[i];
305
+ if (typeof option === 'number') {
306
+ if (option === pageSize) {
307
+ return true;
308
+ }
309
+ } else if (option.value === pageSize) {
310
+ return true;
311
+ }
312
+ }
313
+ return false;
314
+ };
315
+ const pageSizeOptions = isPageSizeIncludedInPageSizeOptions() ? rootProps.pageSizeOptions : [];
300
316
  const handleChangeRowsPerPage = (event, newValue) => {
301
317
  const newPageSize = Number(newValue);
302
318
  apiRef.current.setPageSize(newPageSize);
@@ -320,9 +336,9 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
320
336
  value: pageSize,
321
337
  children: pageSizeOptions.map(option => {
322
338
  return /*#__PURE__*/_jsx(Option, {
323
- value: option,
324
- children: option
325
- }, option);
339
+ value: typeof option !== 'number' && option.value ? option.value : option,
340
+ children: typeof option !== 'number' && option.label ? option.label : `${option}`
341
+ }, typeof option !== 'number' && option.label ? option.label : `${option}`);
326
342
  })
327
343
  })]
328
344
  }), /*#__PURE__*/_jsx(JoyTypography, {
@@ -367,6 +383,12 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
367
383
  })]
368
384
  });
369
385
  });
386
+ const LoadingOverlay = /*#__PURE__*/React.forwardRef((props, ref) => {
387
+ return /*#__PURE__*/_jsx(GridOverlay, _extends({}, props, {
388
+ ref: ref,
389
+ children: /*#__PURE__*/_jsx(JoyCircularProgress, {})
390
+ }));
391
+ });
370
392
  const joySlots = _extends({}, joyIconSlots, {
371
393
  baseCheckbox: Checkbox,
372
394
  baseTextField: TextField,
@@ -377,8 +399,8 @@ const joySlots = _extends({}, joyIconSlots, {
377
399
  baseSelectOption: Option,
378
400
  baseInputLabel: InputLabel,
379
401
  baseFormControl: JoyFormControl,
380
- // BaseTooltip: MUITooltip,
381
- // BasePopper: MUIPopper,
382
- pagination: Pagination
402
+ baseTooltip: JoyTooltip,
403
+ pagination: Pagination,
404
+ loadingOverlay: LoadingOverlay
383
405
  });
384
406
  export default joySlots;
@@ -8,8 +8,8 @@ const esESGrid = {
8
8
  toolbarDensity: 'Densidad',
9
9
  toolbarDensityLabel: 'Densidad',
10
10
  toolbarDensityCompact: 'Compacta',
11
- toolbarDensityStandard: 'Standard',
12
- toolbarDensityComfortable: 'Comoda',
11
+ toolbarDensityStandard: 'Estándar',
12
+ toolbarDensityComfortable: 'Cómoda',
13
13
  // Columns selector toolbar button text
14
14
  toolbarColumns: 'Columnas',
15
15
  toolbarColumnsLabel: 'Seleccionar columnas',
@@ -37,7 +37,7 @@ const esESGrid = {
37
37
  columnsPanelHideAllButton: 'Ocultar todo',
38
38
  // Filter panel text
39
39
  filterPanelAddFilter: 'Agregar filtro',
40
- // filterPanelRemoveAll: 'Remove all',
40
+ filterPanelRemoveAll: 'Remover todos',
41
41
  filterPanelDeleteIconLabel: 'Borrar',
42
42
  filterPanelLogicOperator: 'Operador lógico',
43
43
  filterPanelOperator: 'Operadores',