@mui/x-data-grid-pro 5.15.1 → 5.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/DataGridPro/DataGridPro.js +4 -2
  3. package/DataGridPro/useDataGridProComponent.js +4 -1
  4. package/README.md +2 -1
  5. package/components/DataGridProColumnHeaders.js +25 -13
  6. package/hooks/features/columnReorder/useGridColumnReorder.js +95 -3
  7. package/hooks/features/columnResize/useGridColumnResize.js +10 -7
  8. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +4 -4
  9. package/hooks/features/treeData/gridTreeDataUtils.d.ts +2 -1
  10. package/hooks/features/treeData/gridTreeDataUtils.js +7 -2
  11. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  12. package/index.js +1 -1
  13. package/legacy/DataGridPro/DataGridPro.js +4 -2
  14. package/legacy/DataGridPro/useDataGridProComponent.js +4 -1
  15. package/legacy/components/DataGridProColumnHeaders.js +25 -13
  16. package/legacy/hooks/features/columnReorder/useGridColumnReorder.js +99 -3
  17. package/legacy/hooks/features/columnResize/useGridColumnResize.js +11 -7
  18. package/legacy/hooks/features/treeData/gridTreeDataUtils.js +7 -2
  19. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  20. package/legacy/index.js +1 -1
  21. package/legacy/utils/domUtils.js +5 -0
  22. package/legacy/utils/releaseInfo.js +1 -1
  23. package/modern/DataGridPro/DataGridPro.js +4 -2
  24. package/modern/DataGridPro/useDataGridProComponent.js +4 -1
  25. package/modern/components/DataGridProColumnHeaders.js +25 -13
  26. package/modern/hooks/features/columnReorder/useGridColumnReorder.js +83 -3
  27. package/modern/hooks/features/columnResize/useGridColumnResize.js +5 -2
  28. package/modern/hooks/features/treeData/gridTreeDataUtils.js +7 -2
  29. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  30. package/modern/index.js +1 -1
  31. package/modern/utils/domUtils.js +3 -0
  32. package/modern/utils/releaseInfo.js +1 -1
  33. package/node/DataGridPro/DataGridPro.js +4 -2
  34. package/node/DataGridPro/useDataGridProComponent.js +3 -0
  35. package/node/components/DataGridProColumnHeaders.js +25 -12
  36. package/node/hooks/features/columnReorder/useGridColumnReorder.js +95 -3
  37. package/node/hooks/features/columnResize/useGridColumnResize.js +9 -6
  38. package/node/hooks/features/treeData/gridTreeDataUtils.js +9 -2
  39. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  40. package/node/index.js +1 -1
  41. package/node/utils/domUtils.js +7 -0
  42. package/node/utils/releaseInfo.js +1 -1
  43. package/package.json +5 -5
  44. package/utils/domUtils.d.ts +1 -0
  45. package/utils/domUtils.js +5 -0
  46. package/utils/releaseInfo.js +1 -1
@@ -39,6 +39,7 @@ export const useGridColumnReorder = (apiRef, props) => {
39
39
  y: 0
40
40
  });
41
41
  const originColumnIndex = React.useRef(null);
42
+ const forbiddenIndexes = React.useRef({});
42
43
  const removeDnDStylesTimeout = React.useRef();
43
44
  const ownerState = {
44
45
  classes: props.classes
@@ -70,6 +71,57 @@ export const useGridColumnReorder = (apiRef, props) => {
70
71
  dragColNode.current.classList.remove(classes.columnHeaderDragging);
71
72
  });
72
73
  originColumnIndex.current = apiRef.current.getColumnIndex(params.field, false);
74
+ const draggingColumnGroupPath = apiRef.current.unstable_getColumnGroupPath(params.field);
75
+ const columnIndex = originColumnIndex.current;
76
+ const allColumns = apiRef.current.getAllColumns();
77
+ const groupsLookup = apiRef.current.unstable_getAllGroupDetails(); // The limitingGroupId is the id of the group from which the dragged column should not escape
78
+
79
+ let limitingGroupId = null;
80
+ draggingColumnGroupPath.forEach(groupId => {
81
+ if (!groupsLookup[groupId]?.freeReordering) {
82
+ // Only consider group that are made of more than one column
83
+ if (columnIndex > 0 && allColumns[columnIndex - 1].groupPath?.includes(groupId)) {
84
+ limitingGroupId = groupId;
85
+ } else if (columnIndex + 1 < allColumns.length && allColumns[columnIndex + 1].groupPath?.includes(groupId)) {
86
+ limitingGroupId = groupId;
87
+ }
88
+ }
89
+ });
90
+ forbiddenIndexes.current = {};
91
+
92
+ for (let indexToForbid = 0; indexToForbid < allColumns.length; indexToForbid += 1) {
93
+ const leftIndex = indexToForbid <= columnIndex ? indexToForbid - 1 : indexToForbid;
94
+ const rightIndex = indexToForbid < columnIndex ? indexToForbid : indexToForbid + 1;
95
+
96
+ if (limitingGroupId !== null) {
97
+ // verify this indexToForbid will be linked to the limiting group. Otherwise forbid it
98
+ let allowIndex = false;
99
+
100
+ if (leftIndex >= 0 && allColumns[leftIndex].groupPath?.includes(limitingGroupId)) {
101
+ allowIndex = true;
102
+ } else if (rightIndex < allColumns.length && allColumns[rightIndex].groupPath?.includes(limitingGroupId)) {
103
+ allowIndex = true;
104
+ }
105
+
106
+ if (!allowIndex) {
107
+ forbiddenIndexes.current[indexToForbid] = true;
108
+ }
109
+ } // Verify we are not splitting another group
110
+
111
+
112
+ if (leftIndex >= 0 && rightIndex < allColumns.length) {
113
+ allColumns[rightIndex]?.groupPath?.forEach(groupId => {
114
+ if (allColumns[leftIndex].groupPath?.includes(groupId)) {
115
+ if (!draggingColumnGroupPath.includes(groupId)) {
116
+ // moving here split the group groupId in two distincts chunks
117
+ if (!groupsLookup[groupId]?.freeReordering) {
118
+ forbiddenIndexes.current[indexToForbid] = true;
119
+ }
120
+ }
121
+ }
122
+ });
123
+ }
124
+ }
73
125
  }, [props.disableColumnReorder, classes.columnHeaderDragging, logger, apiRef]);
