@mui/x-data-grid-pro 5.15.3 → 5.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +150 -1
  2. package/DataGridPro/DataGridPro.js +19 -0
  3. package/DataGridPro/useDataGridProComponent.js +8 -1
  4. package/DataGridPro/useDataGridProProps.js +2 -1
  5. package/components/DataGridProColumnHeaders.js +25 -13
  6. package/components/DataGridProVirtualScroller.js +18 -15
  7. package/components/GridDetailPanelToggleCell.js +2 -1
  8. package/components/GridTreeDataGroupingCell.js +2 -1
  9. package/hooks/features/columnReorder/useGridColumnReorder.js +95 -3
  10. package/hooks/features/columnResize/useGridColumnResize.js +10 -7
  11. package/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +15 -0
  12. package/hooks/features/infiniteLoader/useGridInfiniteLoader.d.ts +1 -1
  13. package/hooks/features/infiniteLoader/useGridInfiniteLoader.js +4 -4
  14. package/hooks/features/lazyLoader/useGridLazyLoader.d.ts +10 -0
  15. package/hooks/features/lazyLoader/useGridLazyLoader.js +178 -0
  16. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.d.ts +5 -0
  17. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +32 -0
  18. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +4 -4
  19. package/hooks/features/treeData/gridTreeDataUtils.d.ts +3 -1
  20. package/hooks/features/treeData/gridTreeDataUtils.js +1 -1
  21. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  22. package/index.js +1 -1
  23. package/legacy/DataGridPro/DataGridPro.js +19 -0
  24. package/legacy/DataGridPro/useDataGridProComponent.js +8 -1
  25. package/legacy/DataGridPro/useDataGridProProps.js +2 -1
  26. package/legacy/components/DataGridProColumnHeaders.js +25 -13
  27. package/legacy/components/DataGridProVirtualScroller.js +18 -15
  28. package/legacy/components/GridDetailPanelToggleCell.js +2 -1
  29. package/legacy/components/GridTreeDataGroupingCell.js +2 -1
  30. package/legacy/hooks/features/columnReorder/useGridColumnReorder.js +99 -3
  31. package/legacy/hooks/features/columnResize/useGridColumnResize.js +11 -7
  32. package/legacy/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +15 -0
  33. package/legacy/hooks/features/infiniteLoader/useGridInfiniteLoader.js +4 -4
  34. package/legacy/hooks/features/lazyLoader/useGridLazyLoader.js +185 -0
  35. package/legacy/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +35 -0
  36. package/legacy/hooks/features/treeData/gridTreeDataUtils.js +1 -1
  37. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  38. package/legacy/index.js +1 -1
  39. package/legacy/models/gridFetchRowsParams.js +1 -0
  40. package/legacy/models/index.js +2 -1
  41. package/legacy/utils/domUtils.js +5 -0
  42. package/legacy/utils/releaseInfo.js +1 -1
  43. package/models/dataGridProProps.d.ts +22 -1
  44. package/models/gridFetchRowsParams.d.ts +22 -0
  45. package/models/gridFetchRowsParams.js +1 -0
  46. package/models/index.d.ts +1 -0
  47. package/models/index.js +2 -1
  48. package/modern/DataGridPro/DataGridPro.js +19 -0
  49. package/modern/DataGridPro/useDataGridProComponent.js +8 -1
  50. package/modern/DataGridPro/useDataGridProProps.js +2 -1
  51. package/modern/components/DataGridProColumnHeaders.js +25 -13
  52. package/modern/components/DataGridProVirtualScroller.js +18 -15
  53. package/modern/components/GridDetailPanelToggleCell.js +2 -1
  54. package/modern/components/GridTreeDataGroupingCell.js +2 -1
  55. package/modern/hooks/features/columnReorder/useGridColumnReorder.js +83 -3
  56. package/modern/hooks/features/columnResize/useGridColumnResize.js +5 -2
  57. package/modern/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +15 -0
  58. package/modern/hooks/features/infiniteLoader/useGridInfiniteLoader.js +4 -4
  59. package/modern/hooks/features/lazyLoader/useGridLazyLoader.js +176 -0
  60. package/modern/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +30 -0
  61. package/modern/hooks/features/treeData/gridTreeDataUtils.js +1 -1
  62. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  63. package/modern/index.js +1 -1
  64. package/modern/models/gridFetchRowsParams.js +1 -0
  65. package/modern/models/index.js +2 -1
  66. package/modern/utils/domUtils.js +3 -0
  67. package/modern/utils/releaseInfo.js +1 -1
  68. package/node/DataGridPro/DataGridPro.js +19 -0
  69. package/node/DataGridPro/useDataGridProComponent.js +9 -0
  70. package/node/DataGridPro/useDataGridProProps.js +1 -0
  71. package/node/components/DataGridProColumnHeaders.js +25 -12
  72. package/node/components/DataGridProVirtualScroller.js +18 -15
  73. package/node/components/GridDetailPanelToggleCell.js +2 -1
  74. package/node/components/GridTreeDataGroupingCell.js +2 -1
  75. package/node/hooks/features/columnReorder/useGridColumnReorder.js +95 -3
  76. package/node/hooks/features/columnResize/useGridColumnResize.js +9 -6
  77. package/node/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +16 -0
  78. package/node/hooks/features/infiniteLoader/useGridInfiniteLoader.js +3 -3
  79. package/node/hooks/features/lazyLoader/useGridLazyLoader.js +193 -0
  80. package/node/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +52 -0
  81. package/node/hooks/features/treeData/gridTreeDataUtils.js +1 -1
  82. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -1
  83. package/node/index.js +1 -1
  84. package/node/models/gridFetchRowsParams.js +5 -0
  85. package/node/models/index.js +13 -0
  86. package/node/utils/domUtils.js +7 -0
  87. package/node/utils/releaseInfo.js +1 -1
  88. package/package.json +5 -5
  89. package/typeOverloads/modules.d.ts +7 -1
  90. package/utils/domUtils.d.ts +1 -0
  91. package/utils/domUtils.js +5 -0
  92. package/utils/releaseInfo.js +1 -1
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export var getReleaseInfo = function getReleaseInfo() {
3
- var releaseInfo = "MTY2MDc5MTYwMDAwMA==";
3
+ var releaseInfo = "MTY2MjMyNTIwMDAwMA==";
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).
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { GridRowTreeNodeConfig, GridEventListener, GridCallbackDetails, GridRowParams, GridRowId, GridValidRowModel } from '@mui/x-data-grid';
2
+ import { GridRowTreeNodeConfig, GridEventListener, GridCallbackDetails, GridRowParams, GridRowId, GridValidRowModel, GridFeatureMode } from '@mui/x-data-grid';
3
3
  import { GridExperimentalFeatures, DataGridPropsWithoutDefaultValue, DataGridPropsWithDefaultValues, DataGridPropsWithComplexDefaultValueAfterProcessing, DataGridPropsWithComplexDefaultValueBeforeProcessing } from '@mui/x-data-grid/internals';
4
4
  import type { GridPinnedColumns } from '../hooks/features/columnPinning';
5
5
  import type { GridPinnedRowsProp } from '../hooks/features/rowPinning';
@@ -7,6 +7,13 @@ import { GridApiPro } from './gridApiPro';
7
7
  import { GridGroupingColDefOverride, GridGroupingColDefOverrideParams } from './gridGroupingColDefOverride';
8
8
  import { GridInitialStatePro } from './gridStatePro';
9
9
  export interface GridExperimentalProFeatures extends GridExperimentalFeatures {
10
+ /**
11
+ * Enables the data grid to lazy load rows while scrolling.
12
+ */
13
+ lazyLoading: boolean;
14
+ /**
15
+ * Enables the the ability for rows to be pinned in data grid.
16
+ */
10
17
  rowPinning: boolean;
11
18
  }
12
19
  /**
@@ -76,6 +83,13 @@ export interface DataGridProPropsWithDefaultValue extends DataGridPropsWithDefau
76
83
  * @default false
77
84
  */
78
85
  rowReordering: boolean;
86
+ /**
87
+ * Loading rows can be processed on the server or client-side.
88
+ * Set it to 'client' if you would like enable infnite loading.
89
+ * Set it to 'server' if you would like to enable lazy loading.
90
+ * * @default "client"
91
+ */
92
+ rowsLoadingMode: GridFeatureMode;
79
93
  }