74
126
  const handleDragEnter = React.useCallback((params, event) => {
75
127
  event.preventDefault(); // Prevent drag events propagation.
@@ -100,19 +152,47 @@ export const useGridColumnReorder = (apiRef, props) => {
100
152
  const targetCol = apiRef.current.getColumn(params.field);
101
153
  const dragColIndex = apiRef.current.getColumnIndex(dragColField, false);
102
154
  const visibleColumns = apiRef.current.getVisibleColumns();
155
+ const allColumns = apiRef.current.getAllColumns();
103
156
  const cursorMoveDirectionX = getCursorMoveDirectionX(cursorPosition.current, coordinates);
104
157
  const hasMovedLeft = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_LEFT && targetColIndex < dragColIndex;
105
158
  const hasMovedRight = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_RIGHT && dragColIndex < targetColIndex;
106
159
 
107
160
  if (hasMovedLeft || hasMovedRight) {
108
161
  let canBeReordered;
162
+ let indexOffsetInHiddenColumns = 0;
109
163
 
110
164
  if (!targetCol.disableReorder) {
111
165
  canBeReordered = true;
112
166
  } else if (hasMovedLeft) {
113
- canBeReordered = targetColIndex > 0 && !visibleColumns[targetColIndex - 1].disableReorder;
167
+ canBeReordered = targetColVisibleIndex > 0 && !visibleColumns[targetColVisibleIndex - 1].disableReorder;
114
168
  } else {
115
- canBeReordered = targetColIndex < visibleColumns.length - 1 && !visibleColumns[targetColIndex + 1].disableReorder;
169
+ canBeReordered = targetColVisibleIndex < visibleColumns.length - 1 && !visibleColumns[targetColVisibleIndex + 1].disableReorder;
170
+ }
171
+
172
+ if (forbiddenIndexes.current[targetColIndex]) {
173
+ let nextVisibleColumnField;
174
+ let indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
175
+
176
+ if (hasMovedLeft) {
177
+ nextVisibleColumnField = targetColVisibleIndex > 0 ? visibleColumns[targetColVisibleIndex - 1].field : null;
178
+
179
+ while (indexWithOffset > 0 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) {
180
+ indexOffsetInHiddenColumns -= 1;
181
+ indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
182
+ }
183
+ } else {
184
+ nextVisibleColumnField = targetColVisibleIndex + 1 < visibleColumns.length ? visibleColumns[targetColVisibleIndex + 1].field : null;
185
+
186
+ while (indexWithOffset < allColumns.length - 1 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) {
187
+ indexOffsetInHiddenColumns += 1;
188
+ indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
189
+ }
190
+ }
191
+
192
+ if (forbiddenIndexes.current[indexWithOffset] || allColumns[indexWithOffset].field === nextVisibleColumnField) {
193
+ // If we ended up on a visible column, or a forbidden one, we can not do the reorder
194
+ canBeReordered = false;
195
+ }
116
196
  }
117
197
 
118
198
  const canBeReorderedProcessed = apiRef.current.unstable_applyPipeProcessors('canBeReordered', canBeReordered, {
@@ -120,7 +200,7 @@ export const useGridColumnReorder = (apiRef, props) => {
120
200
  });
121
201
 
122
202
  if (canBeReorderedProcessed) {
123
- apiRef.current.setColumnIndex(dragColField, targetColIndex);
203
+ apiRef.current.setColumnIndex(dragColField, targetColIndex + indexOffsetInHiddenColumns);
124
204
  }
125
205
  }
126
206
 
@@ -4,7 +4,7 @@ import { ownerDocument, useEventCallback } from '@mui/material/utils';
4
4
  import { gridClasses, useGridApiEventHandler, useGridApiOptionHandler, useGridNativeEventListener, useGridLogger } from '@mui/x-data-grid';
5
5
  import { clamp, findParentElementFromClassName } from '@mui/x-data-grid/internals';
6
6
  import { useTheme } from '@mui/material/styles';
7
- import { findGridCellElementsFromCol, getFieldFromHeaderElem, findHeaderElementFromField } from '../../../utils/domUtils';
7
+ import { findGridCellElementsFromCol, getFieldFromHeaderElem, findHeaderElementFromField, findGroupHeaderElementsFromField } from '../../../utils/domUtils';
8
8
  // TODO: remove support for Safari < 13.
9
9
  // https://caniuse.com/#search=touch-action
10
10
  //
@@ -104,6 +104,7 @@ export const useGridColumnResize = (apiRef, props) => {
104
104
  const logger = useGridLogger(apiRef, 'useGridColumnResize');
105
105
  const colDefRef = React.useRef();
106
106
  const colElementRef = React.useRef();
107
+ const colGroupingElementRef = React.useRef();
107
108
  const colCellElementsRef = React.useRef();
108
109
  const theme = useTheme(); // To improve accessibility, the separator has padding on both sides.
109
110
  // Clicking inside the padding area should be treated as a click in the separator.
@@ -124,7 +125,7 @@ export const useGridColumnResize = (apiRef, props) => {
124
125
  colElementRef.current.style.width = `${newWidth}px`;
125
126
  colElementRef.current.style.minWidth = `${newWidth}px`;
126
127
  colElementRef.current.style.maxWidth = `${newWidth}px`;
127
- colCellElementsRef.current.forEach(element => {
128
+ [...colCellElementsRef.current, ...colGroupingElementRef.current].forEach(element => {
128
129
  const div = element;
129
130
  let finalWidth;
130
131
 
@@ -198,6 +199,7 @@ export const useGridColumnResize = (apiRef, props) => {
198
199
  }, event);
199
200
  colDefRef.current = colDef;
200
201
  colElementRef.current = apiRef.current.columnHeadersContainerElementRef?.current.querySelector(`[data-field="${colDef.field}"]`);
202
+ colGroupingElementRef.current = findGroupHeaderElementsFromField(apiRef.current.columnHeadersContainerElementRef?.current, colDef.field);
201
203
  colCellElementsRef.current = findGridCellElementsFromCol(colElementRef.current, apiRef.current);
202
204
  const doc = ownerDocument(apiRef.current.rootElementRef.current);
203
205
  doc.body.style.cursor = 'col-resize';
@@ -267,6 +269,7 @@ export const useGridColumnResize = (apiRef, props) => {
267
269
  colElementRef.current = findParentElementFromClassName(event.target, gridClasses.columnHeader);
268
270
  const field = getFieldFromHeaderElem(colElementRef.current);
269
271
  const colDef = apiRef.current.getColumn(field);
272
+ colGroupingElementRef.current = findGroupHeaderElementsFromField(apiRef.current.columnHeadersContainerElementRef?.current, field);
270
273
  logger.debug(`Start Resize on col ${colDef.field}`);
271
274
  apiRef.current.publishEvent('columnResizeStart', {
272
275
  field
@@ -1,3 +1,4 @@
1
+ import { passFilterLogic } from '@mui/x-data-grid/internals';
1
2
  export const TREE_DATA_STRATEGY = 'tree-data';
2
3
  /**
3
4
  * A node is visible if one of the following criteria is met:
@@ -21,10 +22,14 @@ export const filterRowTreeFromTreeData = params => {
21
22
 
22
23
  if (shouldSkipFilters) {
23
24
  isMatchingFilters = null;
24
- } else if (!isRowMatchingFilters) {
25
+ } else if (!isRowMatchingFilters || node.position === 'footer') {
25
26
  isMatchingFilters = true;
26
27
  } else {
27
- isMatchingFilters = isRowMatchingFilters(node.id);
28
+ const {
29
+ passingFilterItems,
30
+ passingQuickFilterValues
31
+ } = isRowMatchingFilters(node.id);
32
+ isMatchingFilters = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel);
28
33
  }
29
34
 
30
35
  let filteredDescendantCount = 0;
@@ -97,7 +97,8 @@ export const useGridTreeDataPreProcessors = (apiRef, props) => {
97
97
  return filterRowTreeFromTreeData({
98
98
  rowTree,
99
99
  isRowMatchingFilters: params.isRowMatchingFilters,
100
- disableChildrenFiltering: props.disableChildrenFiltering
100
+ disableChildrenFiltering: props.disableChildrenFiltering,
101
+ filterModel: params.filterModel
101
102
  });
102
103
  }, [apiRef, props.disableChildrenFiltering]);
103
104
  const sortRows = React.useCallback(params => {
package/modern/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.15.1
1
+ /** @license MUI v5.16.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -6,6 +6,9 @@ export function getFieldFromHeaderElem(colCellEl) {
6
6
  export function findHeaderElementFromField(elem, field) {
7
7
  return elem.querySelector(`[data-field="${field}"]`);
8
8
  }
9
+ export function findGroupHeaderElementsFromField(elem, field) {
10
+ return Array.from(elem.querySelectorAll(`[data-fields*="|-${field}-|"]`) ?? []);
11
+ }
9
12
  export function findGridCellElementsFromCol(col, api) {
10
13
  const root = findParentElementFromClassName(col, 'MuiDataGrid-root');
11
14
 
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTY1OTU2NDAwMDAwMA==";
3
+ const releaseInfo = "MTY2MTM3ODQwMDAwMA==";
4
4
 
5
5
  if (process.env.NODE_ENV !== 'production') {
6
6
  // A simple hack to set the value in the test environment (has no build step).
@@ -130,6 +130,7 @@ DataGridProRaw.propTypes = {
130
130
  * @default 3
131
131
  */
132
132
  columnBuffer: _propTypes.default.number,
133
+ columnGroupingModel: _propTypes.default.arrayOf(_propTypes.default.object),
133
134
 
134
135
  /**
135
136
  * Set of columns of type [[GridColumns]].
@@ -298,6 +299,7 @@ DataGridProRaw.propTypes = {
298
299
  * For each feature, if the flag is not explicitly set to `true`, the feature will be fully disabled and any property / method call will not have any effect.
299
300
  */
300
301
  experimentalFeatures: _propTypes.default.shape({
302
+ columnGrouping: _propTypes.default.bool,
301
303
  newEditingApi: _propTypes.default.bool,
302
304
  preventCommitWhileValidating: _propTypes.default.bool,
303
305
  rowPinning: _propTypes.default.bool,
@@ -502,7 +504,7 @@ DataGridProRaw.propTypes = {
502
504
 
503
505
  /**
504
506
  * Allows to pass the logging level or false to turn off logging.
505
- * @default "debug"
507
+ * @default "error" ("warn" in dev mode)
506
508
  */
507
509
  logLevel: _propTypes.default.oneOf(['debug', 'error', 'info', 'warn', false]),
508
510
 
@@ -846,7 +848,7 @@ DataGridProRaw.propTypes = {
846
848
  * @param {GridState} state The new state.
847
849
  * @param {MuiEvent<{}>} event The event object.
848
850
  * @param {GridCallbackDetails} details Additional details for this callback.
849
- * @internal
851
+ * @ignore - do not document.
850
852
  */
851
853
  onStateChange: _propTypes.default.func,
852
854
 
@@ -42,6 +42,7 @@ const useDataGridProComponent = (inputApiRef, props) => {
42
42
  * Register all pre-processors called during state initialization here.
43
43
  */
44
44
 
45
+ (0, _internals.useGridColumnGroupingPreProcessors)(apiRef, props);
45
46
  (0, _internals.useGridSelectionPreProcessors)(apiRef, props);
46
47
  (0, _useGridRowReorderPreProcessors.useGridRowReorderPreProcessors)(apiRef, props);
47
48
  (0, _useGridTreeDataPreProcessors.useGridTreeDataPreProcessors)(apiRef, props);
@@ -72,6 +73,7 @@ const useDataGridProComponent = (inputApiRef, props) => {
72
73
  (0, _internals.useGridInitializeState)(_internals.paginationStateInitializer, apiRef, props);
73
74
  (0, _internals.useGridInitializeState)(_internals.rowsMetaStateInitializer, apiRef, props);
74
75
  (0, _internals.useGridInitializeState)(_internals.columnMenuStateInitializer, apiRef, props);
76
+ (0, _internals.useGridInitializeState)(_internals.columnGroupsStateInitializer, apiRef, props);
75
77
  (0, _useGridTreeData.useGridTreeData)(apiRef);
76
78
  (0, _internals.useGridKeyboardNavigation)(apiRef, props);
77
79
  (0, _internals.useGridSelection)(apiRef, props);
@@ -82,6 +84,7 @@ const useDataGridProComponent = (inputApiRef, props) => {
82
84
  (0, _internals.useGridParamsApi)(apiRef);
83
85
  (0, _useGridDetailPanel.useGridDetailPanel)(apiRef, props);
84
86
  (0, _internals.useGridColumnSpanning)(apiRef);
87
+ (0, _internals.useGridColumnGrouping)(apiRef, props);
85
88
  const useGridEditing = (_props$experimentalFe2 = props.experimentalFeatures) != null && _props$experimentalFe2.newEditingApi ? _internals.useGridEditing_new : _internals.useGridEditing_old;
86
89
  useGridEditing(apiRef, props);
87
90
  (0, _internals.useGridFocus)(apiRef, props);
@@ -82,6 +82,7 @@ const GridColumnHeadersPinnedColumnHeaders = (0, _styles.styled)('div', {
82
82
  height: '100%',
83
83
  zIndex: 1,
84
84
  display: 'flex',
85
+ flexDirection: 'column',
85
86
  boxShadow: theme.shadows[2],
86
87
  backgroundColor: theme.palette.background.default
87
88
  }, theme.palette.mode === 'dark' && {
@@ -122,7 +123,8 @@ const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function DataGrid
122
123
  renderContext,
123
124
  getRootProps,
124
125
  getInnerProps,
125
- getColumns
126
+ getColumnHeaders,
127
+ getColumnGroupHeaders
126
128
  } = (0, _internals.useGridColumnHeaders)({
127
129
  innerRef,
128
130
  minColumnIndex: leftPinnedColumns.length
@@ -143,35 +145,42 @@ const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function DataGrid
143
145
  }) : null;
144
146
  const innerProps = getInnerProps();
145
147
  const pinnedColumnHeadersProps = {
146
- role: innerProps.role,
147
- 'aria-rowindex': innerProps['aria-rowindex']
148
+ role: innerProps.role
148
149
  };
149
150
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_internals.GridColumnHeaders, (0, _extends2.default)({
150
151
  ref: ref,
151
152
  className: className
152
153
  }, getRootProps(other), {
153
- children: [leftRenderContext && /*#__PURE__*/(0, _jsxRuntime.jsx)(GridColumnHeadersPinnedColumnHeaders, (0, _extends2.default)({
154
+ children: [leftRenderContext && /*#__PURE__*/(0, _jsxRuntime.jsxs)(GridColumnHeadersPinnedColumnHeaders, (0, _extends2.default)({
154
155
  className: classes.leftPinnedColumns,
155
156
  ownerState: {
156
157
  side: _columnPinning.GridPinnedPosition.left
157
158
  }
158
159
  }, pinnedColumnHeadersProps, {
159
- children: getColumns({
160
+ children: [getColumnGroupHeaders({
161
+ renderContext: leftRenderContext,
162
+ minFirstColumn: leftRenderContext.firstColumnIndex,
163
+ maxLastColumn: leftRenderContext.lastColumnIndex
164
+ }), getColumnHeaders({
160
165
  renderContext: leftRenderContext,
161
166
  minFirstColumn: leftRenderContext.firstColumnIndex,
162
167
  maxLastColumn: leftRenderContext.lastColumnIndex
163
168
  }, {
164
169
  disableReorder: true
165
- })
166
- })), /*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.GridColumnHeadersInner, (0, _extends2.default)({
170
+ })]
171
+ })), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_internals.GridColumnHeadersInner, (0, _extends2.default)({
167
172
  isDragging: isDragging
168
173
  }, innerProps, {
169
- children: getColumns({
174
+ children: [getColumnGroupHeaders({
170
175
  renderContext,
171
176
  minFirstColumn: leftPinnedColumns.length,
172
177
  maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
173
- })
174
- })), rightRenderContext && /*#__PURE__*/(0, _jsxRuntime.jsx)(GridColumnHeadersPinnedColumnHeaders, (0, _extends2.default)({
178
+ }), getColumnHeaders({
179
+ renderContext,
180
+ minFirstColumn: leftPinnedColumns.length,
181
+ maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
182
+ })]
183
+ })), rightRenderContext && /*#__PURE__*/(0, _jsxRuntime.jsxs)(GridColumnHeadersPinnedColumnHeaders, (0, _extends2.default)({
175
184
  ownerState: {
176
185
  side: _columnPinning.GridPinnedPosition.right
177
186
  },
@@ -180,14 +189,18 @@ const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function DataGrid
180
189
  paddingRight: scrollbarSize
181
190
  }
182
191
  }, pinnedColumnHeadersProps, {
183
- children: getColumns({
192
+ children: [getColumnGroupHeaders({
193
+ renderContext: rightRenderContext,
194
+ minFirstColumn: rightRenderContext.firstColumnIndex,
195
+ maxLastColumn: rightRenderContext.lastColumnIndex
196
+ }), getColumnHeaders({
184
197
  renderContext: rightRenderContext,
185
198
  minFirstColumn: rightRenderContext.firstColumnIndex,
186
199
  maxLastColumn: rightRenderContext.lastColumnIndex
187
200
  }, {
188
201
  disableReorder: true,
189
202
  separatorSide: _xDataGrid.GridColumnHeaderSeparatorSides.Left
190
- })
203
+ })]
191
204
  }))]
192
205
  }));
193
206
  });
@@ -60,6 +60,7 @@ const useGridColumnReorder = (apiRef, props) => {
60
60
  y: 0
61
61
  });
62
62
  const originColumnIndex = React.useRef(null);
63
+ const forbiddenIndexes = React.useRef({});
63
64
  const removeDnDStylesTimeout = React.useRef();
64
65
  const ownerState = {
65
66
  classes: props.classes
@@ -91,6 +92,69 @@ const useGridColumnReorder = (apiRef, props) => {
91
92
  dragColNode.current.classList.remove(classes.columnHeaderDragging);
92
93
  });
93
94
  originColumnIndex.current = apiRef.current.getColumnIndex(params.field, false);
95
+ const draggingColumnGroupPath = apiRef.current.unstable_getColumnGroupPath(params.field);
96
+ const columnIndex = originColumnIndex.current;
97
+ const allColumns = apiRef.current.getAllColumns();
98
+ const groupsLookup = apiRef.current.unstable_getAllGroupDetails(); // The limitingGroupId is the id of the group from which the dragged column should not escape
99
+
100
+ let limitingGroupId = null;
101
+ draggingColumnGroupPath.forEach(groupId => {
102
+ var _groupsLookup$groupId;
103
+
104
+ if (!((_groupsLookup$groupId = groupsLookup[groupId]) != null && _groupsLookup$groupId.freeReordering)) {
105
+ var _allColumns$groupPath, _allColumns$groupPath2;
106
+
107
+ // Only consider group that are made of more than one column
108
+ if (columnIndex > 0 && (_allColumns$groupPath = allColumns[columnIndex - 1].groupPath) != null && _allColumns$groupPath.includes(groupId)) {
109
+ limitingGroupId = groupId;
110
+ } else if (columnIndex + 1 < allColumns.length && (_allColumns$groupPath2 = allColumns[columnIndex + 1].groupPath) != null && _allColumns$groupPath2.includes(groupId)) {
111
+ limitingGroupId = groupId;
112
+ }
113
+ }
114
+ });
115
+ forbiddenIndexes.current = {};
116
+
117
+ for (let indexToForbid = 0; indexToForbid < allColumns.length; indexToForbid += 1) {
118
+ const leftIndex = indexToForbid <= columnIndex ? indexToForbid - 1 : indexToForbid;
119
+ const rightIndex = indexToForbid < columnIndex ? indexToForbid : indexToForbid + 1;
120
+
121
+ if (limitingGroupId !== null) {
122
+ var _allColumns$leftIndex, _allColumns$rightInde;
123
+
124
+ // verify this indexToForbid will be linked to the limiting group. Otherwise forbid it
125
+ let allowIndex = false;
126
+
127
+ if (leftIndex >= 0 && (_allColumns$leftIndex = allColumns[leftIndex].groupPath) != null && _allColumns$leftIndex.includes(limitingGroupId)) {
128
+ allowIndex = true;
129
+ } else if (rightIndex < allColumns.length && (_allColumns$rightInde = allColumns[rightIndex].groupPath) != null && _allColumns$rightInde.includes(limitingGroupId)) {
130
+ allowIndex = true;
131
+ }
132
+
133
+ if (!allowIndex) {
134
+ forbiddenIndexes.current[indexToForbid] = true;
135
+ }
136
+ } // Verify we are not splitting another group
137
+
138
+
139
+ if (leftIndex >= 0 && rightIndex < allColumns.length) {
140
+ var _allColumns$rightInde2, _allColumns$rightInde3;
141
+
142
+ (_allColumns$rightInde2 = allColumns[rightIndex]) == null ? void 0 : (_allColumns$rightInde3 = _allColumns$rightInde2.groupPath) == null ? void 0 : _allColumns$rightInde3.forEach(groupId => {
143
+ var _allColumns$leftIndex2;
144
+
145
+ if ((_allColumns$leftIndex2 = allColumns[leftIndex].groupPath) != null && _allColumns$leftIndex2.includes(groupId)) {
146
+ if (!draggingColumnGroupPath.includes(groupId)) {
147
+ var _groupsLookup$groupId2;
148
+
149
+ // moving here split the group groupId in two distincts chunks
150
+ if (!((_groupsLookup$groupId2 = groupsLookup[groupId]) != null && _groupsLookup$groupId2.freeReordering)) {
151
+ forbiddenIndexes.current[indexToForbid] = true;
152
+ }
153
+ }
154
+ }
155
+ });
156
+ }
157
+ }
94
158
  }, [props.disableColumnReorder, classes.columnHeaderDragging, logger, apiRef]);
95
159
  const handleDragEnter = React.useCallback((params, event) => {
96
160
  event.preventDefault(); // Prevent drag events propagation.
@@ -121,19 +185,47 @@ const useGridColumnReorder = (apiRef, props) => {
121
185
  const targetCol = apiRef.current.getColumn(params.field);
122
186
  const dragColIndex = apiRef.current.getColumnIndex(dragColField, false);
123
187
  const visibleColumns = apiRef.current.getVisibleColumns();
188
+ const allColumns = apiRef.current.getAllColumns();
124
189
  const cursorMoveDirectionX = getCursorMoveDirectionX(cursorPosition.current, coordinates);
125
190
  const hasMovedLeft = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_LEFT && targetColIndex < dragColIndex;
126
191
  const hasMovedRight = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_RIGHT && dragColIndex < targetColIndex;
127
192
 
128
193
  if (hasMovedLeft || hasMovedRight) {
129
194
  let canBeReordered;
195
+ let indexOffsetInHiddenColumns = 0;
130
196
 
131
197
  if (!targetCol.disableReorder) {
132
198
  canBeReordered = true;
133
199
  } else if (hasMovedLeft) {
134
- canBeReordered = targetColIndex > 0 && !visibleColumns[targetColIndex - 1].disableReorder;
200
+ canBeReordered = targetColVisibleIndex > 0 && !visibleColumns[targetColVisibleIndex - 1].disableReorder;
135
201
  } else {
136
- canBeReordered = targetColIndex < visibleColumns.length - 1 && !visibleColumns[targetColIndex + 1].disableReorder;
202
+ canBeReordered = targetColVisibleIndex < visibleColumns.length - 1 && !visibleColumns[targetColVisibleIndex + 1].disableReorder;
203
+ }
204
+
205
+ if (forbiddenIndexes.current[targetColIndex]) {
206
+ let nextVisibleColumnField;
207
+ let indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
208
+
209
+ if (hasMovedLeft) {
210
+ nextVisibleColumnField = targetColVisibleIndex > 0 ? visibleColumns[targetColVisibleIndex - 1].field : null;
211
+
212
+ while (indexWithOffset > 0 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) {
213
+ indexOffsetInHiddenColumns -= 1;
214
+ indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
215
+ }
216
+ } else {
217
+ nextVisibleColumnField = targetColVisibleIndex + 1 < visibleColumns.length ? visibleColumns[targetColVisibleIndex + 1].field : null;
218
+
219
+ while (indexWithOffset < allColumns.length - 1 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) {
220
+ indexOffsetInHiddenColumns += 1;
221
+ indexWithOffset = targetColIndex + indexOffsetInHiddenColumns;
222
+ }
223
+ }
224
+
225
+ if (forbiddenIndexes.current[indexWithOffset] || allColumns[indexWithOffset].field === nextVisibleColumnField) {
226
+ // If we ended up on a visible column, or a forbidden one, we can not do the reorder
227
+ canBeReordered = false;
228
+ }
137
229
  }
138
230
 
139
231
  const canBeReorderedProcessed = apiRef.current.unstable_applyPipeProcessors('canBeReordered', canBeReordered, {
@@ -141,7 +233,7 @@ const useGridColumnReorder = (apiRef, props) => {
141
233
  });
142
234
 
143
235
  if (canBeReorderedProcessed) {
144
- apiRef.current.setColumnIndex(dragColField, targetColIndex);
236
+ apiRef.current.setColumnIndex(dragColField, targetColIndex + indexOffsetInHiddenColumns);
145
237
  }
146
238
  }
147
239
 
@@ -127,6 +127,7 @@ const useGridColumnResize = (apiRef, props) => {
127
127
  const logger = (0, _xDataGrid.useGridLogger)(apiRef, 'useGridColumnResize');
128
128
  const colDefRef = React.useRef();
129
129
  const colElementRef = React.useRef();
130
+ const colGroupingElementRef = React.useRef();
130
131
  const colCellElementsRef = React.useRef();
131
132
  const theme = (0, _styles.useTheme)(); // To improve accessibility, the separator has padding on both sides.
132
133
  // Clicking inside the padding area should be treated as a click in the separator.
@@ -147,7 +148,7 @@ const useGridColumnResize = (apiRef, props) => {
147
148
  colElementRef.current.style.width = `${newWidth}px`;
148
149
  colElementRef.current.style.minWidth = `${newWidth}px`;
149
150
  colElementRef.current.style.maxWidth = `${newWidth}px`;
150
- colCellElementsRef.current.forEach(element => {
151
+ [...colCellElementsRef.current, ...colGroupingElementRef.current].forEach(element => {
151
152
  const div = element;
152
153
  let finalWidth;
153
154
 
@@ -205,7 +206,7 @@ const useGridColumnResize = (apiRef, props) => {
205
206
  const handleColumnResizeMouseDown = (0, _utils.useEventCallback)(({
206
207
  colDef
207
208
  }, event) => {
208
- var _apiRef$current$colum;
209
+ var _apiRef$current$colum, _apiRef$current$colum2;
209
210
 
210
211
  // Only handle left clicks
211
212
  if (event.button !== 0) {
@@ -225,6 +226,7 @@ const useGridColumnResize = (apiRef, props) => {
225
226
  }, event);
226
227
  colDefRef.current = colDef;
227
228
  colElementRef.current = (_apiRef$current$colum = apiRef.current.columnHeadersContainerElementRef) == null ? void 0 : _apiRef$current$colum.current.querySelector(`[data-field="${colDef.field}"]`);
229
+ colGroupingElementRef.current = (0, _domUtils.findGroupHeaderElementsFromField)((_apiRef$current$colum2 = apiRef.current.columnHeadersContainerElementRef) == null ? void 0 : _apiRef$current$colum2.current, colDef.field);
228
230
  colCellElementsRef.current = (0, _domUtils.findGridCellElementsFromCol)(colElementRef.current, apiRef.current);
229
231
  const doc = (0, _utils.ownerDocument)(apiRef.current.rootElementRef.current);
230
232
  doc.body.style.cursor = 'col-resize';
@@ -273,7 +275,7 @@ const useGridColumnResize = (apiRef, props) => {
273
275
  apiRef.current.publishEvent('columnResize', params, nativeEvent);
274
276
  });
275
277
  const handleTouchStart = (0, _utils.useEventCallback)(event => {
276
- var _apiRef$current$colum2;
278
+ var _apiRef$current$colum3, _apiRef$current$colum4;
277
279
 
278
280
  const cellSeparator = (0, _internals.findParentElementFromClassName)(event.target, _xDataGrid.gridClasses['columnSeparator--resizable']); // Let the event bubble if the target is not a col separator
279
281
 
@@ -296,12 +298,13 @@ const useGridColumnResize = (apiRef, props) => {
296
298
  colElementRef.current = (0, _internals.findParentElementFromClassName)(event.target, _xDataGrid.gridClasses.columnHeader);
297
299
  const field = (0, _domUtils.getFieldFromHeaderElem)(colElementRef.current);
298
300
  const colDef = apiRef.current.getColumn(field);
301
+ colGroupingElementRef.current = (0, _domUtils.findGroupHeaderElementsFromField)((_apiRef$current$colum3 = apiRef.current.columnHeadersContainerElementRef) == null ? void 0 : _apiRef$current$colum3.current, field);
299
302
  logger.debug(`Start Resize on col ${colDef.field}`);
300
303
  apiRef.current.publishEvent('columnResizeStart', {
301
304
  field
302
305
  }, event);
303
306
  colDefRef.current = colDef;
304
- colElementRef.current = (0, _domUtils.findHeaderElementFromField)((_apiRef$current$colum2 = apiRef.current.columnHeadersElementRef) == null ? void 0 : _apiRef$current$colum2.current, colDef.field);
307
+ colElementRef.current = (0, _domUtils.findHeaderElementFromField)((_apiRef$current$colum4 = apiRef.current.columnHeadersElementRef) == null ? void 0 : _apiRef$current$colum4.current, colDef.field);
305
308
  colCellElementsRef.current = (0, _domUtils.findGridCellElementsFromCol)(colElementRef.current, apiRef.current);
306
309
  resizeDirection.current = getResizeDirection(event.target, theme.direction);
307
310
  initialOffsetToSeparator.current = computeOffsetToSeparator(touch.clientX, colElementRef.current.getBoundingClientRect(), resizeDirection.current);
@@ -342,9 +345,9 @@ const useGridColumnResize = (apiRef, props) => {
342
345
  };
343
346
  }, [apiRef, handleTouchStart, stopListening]);
344
347
  (0, _xDataGrid.useGridNativeEventListener)(apiRef, () => {
345
- var _apiRef$current$colum3;
348
+ var _apiRef$current$colum5;
346
349
 
347
- return (_apiRef$current$colum3 = apiRef.current.columnHeadersElementRef) == null ? void 0 : _apiRef$current$colum3.current;
350
+ return (_apiRef$current$colum5 = apiRef.current.columnHeadersElementRef) == null ? void 0 : _apiRef$current$colum5.current;
348
351
  }, 'touchstart', handleTouchStart, {
349
352
  passive: doesSupportTouchActionNone()
350
353
  });
@@ -4,6 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.filterRowTreeFromTreeData = exports.TREE_DATA_STRATEGY = void 0;
7
+
8
+ var _internals = require("@mui/x-data-grid/internals");
9
+
7
10
  const TREE_DATA_STRATEGY = 'tree-data';
8
11
  /**
9
12
  * A node is visible if one of the following criteria is met:
@@ -31,10 +34,14 @@ const filterRowTreeFromTreeData = params => {
31
34
 
32
35
  if (shouldSkipFilters) {
33
36
  isMatchingFilters = null;
34
- } else if (!isRowMatchingFilters) {
37
+ } else if (!isRowMatchingFilters || node.position === 'footer') {
35
38
  isMatchingFilters = true;
36
39
  } else {
37
- isMatchingFilters = isRowMatchingFilters(node.id);
40
+ const {
41
+ passingFilterItems,
42
+ passingQuickFilterValues
43
+ } = isRowMatchingFilters(node.id);
44
+ isMatchingFilters = (0, _internals.passFilterLogic)([passingFilterItems], [passingQuickFilterValues], params.filterModel);
38
45
  }
39
46
 
40
47
  let filteredDescendantCount = 0;
@@ -123,7 +123,8 @@ const useGridTreeDataPreProcessors = (apiRef, props) => {
123
123
  return (0, _gridTreeDataUtils.filterRowTreeFromTreeData)({
124
124
  rowTree,
125
125
  isRowMatchingFilters: params.isRowMatchingFilters,
126
- disableChildrenFiltering: props.disableChildrenFiltering
126
+ disableChildrenFiltering: props.disableChildrenFiltering,
127
+ filterModel: params.filterModel
127
128
  });
128
129
  }, [apiRef, props.disableChildrenFiltering]);
129
130
  const sortRows = React.useCallback(params => {
package/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.15.1
1
+ /** @license MUI v5.16.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.findGridCellElementsFromCol = findGridCellElementsFromCol;
7
+ exports.findGroupHeaderElementsFromField = findGroupHeaderElementsFromField;
7
8
  exports.findHeaderElementFromField = findHeaderElementFromField;
8
9
  exports.getFieldFromHeaderElem = getFieldFromHeaderElem;
9
10
 
@@ -19,6 +20,12 @@ function findHeaderElementFromField(elem, field) {
19
20
  return elem.querySelector(`[data-field="${field}"]`);
20
21
  }
21
22
 
23
+ function findGroupHeaderElementsFromField(elem, field) {
24
+ var _elem$querySelectorAl;
25
+
26
+ return Array.from((_elem$querySelectorAl = elem.querySelectorAll(`[data-fields*="|-${field}-|"]`)) != null ? _elem$querySelectorAl : []);
27
+ }
28
+
22
29
  function findGridCellElementsFromCol(col, api) {
23
30
  const root = (0, _internals.findParentElementFromClassName)(col, 'MuiDataGrid-root');
24
31
 
@@ -8,7 +8,7 @@ exports.getReleaseInfo = void 0;
8
8
  var _utils = require("@mui/utils");
9
9
 
10
10
  const getReleaseInfo = () => {
11
- const releaseInfo = "MTY1OTU2NDAwMDAwMA==";
11
+ const releaseInfo = "MTY2MTM3ODQwMDAwMA==";
12
12
 
13
13
  if (process.env.NODE_ENV !== 'production') {
14
14
  // A simple hack to set the value in the test environment (has no build step).