80
94
  export interface DataGridProPropsWithoutDefaultValue<R extends GridValidRowModel = any> extends Omit<DataGridPropsWithoutDefaultValue<R>, 'initialState'> {
81
95
  /**
@@ -160,6 +174,13 @@ export interface DataGridProPropsWithoutDefaultValue<R extends GridValidRowModel
160
174
  * @param {GridCallbackDetails} details Additional details for this callback.
161
175
  */
162
176
  onRowOrderChange?: GridEventListener<'rowOrderChange'>;
177
+ /**
178
+ * Callback fired when rowCount is set and the next batch of virtualized rows is rendered.
179
+ * @param {GridFetchRowsParams} params With all properties from [[GridFetchRowsParams]].
180
+ * @param {MuiEvent<{}>} event The event object.
181
+ * @param {GridCallbackDetails} details Additional details for this callback.
182
+ */
183
+ onFetchRows?: GridEventListener<'fetchRows'>;
163
184
  /**
164
185
  * Rows data to pin on top or bottom.
165
186
  */
@@ -0,0 +1,22 @@
1
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid/models';
2
+ /**
3
+ * Object passed as parameter to the [[onFetchRows]] option.
4
+ */
5
+ export interface GridFetchRowsParams {
6
+ /**
7
+ * The index of the first row to render.
8
+ */
9
+ firstRowToRender: number;
10
+ /**
11
+ * The index of the last row to render.
12
+ */
13
+ lastRowToRender: number;
14
+ /**
15
+ * The sort model used to sort the grid.
16
+ */
17
+ sortModel: GridSortModel;
18
+ /**
19
+ * The filter model.
20
+ */
21
+ filterModel: GridFilterModel;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
package/models/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './gridGroupingColDefOverride';
2
2
  export * from './gridRowScrollEndParams';
3
3
  export * from './gridRowOrderChangeParams';
4
+ export * from './gridFetchRowsParams';
package/models/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './gridGroupingColDefOverride';
2
2
  export * from './gridRowScrollEndParams';
3
- export * from './gridRowOrderChangeParams';
3
+ export * from './gridRowOrderChangeParams';
4
+ export * from './gridFetchRowsParams';
@@ -106,6 +106,7 @@ DataGridProRaw.propTypes = {
106
106
  * @default 3
107
107
  */
108
108
  columnBuffer: PropTypes.number,
109
+ columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
109
110
 
110
111
  /**
111
112
  * Set of columns of type [[GridColumns]].
@@ -274,6 +275,8 @@ DataGridProRaw.propTypes = {
274
275
  * 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.
275
276
  */
276
277
  experimentalFeatures: PropTypes.shape({
278
+ columnGrouping: PropTypes.bool,
279
+ lazyLoading: PropTypes.bool,
277
280
  newEditingApi: PropTypes.bool,
278
281
  preventCommitWhileValidating: PropTypes.bool,
279
282
  rowPinning: PropTypes.bool,
@@ -668,6 +671,14 @@ DataGridProRaw.propTypes = {
668
671
  */
669
672
  onError: PropTypes.func,
670
673
 
674
+ /**
675
+ * Callback fired when rowCount is set and the next batch of virtualized rows is rendered.
676
+ * @param {GridFetchRowsParams} params With all properties from [[GridFetchRowsParams]].
677
+ * @param {MuiEvent<{}>} event The event object.
678
+ * @param {GridCallbackDetails} details Additional details for this callback.
679
+ */
680
+ onFetchRows: PropTypes.func,
681
+
671
682
  /**
672
683
  * Callback fired when the Filter model changes before the filters are applied.
673
684
  * @param {GridFilterModel} model With all properties from [[GridFilterModel]].
@@ -913,6 +924,14 @@ DataGridProRaw.propTypes = {
913
924
  */
914
925
  rows: PropTypes.array.isRequired,
915
926
 
927
+ /**
928
+ * Loading rows can be processed on the server or client-side.
929
+ * Set it to 'client' if you would like enable infnite loading.
930
+ * Set it to 'server' if you would like to enable lazy loading.
931
+ * * @default "client"
932
+ */
933
+ rowsLoadingMode: PropTypes.oneOf(['client', 'server']),
934
+
916
935
  /**
917
936
  * Sets the type of space between rows added by `getRowSpacing`.
918
937
  * @default "margin"
@@ -1,4 +1,4 @@
1
- import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing_new, useGridEditing_old, editingStateInitializer_old, editingStateInitializer_new, useGridRows, useGridRowsPreProcessors, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, useGridColumnSpanning, columnMenuStateInitializer, densityStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer } from '@mui/x-data-grid/internals';
1
+ import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing_new, useGridEditing_old, editingStateInitializer_old, editingStateInitializer_new, useGridRows, useGridRowsPreProcessors, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, useGridColumnSpanning, columnMenuStateInitializer, densityStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer, useGridColumnGrouping, columnGroupsStateInitializer, useGridColumnGroupingPreProcessors } from '@mui/x-data-grid/internals';
2
2
  // Pro-only features
3
3
  import { useGridInfiniteLoader } from '../hooks/features/infiniteLoader/useGridInfiniteLoader';
4
4
  import { useGridColumnReorder, columnReorderStateInitializer } from '../hooks/features/columnReorder/useGridColumnReorder';
@@ -11,6 +11,8 @@ import { useGridDetailPanel, detailPanelStateInitializer } from '../hooks/featur
11
11
  import { useGridDetailPanelPreProcessors } from '../hooks/features/detailPanel/useGridDetailPanelPreProcessors';
12
12
  import { useGridRowReorder } from '../hooks/features/rowReorder/useGridRowReorder';
13
13
  import { useGridRowReorderPreProcessors } from '../hooks/features/rowReorder/useGridRowReorderPreProcessors';
14
+ import { useGridLazyLoader } from '../hooks/features/lazyLoader/useGridLazyLoader';
15
+ import { useGridLazyLoaderPreProcessors } from '../hooks/features/lazyLoader/useGridLazyLoaderPreProcessors';
14
16
  import { useGridRowPinning, rowPinningStateInitializer } from '../hooks/features/rowPinning/useGridRowPinning';
15
17
  import { useGridRowPinningPreProcessors } from '../hooks/features/rowPinning/useGridRowPinningPreProcessors';
16
18
  export const useDataGridProComponent = (inputApiRef, props) => {
@@ -19,9 +21,11 @@ export const useDataGridProComponent = (inputApiRef, props) => {
19
21
  * Register all pre-processors called during state initialization here.
20
22
  */
21
23
 
24
+ useGridColumnGroupingPreProcessors(apiRef, props);
22
25
  useGridSelectionPreProcessors(apiRef, props);
23
26
  useGridRowReorderPreProcessors(apiRef, props);
24
27
  useGridTreeDataPreProcessors(apiRef, props);
28
+ useGridLazyLoaderPreProcessors(apiRef, props);
25
29
  useGridRowPinningPreProcessors(apiRef);
26
30
  useGridDetailPanelPreProcessors(apiRef, props); // The column pinning `hydrateColumns` pre-processor must be after every other `hydrateColumns` pre-processors
27
31
  // Because it changes the order of the columns.
@@ -49,6 +53,7 @@ export const useDataGridProComponent = (inputApiRef, props) => {
49
53
  useGridInitializeState(paginationStateInitializer, apiRef, props);
50
54
  useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
51
55
  useGridInitializeState(columnMenuStateInitializer, apiRef, props);
56
+ useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
52
57
  useGridTreeData(apiRef);
53
58
  useGridKeyboardNavigation(apiRef, props);
54
59
  useGridSelection(apiRef, props);
@@ -59,6 +64,7 @@ export const useDataGridProComponent = (inputApiRef, props) => {
59
64
  useGridParamsApi(apiRef);
60
65
  useGridDetailPanel(apiRef, props);
61
66
  useGridColumnSpanning(apiRef);
67
+ useGridColumnGrouping(apiRef, props);
62
68
  const useGridEditing = props.experimentalFeatures?.newEditingApi ? useGridEditing_new : useGridEditing_old;
63
69
  useGridEditing(apiRef, props);
64
70
  useGridFocus(apiRef, props);
@@ -73,6 +79,7 @@ export const useDataGridProComponent = (inputApiRef, props) => {
73
79
  useGridRowReorder(apiRef, props);
74
80
  useGridScroll(apiRef, props);
75
81
  useGridInfiniteLoader(apiRef, props);
82
+ useGridLazyLoader(apiRef, props);
76
83
  useGridColumnMenu(apiRef);
77
84
  useGridCsvExport(apiRef);
78
85
  useGridPrintExport(apiRef, props);
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { useThemeProps } from '@mui/material/styles';
4
- import { DATA_GRID_DEFAULT_SLOTS_COMPONENTS, GRID_DEFAULT_LOCALE_TEXT, DATA_GRID_PROPS_DEFAULT_VALUES } from '@mui/x-data-grid';
4
+ import { DATA_GRID_DEFAULT_SLOTS_COMPONENTS, GRID_DEFAULT_LOCALE_TEXT, DATA_GRID_PROPS_DEFAULT_VALUES, GridFeatureModeConstant } from '@mui/x-data-grid';
5
5
 
6
6
  /**
7
7
  * The default values of `DataGridProPropsWithDefaultValue` to inject in the props of DataGridPro.
@@ -14,6 +14,7 @@ export const DATA_GRID_PRO_PROPS_DEFAULT_VALUES = _extends({}, DATA_GRID_PROPS_D
14
14
  disableChildrenFiltering: false,
15
15
  disableChildrenSorting: false,
16
16
  rowReordering: false,
17
+ rowsLoadingMode: GridFeatureModeConstant.client,
17
18
  getDetailPanelHeight: () => 500
18
19
  });
19
20
  export const useDataGridProProps = inProps => {
@@ -11,7 +11,6 @@ import { useGridRootProps } from '../hooks/utils/useGridRootProps';
11
11
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
12
12
  import { gridPinnedColumnsSelector, GridPinnedPosition } from '../hooks/features/columnPinning';
13
13
  import { filterColumns } from './DataGridProVirtualScroller';
14
- import { jsx as _jsx } from "react/jsx-runtime";
15
14
  import { jsxs as _jsxs } from "react/jsx-runtime";
16
15
 
17
16
  const useUtilityClasses = ownerState => {
@@ -57,6 +56,7 @@ const GridColumnHeadersPinnedColumnHeaders = styled('div', {
57
56
  height: '100%',
58
57
  zIndex: 1,
59
58
  display: 'flex',
59
+ flexDirection: 'column',
60
60
  boxShadow: theme.shadows[2],
61
61
  backgroundColor: theme.palette.background.default
62
62
  }, theme.palette.mode === 'dark' && {
@@ -98,7 +98,8 @@ export const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function D
98
98
  renderContext,
99
99
  getRootProps,
100
100
  getInnerProps,
101
- getColumns
101
+ getColumnHeaders,
102
+ getColumnGroupHeaders
102
103
  } = useGridColumnHeaders({
103
104
  innerRef,
104
105
  minColumnIndex: leftPinnedColumns.length
@@ -119,35 +120,42 @@ export const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function D
119
120
  }) : null;
120
121
  const innerProps = getInnerProps();
121
122
  const pinnedColumnHeadersProps = {
122
- role: innerProps.role,
123
- 'aria-rowindex': innerProps['aria-rowindex']
123
+ role: innerProps.role
124
124
  };
125
125
  return /*#__PURE__*/_jsxs(GridColumnHeaders, _extends({
126
126
  ref: ref,
127
127
  className: className
128
128
  }, getRootProps(other), {
129
- children: [leftRenderContext && /*#__PURE__*/_jsx(GridColumnHeadersPinnedColumnHeaders, _extends({
129
+ children: [leftRenderContext && /*#__PURE__*/_jsxs(GridColumnHeadersPinnedColumnHeaders, _extends({
130
130
  className: classes.leftPinnedColumns,
131
131
  ownerState: {
132
132
  side: GridPinnedPosition.left
133
133
  }
134
134
  }, pinnedColumnHeadersProps, {
135
- children: getColumns({
135
+ children: [getColumnGroupHeaders({
136
+ renderContext: leftRenderContext,
137
+ minFirstColumn: leftRenderContext.firstColumnIndex,
138
+ maxLastColumn: leftRenderContext.lastColumnIndex
139
+ }), getColumnHeaders({
136
140
  renderContext: leftRenderContext,
137
141
  minFirstColumn: leftRenderContext.firstColumnIndex,
138
142
  maxLastColumn: leftRenderContext.lastColumnIndex
139
143
  }, {
140
144
  disableReorder: true
141
- })
142
- })), /*#__PURE__*/_jsx(GridColumnHeadersInner, _extends({
145
+ })]
146
+ })), /*#__PURE__*/_jsxs(GridColumnHeadersInner, _extends({
143
147
  isDragging: isDragging
144
148
  }, innerProps, {
145
- children: getColumns({
149
+ children: [getColumnGroupHeaders({
146
150
  renderContext,
147
151
  minFirstColumn: leftPinnedColumns.length,
148
152
  maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
149
- })
150
- })), rightRenderContext && /*#__PURE__*/_jsx(GridColumnHeadersPinnedColumnHeaders, _extends({
153
+ }), getColumnHeaders({
154
+ renderContext,
155
+ minFirstColumn: leftPinnedColumns.length,
156
+ maxLastColumn: visibleColumnFields.length - rightPinnedColumns.length
157
+ })]
158
+ })), rightRenderContext && /*#__PURE__*/_jsxs(GridColumnHeadersPinnedColumnHeaders, _extends({
151
159
  ownerState: {
152
160
  side: GridPinnedPosition.right
153
161
  },
@@ -156,14 +164,18 @@ export const DataGridProColumnHeaders = /*#__PURE__*/React.forwardRef(function D
156
164
  paddingRight: scrollbarSize
157
165
  }
158
166
  }, pinnedColumnHeadersProps, {
159
- children: getColumns({
167
+ children: [getColumnGroupHeaders({
168
+ renderContext: rightRenderContext,
169
+ minFirstColumn: rightRenderContext.firstColumnIndex,
170
+ maxLastColumn: rightRenderContext.lastColumnIndex
171
+ }), getColumnHeaders({
160
172
  renderContext: rightRenderContext,
161
173
  minFirstColumn: rightRenderContext.firstColumnIndex,
162
174
  maxLastColumn: rightRenderContext.lastColumnIndex
163
175
  }, {
164
176
  disableReorder: true,
165
177
  separatorSide: GridColumnHeaderSeparatorSides.Left
166
- })
178
+ })]
167
179
  }))]
168
180
  }));
169
181
  });
@@ -272,17 +272,20 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
272
272
  const detailPanels = getDetailPanels();
273
273
  const topPinnedRows = getRows({
274
274
  renderContext,
275
- rows: topPinnedRowsData
275
+ rows: topPinnedRowsData,
276
+ position: 'center'
276
277
  });
277
278
  const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
278
279
  const mainRows = getRows({
279
280
  renderContext,
280
- rowIndexOffset: topPinnedRowsData.length
281
+ rowIndexOffset: topPinnedRowsData.length,
282
+ position: 'center'
281
283
  });
282
284
  const bottomPinnedRows = getRows({
283
285
  renderContext,
284
286
  rows: bottomPinnedRowsData,
285
- rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0)
287
+ rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0),
288
+ position: 'center'
286
289
  });
287
290
  const contentProps = getContentProps();
288
291
  const pinnedColumnsStyle = {
@@ -314,8 +317,8 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
314
317
  minFirstColumn: leftRenderContext.firstColumnIndex,
315
318
  maxLastColumn: leftRenderContext.lastColumnIndex,
316
319
  availableSpace: 0,
317
- ignoreAutoHeight: true,
318
- rows: topPinnedRowsData
320
+ rows: topPinnedRowsData,
321
+ position: 'left'
319
322
  })
320
323
  }), /*#__PURE__*/_jsx(VirtualScrollerPinnedRowsRenderZone, {
321
324
  className: classes.pinnedRowsRenderZone,
@@ -331,9 +334,9 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
331
334
  renderContext: rightRenderContext,
332
335
  minFirstColumn: rightRenderContext.firstColumnIndex,
333
336
  maxLastColumn: rightRenderContext.lastColumnIndex,
334
- ignoreAutoHeight: true,
335
337
  availableSpace: 0,
336
- rows: topPinnedRowsData
338
+ rows: topPinnedRowsData,
339
+ position: 'right'
337
340
  })
338
341
  })]
339
342
  }) : null, /*#__PURE__*/_jsxs(GridVirtualScrollerContent, _extends({}, contentProps, {
@@ -349,8 +352,8 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
349
352
  minFirstColumn: leftRenderContext.firstColumnIndex,
350
353
  maxLastColumn: leftRenderContext.lastColumnIndex,
351
354
  availableSpace: 0,
352
- ignoreAutoHeight: true,
353
- rowIndexOffset: topPinnedRowsData.length
355
+ rowIndexOffset: topPinnedRowsData.length,
356
+ position: 'left'
354
357
  })
355
358
  }), /*#__PURE__*/_jsx(GridVirtualScrollerRenderZone, _extends({}, getRenderZoneProps(), {
356
359
  children: mainRows
@@ -366,8 +369,8 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
366
369
  minFirstColumn: rightRenderContext.firstColumnIndex,
367
370
  maxLastColumn: rightRenderContext.lastColumnIndex,
368
371
  availableSpace: 0,
369
- ignoreAutoHeight: true,
370
- rowIndexOffset: topPinnedRowsData.length
372
+ rowIndexOffset: topPinnedRowsData.length,
373
+ position: 'right'
371
374
  })
372
375
  }), detailPanels.length > 0 && /*#__PURE__*/_jsx(VirtualScrollerDetailPanels, {
373
376
  className: classes.detailPanels,
@@ -393,9 +396,9 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
393
396
  minFirstColumn: leftRenderContext.firstColumnIndex,
394
397
  maxLastColumn: leftRenderContext.lastColumnIndex,
395
398
  availableSpace: 0,
396
- ignoreAutoHeight: true,
397
399
  rows: bottomPinnedRowsData,
398
- rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0)
400
+ rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0),
401
+ position: 'left'
399
402
  })
400
403
  }), /*#__PURE__*/_jsx(VirtualScrollerPinnedRowsRenderZone, {
401
404
  className: classes.pinnedRowsRenderZone,
@@ -412,9 +415,9 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
412
415
  minFirstColumn: rightRenderContext.firstColumnIndex,
413
416
  maxLastColumn: rightRenderContext.lastColumnIndex,
414
417
  availableSpace: 0,
415
- ignoreAutoHeight: true,
416
418
  rows: bottomPinnedRowsData,
417
- rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0)
419
+ rowIndexOffset: topPinnedRowsData.length + (mainRows ? mainRows.length : 0),
420
+ position: 'right'
418
421
  })
419
422
  })]
420
423
  }) : null]
@@ -129,7 +129,8 @@ process.env.NODE_ENV !== "production" ? GridDetailPanelToggleCell.propTypes = {
129
129
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
130
130
 
131
131
  /**
132
- * The cell value, but if the column has valueGetter, use getValue.
132
+ * The cell value.
133
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
133
134
  */
134
135
  value: PropTypes.any
135
136
  } : void 0;
@@ -162,7 +162,8 @@ process.env.NODE_ENV !== "production" ? GridTreeDataGroupingCell.propTypes = {
162
162
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
163
163
 
164
164
  /**
165
- * The cell value, but if the column has valueGetter, use getValue.
165
+ * The cell value.
166
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
166
167
  */
167
168
  value: PropTypes.any
168
169
  } : void 0;
@@ -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
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
4
4
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_DETAIL_PANEL_TOGGLE_COL_DEF } from './gridDetailPanelToggleColDef';
5
+ import { gridDetailPanelExpandedRowIdsSelector } from './gridDetailPanelSelector';
5
6
  export const useGridDetailPanelPreProcessors = (apiRef, props) => {
6
7
  const addToggleColumn = React.useCallback(columnsState => {
7
8
  if (props.getDetailPanelContent == null) {
@@ -27,5 +28,19 @@ export const useGridDetailPanelPreProcessors = (apiRef, props) => {
27
28
  });
28
29
  return columnsState;
29
30
  }, [apiRef, props.getDetailPanelContent]);
31
+ const addExpandedClassToRow = React.useCallback((classes, id) => {
32
+ if (props.getDetailPanelContent == null) {
33
+ return classes;
34
+ }
35
+
36
+ const expandedRowIds = gridDetailPanelExpandedRowIdsSelector(apiRef.current.state);
37
+
38
+ if (!expandedRowIds.includes(id)) {
39
+ return classes;
40
+ }
41
+
42
+ return [...classes, 'MuiDataGrid-row--detailPanelExpanded'];
43
+ }, [apiRef, props.getDetailPanelContent]);
30
44
  useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', addToggleColumn);
45
+ useGridRegisterPipeProcessor(apiRef, 'rowClassName', addExpandedClassToRow);
31
46
  };
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { useGridSelector, useGridApiEventHandler, useGridApiOptionHandler, gridVisibleColumnDefinitionsSelector, gridRowsMetaSelector } from '@mui/x-data-grid';
2
+ import { useGridSelector, useGridApiEventHandler, useGridApiOptionHandler, gridVisibleColumnDefinitionsSelector, gridRowsMetaSelector, GridFeatureModeConstant } from '@mui/x-data-grid';
3
3
  import { useGridVisibleRows } from '@mui/x-data-grid/internals';
4
4
 
5
5
  /**
@@ -14,9 +14,9 @@ export const useGridInfiniteLoader = (apiRef, props) => {
14
14
  const contentHeight = Math.max(rowsMeta.currentPageTotalHeight, 1);
15
15
  const isInScrollBottomArea = React.useRef(false);
16
16
  const handleRowsScrollEnd = React.useCallback(scrollPosition => {
17
- const dimensions = apiRef.current.getRootDimensions();
17
+ const dimensions = apiRef.current.getRootDimensions(); // Prevent the infite loading working in combination with lazy loading
18
18
 
19
- if (!dimensions) {
19
+ if (!dimensions || props.rowsLoadingMode !== GridFeatureModeConstant.client) {
20
20
  return;
21
21
  }
22
22
 
@@ -36,7 +36,7 @@ export const useGridInfiniteLoader = (apiRef, props) => {
36
36
  apiRef.current.publishEvent('rowsScrollEnd', rowScrollEndParam);
37
37
  isInScrollBottomArea.current = true;
38
38
  }
39
- }, [contentHeight, props.scrollEndThreshold, visibleColumns, apiRef, currentPage.rows.length]);
39
+ }, [contentHeight, props.scrollEndThreshold, props.rowsLoadingMode, visibleColumns, apiRef, currentPage.rows.length]);
40
40
  const handleGridScroll = React.useCallback(({
41
41
  left,
42
42
  top