@mui/x-data-grid 8.8.0 → 8.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 (196) hide show
  1. package/CHANGELOG.md +225 -24
  2. package/DataGrid/DataGrid.js +5 -0
  3. package/DataGrid/index.d.ts +0 -1
  4. package/DataGrid/useDataGridComponent.js +10 -0
  5. package/colDef/gridCheckboxSelectionColDef.js +1 -0
  6. package/components/GridDetailPanels.d.ts +2 -2
  7. package/components/GridPinnedRows.d.ts +2 -2
  8. package/components/GridRow.js +5 -0
  9. package/components/GridScrollArea.js +1 -1
  10. package/components/cell/GridCell.js +7 -5
  11. package/components/cell/GridEditSingleSelectCell.js +1 -1
  12. package/components/columnsManagement/GridColumnsManagement.d.ts +6 -0
  13. package/components/columnsManagement/GridColumnsManagement.js +17 -5
  14. package/components/containers/GridRootStyles.d.ts +1 -1
  15. package/components/containers/GridRootStyles.js +39 -0
  16. package/components/toolbarV8/Toolbar.d.ts +1 -1
  17. package/components/virtualization/GridVirtualScroller.js +5 -5
  18. package/constants/dataGridPropsDefaultValues.js +1 -0
  19. package/constants/gridClasses.d.ts +12 -0
  20. package/constants/gridClasses.js +3 -1
  21. package/esm/DataGrid/DataGrid.js +5 -0
  22. package/esm/DataGrid/index.d.ts +0 -1
  23. package/esm/DataGrid/useDataGridComponent.js +10 -0
  24. package/esm/colDef/gridCheckboxSelectionColDef.js +1 -0
  25. package/esm/components/GridDetailPanels.d.ts +2 -2
  26. package/esm/components/GridPinnedRows.d.ts +2 -2
  27. package/esm/components/GridRow.js +5 -0
  28. package/esm/components/GridScrollArea.js +1 -1
  29. package/esm/components/cell/GridCell.js +7 -5
  30. package/esm/components/cell/GridEditSingleSelectCell.js +1 -1
  31. package/esm/components/columnsManagement/GridColumnsManagement.d.ts +6 -0
  32. package/esm/components/columnsManagement/GridColumnsManagement.js +17 -5
  33. package/esm/components/containers/GridRootStyles.d.ts +1 -1
  34. package/esm/components/containers/GridRootStyles.js +39 -0
  35. package/esm/components/toolbarV8/Toolbar.d.ts +1 -1
  36. package/esm/components/virtualization/GridVirtualScroller.js +5 -5
  37. package/esm/constants/dataGridPropsDefaultValues.js +1 -0
  38. package/esm/constants/gridClasses.d.ts +12 -0
  39. package/esm/constants/gridClasses.js +3 -1
  40. package/esm/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -0
  41. package/esm/hooks/core/pipeProcessing/useGridPipeProcessing.js +20 -5
  42. package/esm/hooks/core/useGridProps.d.ts +2 -2
  43. package/esm/hooks/core/useGridProps.js +3 -1
  44. package/esm/hooks/core/useGridVirtualizer.d.ts +9 -0
  45. package/esm/hooks/core/useGridVirtualizer.js +223 -0
  46. package/esm/hooks/features/columnGrouping/gridColumnGroupsInterfaces.d.ts +4 -1
  47. package/esm/hooks/features/columnGrouping/gridColumnGroupsUtils.js +35 -32
  48. package/esm/hooks/features/columnGrouping/useGridColumnGrouping.js +18 -13
  49. package/esm/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +1 -1
  50. package/esm/hooks/features/columnHeaders/useGridColumnHeaders.js +3 -2
  51. package/esm/hooks/features/columns/gridColumnsInterfaces.d.ts +3 -3
  52. package/esm/hooks/features/columns/gridColumnsSelector.js +6 -2
  53. package/esm/hooks/features/columns/gridColumnsUtils.js +6 -4
  54. package/esm/hooks/features/columns/useGridColumnSpanning.js +5 -90
  55. package/esm/hooks/features/columns/useGridColumns.js +8 -10
  56. package/esm/hooks/features/dimensions/useGridDimensions.js +18 -188
  57. package/esm/hooks/features/export/utils.js +1 -1
  58. package/esm/hooks/features/filter/useGridFilter.js +3 -3
  59. package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  60. package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +6 -10
  61. package/esm/hooks/features/keyboardNavigation/utils.d.ts +3 -3
  62. package/esm/hooks/features/keyboardNavigation/utils.js +5 -5
  63. package/esm/hooks/features/listView/gridListViewSelectors.d.ts +8 -1
  64. package/esm/hooks/features/listView/gridListViewSelectors.js +7 -0
  65. package/esm/hooks/features/pivoting/gridPivotingInterfaces.d.ts +0 -1
  66. package/esm/hooks/features/pivoting/gridPivotingSelectors.d.ts +1 -4
  67. package/esm/hooks/features/pivoting/gridPivotingSelectors.js +1 -2
  68. package/esm/hooks/features/rowSelection/useGridRowSelection.js +5 -4
  69. package/esm/hooks/features/rows/gridRowsMetaInterfaces.d.ts +2 -8
  70. package/esm/hooks/features/rows/gridRowsMetaState.d.ts +2 -18
  71. package/esm/hooks/features/rows/gridRowsUtils.d.ts +1 -1
  72. package/esm/hooks/features/rows/gridRowsUtils.js +5 -2
  73. package/esm/hooks/features/rows/useGridRowAriaAttributes.js +3 -1
  74. package/esm/hooks/features/rows/useGridRowSpanning.d.ts +2 -12
  75. package/esm/hooks/features/rows/useGridRowSpanning.js +54 -85
  76. package/esm/hooks/features/rows/useGridRows.js +4 -3
  77. package/esm/hooks/features/rows/useGridRowsMeta.d.ts +1 -1
  78. package/esm/hooks/features/rows/useGridRowsMeta.js +17 -187
  79. package/esm/hooks/features/scroll/useGridScroll.d.ts +1 -1
  80. package/esm/hooks/features/scroll/useGridScroll.js +2 -3
  81. package/esm/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +1 -1
  82. package/esm/hooks/features/virtualization/index.d.ts +1 -0
  83. package/esm/hooks/features/virtualization/index.js +1 -0
  84. package/esm/hooks/features/virtualization/useGridVirtualization.d.ts +5 -16
  85. package/esm/hooks/features/virtualization/useGridVirtualization.js +41 -22
  86. package/esm/hooks/utils/index.d.ts +2 -1
  87. package/esm/hooks/utils/index.js +2 -1
  88. package/esm/hooks/utils/useFirstRender.d.ts +1 -1
  89. package/esm/hooks/utils/useFirstRender.js +1 -8
  90. package/esm/hooks/utils/useGridInitializeState.d.ts +1 -1
  91. package/esm/hooks/utils/useGridInitializeState.js +6 -1
  92. package/esm/hooks/utils/useRunOncePerLoop.d.ts +1 -0
  93. package/esm/hooks/utils/useRunOncePerLoop.js +26 -0
  94. package/esm/index.js +1 -1
  95. package/esm/internals/index.d.ts +1 -1
  96. package/esm/internals/index.js +1 -1
  97. package/esm/internals/utils/getPinnedCellOffset.js +5 -0
  98. package/esm/locales/frFR.js +18 -21
  99. package/esm/locales/heIL.js +12 -12
  100. package/esm/locales/plPL.js +22 -24
  101. package/esm/models/api/gridApiCommon.d.ts +4 -1
  102. package/esm/models/api/gridColumnSpanning.d.ts +5 -11
  103. package/esm/models/api/gridRowApi.d.ts +5 -0
  104. package/esm/models/events/gridEventLookup.d.ts +2 -1
  105. package/esm/models/gridApiCaches.d.ts +8 -2
  106. package/esm/models/gridStateCommunity.d.ts +2 -2
  107. package/esm/models/props/DataGridProps.d.ts +5 -0
  108. package/esm/utils/roundToDecimalPlaces.d.ts +1 -1
  109. package/esm/utils/roundToDecimalPlaces.js +1 -3
  110. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -0
  111. package/hooks/core/pipeProcessing/useGridPipeProcessing.js +20 -5
  112. package/hooks/core/useGridProps.d.ts +2 -2
  113. package/hooks/core/useGridProps.js +3 -1
  114. package/hooks/core/useGridVirtualizer.d.ts +9 -0
  115. package/hooks/core/useGridVirtualizer.js +231 -0
  116. package/hooks/features/columnGrouping/gridColumnGroupsInterfaces.d.ts +4 -1
  117. package/hooks/features/columnGrouping/gridColumnGroupsUtils.js +35 -32
  118. package/hooks/features/columnGrouping/useGridColumnGrouping.js +18 -13
  119. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +1 -1
  120. package/hooks/features/columnHeaders/useGridColumnHeaders.js +4 -3
  121. package/hooks/features/columns/gridColumnsInterfaces.d.ts +3 -3
  122. package/hooks/features/columns/gridColumnsSelector.js +6 -2
  123. package/hooks/features/columns/gridColumnsUtils.js +6 -4
  124. package/hooks/features/columns/useGridColumnSpanning.js +5 -91
  125. package/hooks/features/columns/useGridColumns.js +8 -10
  126. package/hooks/features/dimensions/useGridDimensions.js +18 -188
  127. package/hooks/features/export/utils.js +1 -1
  128. package/hooks/features/filter/useGridFilter.js +3 -3
  129. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  130. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +6 -10
  131. package/hooks/features/keyboardNavigation/utils.d.ts +3 -3
  132. package/hooks/features/keyboardNavigation/utils.js +5 -5
  133. package/hooks/features/listView/gridListViewSelectors.d.ts +8 -1
  134. package/hooks/features/listView/gridListViewSelectors.js +8 -1
  135. package/hooks/features/pivoting/gridPivotingInterfaces.d.ts +0 -1
  136. package/hooks/features/pivoting/gridPivotingSelectors.d.ts +1 -4
  137. package/hooks/features/pivoting/gridPivotingSelectors.js +2 -3
  138. package/hooks/features/rowSelection/useGridRowSelection.js +5 -4
  139. package/hooks/features/rows/gridRowsMetaInterfaces.d.ts +2 -8
  140. package/hooks/features/rows/gridRowsMetaState.d.ts +2 -18
  141. package/hooks/features/rows/gridRowsUtils.d.ts +1 -1
  142. package/hooks/features/rows/gridRowsUtils.js +5 -2
  143. package/hooks/features/rows/useGridRowAriaAttributes.js +3 -1
  144. package/hooks/features/rows/useGridRowSpanning.d.ts +2 -12
  145. package/hooks/features/rows/useGridRowSpanning.js +54 -85
  146. package/hooks/features/rows/useGridRows.js +4 -3
  147. package/hooks/features/rows/useGridRowsMeta.d.ts +1 -1
  148. package/hooks/features/rows/useGridRowsMeta.js +15 -186
  149. package/hooks/features/scroll/useGridScroll.d.ts +1 -1
  150. package/hooks/features/scroll/useGridScroll.js +2 -3
  151. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +1 -1
  152. package/hooks/features/virtualization/index.d.ts +1 -0
  153. package/hooks/features/virtualization/index.js +12 -0
  154. package/hooks/features/virtualization/useGridVirtualization.d.ts +5 -16
  155. package/hooks/features/virtualization/useGridVirtualization.js +42 -24
  156. package/hooks/utils/index.d.ts +2 -1
  157. package/hooks/utils/index.js +16 -4
  158. package/hooks/utils/useFirstRender.d.ts +1 -1
  159. package/hooks/utils/useFirstRender.js +11 -11
  160. package/hooks/utils/useGridInitializeState.d.ts +1 -1
  161. package/hooks/utils/useGridInitializeState.js +6 -1
  162. package/hooks/utils/useRunOncePerLoop.d.ts +1 -0
  163. package/hooks/utils/useRunOncePerLoop.js +33 -0
  164. package/index.js +1 -1
  165. package/internals/index.d.ts +1 -1
  166. package/internals/index.js +4 -11
  167. package/internals/utils/getPinnedCellOffset.js +5 -0
  168. package/locales/frFR.js +18 -21
  169. package/locales/heIL.js +12 -12
  170. package/locales/plPL.js +22 -24
  171. package/models/api/gridApiCommon.d.ts +4 -1
  172. package/models/api/gridColumnSpanning.d.ts +5 -11
  173. package/models/api/gridRowApi.d.ts +5 -0
  174. package/models/events/gridEventLookup.d.ts +2 -1
  175. package/models/gridApiCaches.d.ts +8 -2
  176. package/models/gridStateCommunity.d.ts +2 -2
  177. package/models/props/DataGridProps.d.ts +5 -0
  178. package/package.json +5 -5
  179. package/utils/roundToDecimalPlaces.d.ts +1 -1
  180. package/utils/roundToDecimalPlaces.js +7 -4
  181. package/esm/hooks/features/rows/gridRowSpanningSelectors.d.ts +0 -10
  182. package/esm/hooks/features/rows/gridRowSpanningSelectors.js +0 -5
  183. package/esm/hooks/features/virtualization/useGridVirtualScroller.d.ts +0 -56
  184. package/esm/hooks/features/virtualization/useGridVirtualScroller.js +0 -846
  185. package/esm/hooks/utils/useRunOnce.d.ts +0 -5
  186. package/esm/hooks/utils/useRunOnce.js +0 -18
  187. package/esm/utils/platform.d.ts +0 -1
  188. package/esm/utils/platform.js +0 -2
  189. package/hooks/features/rows/gridRowSpanningSelectors.d.ts +0 -10
  190. package/hooks/features/rows/gridRowSpanningSelectors.js +0 -11
  191. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +0 -56
  192. package/hooks/features/virtualization/useGridVirtualScroller.js +0 -857
  193. package/hooks/utils/useRunOnce.d.ts +0 -5
  194. package/hooks/utils/useRunOnce.js +0 -27
  195. package/utils/platform.d.ts +0 -1
  196. package/utils/platform.js +0 -8
@@ -49,7 +49,8 @@ export const useGridPipeProcessing = apiRef => {
49
49
  cache.current[group] = {
50
50
  processors: new Map(),
51
51
  processorsAsArray: [],
52
- appliers: {}
52
+ appliers: {},
53
+ processorsUpdated: false
53
54
  };
54
55
  }
55
56
  const groupCache = cache.current[group];
@@ -57,19 +58,20 @@ export const useGridPipeProcessing = apiRef => {
57
58
  if (oldProcessor !== processor) {
58
59
  groupCache.processors.set(id, processor);
59
60
  groupCache.processorsAsArray = Array.from(cache.current[group].processors.values()).filter(processorValue => processorValue !== null);
60
- runAppliers(groupCache);
61
+ groupCache.processorsUpdated = true;
61
62
  }
62
63
  return () => {
63
64
  cache.current[group].processors.set(id, null);
64
65
  cache.current[group].processorsAsArray = Array.from(cache.current[group].processors.values()).filter(processorValue => processorValue !== null);
65
66
  };
66
- }, [runAppliers]);
67
+ }, []);
67
68
  const registerPipeApplier = React.useCallback((group, id, applier) => {
68
69
  if (!cache.current[group]) {
69
70
  cache.current[group] = {
70
71
  processors: new Map(),
71
72
  processorsAsArray: [],
72
- appliers: {}
73
+ appliers: {},
74
+ processorsUpdated: false
73
75
  };
74
76
  }
75
77
  cache.current[group].appliers[id] = applier;
@@ -82,6 +84,18 @@ export const useGridPipeProcessing = apiRef => {
82
84
  const requestPipeProcessorsApplication = React.useCallback(group => {
83
85
  runAppliers(cache.current[group]);
84
86
  }, [runAppliers]);
87
+ const runAppliersForPendingProcessors = React.useCallback(() => {
88
+ for (const group in cache.current) {
89
+ if (!Object.prototype.hasOwnProperty.call(cache.current, group)) {
90
+ continue;
91
+ }
92
+ const groupCache = cache.current[group];
93
+ if (groupCache.processorsUpdated) {
94
+ groupCache.processorsUpdated = false;
95
+ runAppliers(groupCache);
96
+ }
97
+ }
98
+ }, [runAppliers]);
85
99
  const applyPipeProcessors = React.useCallback((...args) => {
86
100
  const [group, value, context] = args;
87
101
  if (!cache.current[group]) {
@@ -97,7 +111,8 @@ export const useGridPipeProcessing = apiRef => {
97
111
  const preProcessingPrivateApi = {
98
112
  registerPipeProcessor,
99
113
  registerPipeApplier,
100
- requestPipeProcessorsApplication
114
+ requestPipeProcessorsApplication,
115
+ runAppliersForPendingProcessors
101
116
  };
102
117
  const preProcessingPublicApi = {
103
118
  unstable_applyPipeProcessors: applyPipeProcessors
@@ -1,8 +1,8 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
- import type { DataGridProps } from "../../models/props/DataGridProps.js";
2
+ import type { DataGridProcessedProps } from "../../models/props/DataGridProps.js";
3
3
  import type { GridPrivateApiCommon } from "../../models/api/gridApiCommon.js";
4
4
  import type { GridStateInitializer } from "../utils/useGridInitializeState.js";
5
- type Props = Pick<DataGridProps, 'getRowId'>;
5
+ type Props = Pick<DataGridProcessedProps, 'getRowId' | 'listView'>;
6
6
  export declare const propsStateInitializer: GridStateInitializer<Props>;
7
7
  export declare const useGridProps: <PrivateApi extends GridPrivateApiCommon>(apiRef: RefObject<PrivateApi>, props: Props) => void;
8
8
  export {};
@@ -5,6 +5,7 @@ import * as React from 'react';
5
5
  export const propsStateInitializer = (state, props) => {
6
6
  return _extends({}, state, {
7
7
  props: {
8
+ listView: props.listView,
8
9
  getRowId: props.getRowId
9
10
  }
10
11
  });
@@ -13,8 +14,9 @@ export const useGridProps = (apiRef, props) => {
13
14
  React.useEffect(() => {
14
15
  apiRef.current.setState(state => _extends({}, state, {
15
16
  props: {
17
+ listView: props.listView,
16
18
  getRowId: props.getRowId
17
19
  }
18
20
  }));
19
- }, [apiRef, props.getRowId]);
21
+ }, [apiRef, props.listView, props.getRowId]);
20
22
  };
@@ -0,0 +1,9 @@
1
+ import { RefObject } from '@mui/x-internals/types';
2
+ import { GridPrivateApiCommunity } from "../../models/api/gridApiCommunity.js";
3
+ import { DataGridProcessedProps } from "../../models/props/DataGridProps.js";
4
+ type RootProps = DataGridProcessedProps;
5
+ /**
6
+ * Virtualizer setup
7
+ */
8
+ export declare function useGridVirtualizer(apiRef: RefObject<GridPrivateApiCommunity>, rootProps: RootProps): void;
9
+ export {};
@@ -0,0 +1,223 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import useEventCallback from '@mui/utils/useEventCallback';
4
+ import { useRtl } from '@mui/system/RtlProvider';
5
+ import { roundToDecimalPlaces } from '@mui/x-internals/math';
6
+ import { useStoreEffect } from '@mui/x-internals/store';
7
+ import { useVirtualizer } from '@mui/x-virtualizer';
8
+ import { useFirstRender } from "../utils/useFirstRender.js";
9
+ import { createSelector } from "../../utils/createSelector.js";
10
+ import { useGridSelector } from "../utils/useGridSelector.js";
11
+ import { gridContentHeightSelector, gridHasFillerSelector, gridVerticalScrollbarWidthSelector } from "../features/dimensions/gridDimensionsSelectors.js";
12
+ import { gridDensityFactorSelector } from "../features/density/index.js";
13
+ import { gridVisibleColumnDefinitionsSelector, gridVisiblePinnedColumnDefinitionsSelector, gridColumnPositionsSelector, gridHasColSpanSelector } from "../features/columns/gridColumnsSelector.js";
14
+ import { gridPinnedRowsSelector, gridRowCountSelector } from "../features/rows/gridRowsSelector.js";
15
+ import { useGridVisibleRows } from "../utils/useGridVisibleRows.js";
16
+ import { gridPaginationSelector } from "../features/pagination/index.js";
17
+ import { gridFocusedVirtualCellSelector } from "../features/virtualization/gridFocusedVirtualCellSelector.js";
18
+ import { gridRowSelectionManagerSelector } from "../features/rowSelection/index.js";
19
+ import { DATA_GRID_PROPS_DEFAULT_VALUES } from "../../constants/dataGridPropsDefaultValues.js";
20
+ import { getValidRowHeight, minimalContentHeight, rowHeightWarning } from "../features/rows/gridRowsUtils.js";
21
+ import { getTotalHeaderHeight } from "../features/columns/gridColumnsUtils.js";
22
+ import { jsx as _jsx } from "react/jsx-runtime";
23
+ function identity(x) {
24
+ return x;
25
+ }
26
+ const columnsTotalWidthSelector = createSelector(gridVisibleColumnDefinitionsSelector, gridColumnPositionsSelector, (visibleColumns, positions) => {
27
+ const colCount = visibleColumns.length;
28
+ if (colCount === 0) {
29
+ return 0;
30
+ }
31
+ return roundToDecimalPlaces(positions[colCount - 1] + visibleColumns[colCount - 1].computedWidth, 1);
32
+ });
33
+
34
+ /**
35
+ * Virtualizer setup
36
+ */
37
+ export function useGridVirtualizer(apiRef, rootProps) {
38
+ const isRtl = useRtl();
39
+ const {
40
+ listView
41
+ } = rootProps;
42
+ const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
43
+ const pinnedRows = useGridSelector(apiRef, gridPinnedRowsSelector);
44
+ const pinnedColumns = gridVisiblePinnedColumnDefinitionsSelector(apiRef);
45
+ const rowSelectionManager = useGridSelector(apiRef, gridRowSelectionManagerSelector);
46
+ const isRowSelected = id => rowSelectionManager.has(id) && apiRef.current.isRowSelectable(id);
47
+ const currentPage = useGridVisibleRows(apiRef);
48
+ const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector);
49
+
50
+ /* TODO: extract dimensions code */
51
+ const contentHeight = useGridSelector(apiRef, gridContentHeightSelector);
52
+ const verticalScrollbarWidth = useGridSelector(apiRef, gridVerticalScrollbarWidthSelector);
53
+ const hasFiller = useGridSelector(apiRef, gridHasFillerSelector);
54
+ const {
55
+ autoHeight
56
+ } = rootProps;
57
+ const scrollReset = listView;
58
+
59
+ // <DIMENSIONS>
60
+ const density = useGridSelector(apiRef, gridDensityFactorSelector);
61
+ const baseRowHeight = getValidRowHeight(rootProps.rowHeight, DATA_GRID_PROPS_DEFAULT_VALUES.rowHeight, rowHeightWarning);
62
+ const rowHeight = Math.floor(baseRowHeight * density);
63
+ const headerHeight = Math.floor(rootProps.columnHeaderHeight * density);
64
+ const groupHeaderHeight = Math.floor((rootProps.columnGroupHeaderHeight ?? rootProps.columnHeaderHeight) * density);
65
+ const headerFilterHeight = Math.floor((rootProps.headerFilterHeight ?? rootProps.columnHeaderHeight) * density);
66
+ const columnsTotalWidth = useGridSelector(apiRef, columnsTotalWidthSelector);
67
+ const headersTotalHeight = getTotalHeaderHeight(apiRef, rootProps);
68
+ const leftPinnedWidth = pinnedColumns.left.reduce((w, col) => w + col.computedWidth, 0);
69
+ const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0);
70
+ const dimensions = {
71
+ rowHeight,
72
+ headerHeight,
73
+ groupHeaderHeight,
74
+ headerFilterHeight,
75
+ columnsTotalWidth,
76
+ headersTotalHeight,
77
+ leftPinnedWidth,
78
+ rightPinnedWidth
79
+ };
80
+
81
+ // </DIMENSIONS>
82
+
83
+ // <ROWS_META>
84
+ const dataRowCount = useGridSelector(apiRef, gridRowCountSelector);
85
+ const pagination = useGridSelector(apiRef, gridPaginationSelector);
86
+ const rowCount = Math.min(pagination.enabled ? pagination.paginationModel.pageSize : dataRowCount, dataRowCount);
87
+ const {
88
+ getRowHeight,
89
+ getEstimatedRowHeight,
90
+ getRowSpacing
91
+ } = rootProps;
92
+ // </ROWS_META>
93
+
94
+ const focusedVirtualCell = useGridSelector(apiRef, gridFocusedVirtualCellSelector);
95
+ const virtualizer = useVirtualizer({
96
+ scrollbarSize: rootProps.scrollbarSize,
97
+ dimensions,
98
+ initialState: {
99
+ scroll: rootProps.initialState?.scroll,
100
+ dimensions: apiRef.current.state.dimensions,
101
+ rowSpanning: apiRef.current.state.rowSpanning,
102
+ virtualization: apiRef.current.state.virtualization
103
+ },
104
+ isRtl,
105
+ rows: currentPage.rows,
106
+ range: currentPage.range,
107
+ rowIdToIndexMap: currentPage.rowIdToIndexMap,
108
+ rowCount,
109
+ columns: visibleColumns,
110
+ pinnedRows,
111
+ pinnedColumns,
112
+ refs: {
113
+ container: apiRef.current.mainElementRef,
114
+ scroller: apiRef.current.virtualScrollerRef,
115
+ scrollbarVertical: apiRef.current.virtualScrollbarVerticalRef,
116
+ scrollbarHorizontal: apiRef.current.virtualScrollbarHorizontalRef
117
+ },
118
+ hasColSpan,
119
+ contentHeight,
120
+ minimalContentHeight,
121
+ autoHeight,
122
+ getRowHeight: React.useMemo(() => {
123
+ if (!getRowHeight) {
124
+ return undefined;
125
+ }
126
+ return rowEntry => getRowHeight(_extends({}, rowEntry, {
127
+ densityFactor: density
128
+ }));
129
+ }, [getRowHeight, density]),
130
+ getEstimatedRowHeight: React.useMemo(() => getEstimatedRowHeight ? rowEntry => getEstimatedRowHeight(_extends({}, rowEntry, {
131
+ densityFactor: density
132
+ })) : undefined, [getEstimatedRowHeight, density]),
133
+ getRowSpacing: React.useMemo(() => getRowSpacing ? (rowEntry, visibility) => getRowSpacing(_extends({}, rowEntry, visibility, {
134
+ indexRelativeToCurrentPage: apiRef.current.getRowIndexRelativeToVisibleRows(rowEntry.id)
135
+ })) : undefined, [apiRef, getRowSpacing]),
136
+ applyRowHeight: useEventCallback((entry, row) => apiRef.current.unstable_applyPipeProcessors('rowHeight', entry, row)),
137
+ virtualizeColumnsWithAutoRowHeight: rootProps.virtualizeColumnsWithAutoRowHeight,
138
+ focusedVirtualCell: useEventCallback(() => focusedVirtualCell),
139
+ rowBufferPx: rootProps.rowBufferPx,
140
+ columnBufferPx: rootProps.columnBufferPx,
141
+ resizeThrottleMs: rootProps.resizeThrottleMs,
142
+ onResize: useEventCallback(size => apiRef.current.publishEvent('resize', size)),
143
+ onWheel: useEventCallback(event => {
144
+ apiRef.current.publishEvent('virtualScrollerWheel', {}, event);
145
+ }),
146
+ onTouchMove: useEventCallback(event => {
147
+ apiRef.current.publishEvent('virtualScrollerTouchMove', {}, event);
148
+ }),
149
+ onRenderContextChange: useEventCallback(nextRenderContext => {
150
+ apiRef.current.publishEvent('renderedRowsIntervalChange', nextRenderContext);
151
+ }),
152
+ onScrollChange: (scrollPosition, nextRenderContext) => {
153
+ apiRef.current.publishEvent('scrollPositionChange', {
154
+ top: scrollPosition.top,
155
+ left: scrollPosition.left,
156
+ renderContext: nextRenderContext
157
+ });
158
+ },
159
+ scrollReset,
160
+ getColspan: (rowId, column) => {
161
+ if (typeof column.colSpan === 'function') {
162
+ const row = apiRef.current.getRow(rowId);
163
+ const value = apiRef.current.getRowValue(row, column);
164
+ return column.colSpan(value, row, column, apiRef) ?? 0;
165
+ }
166
+ return column.colSpan ?? 0;
167
+ },
168
+ renderRow: params => /*#__PURE__*/_jsx(rootProps.slots.row, _extends({
169
+ row: params.model,
170
+ rowId: params.id,
171
+ index: params.rowIndex,
172
+ selected: isRowSelected(params.id),
173
+ offsetLeft: params.offsetLeft,
174
+ columnsTotalWidth: columnsTotalWidth,
175
+ rowHeight: params.baseRowHeight,
176
+ pinnedColumns: pinnedColumns,
177
+ visibleColumns: params.columns,
178
+ firstColumnIndex: params.firstColumnIndex,
179
+ lastColumnIndex: params.lastColumnIndex,
180
+ focusedColumnIndex: params.focusedColumnIndex,
181
+ isFirstVisible: params.isFirstVisible,
182
+ isLastVisible: params.isLastVisible,
183
+ isNotVisible: params.isVirtualFocusRow,
184
+ showBottomBorder: params.showBottomBorder,
185
+ scrollbarWidth: verticalScrollbarWidth,
186
+ gridHasFiller: hasFiller
187
+ }, rootProps.slotProps?.row), params.id),
188
+ renderInfiniteLoadingTrigger: id => apiRef.current.getInfiniteLoadingTriggerElement?.({
189
+ lastRowId: id
190
+ })
191
+ });
192
+
193
+ // HACK: Keep the grid's store in sync with the virtualizer store. We set up the
194
+ // subscription in the render phase rather than in an effect because other grid
195
+ // initialization code runs between those two moments.
196
+ //
197
+ // TODO(v9): Remove this
198
+ useFirstRender(() => {
199
+ apiRef.current.store.state.dimensions = virtualizer.store.state.dimensions;
200
+ apiRef.current.store.state.rowsMeta = virtualizer.store.state.rowsMeta;
201
+ apiRef.current.store.state.virtualization = virtualizer.store.state.virtualization;
202
+ });
203
+ useStoreEffect(virtualizer.store, identity, (_, state) => {
204
+ if (state.dimensions !== apiRef.current.state.dimensions) {
205
+ apiRef.current.setState(gridState => _extends({}, gridState, {
206
+ dimensions: state.dimensions
207
+ }));
208
+ }
209
+ if (state.rowsMeta !== apiRef.current.state.rowsMeta) {
210
+ apiRef.current.setState(gridState => _extends({}, gridState, {
211
+ rowsMeta: state.rowsMeta
212
+ }));
213
+ }
214
+ if (state.virtualization !== apiRef.current.state.virtualization) {
215
+ apiRef.current.setState(gridState => _extends({}, gridState, {
216
+ virtualization: state.virtualization
217
+ }));
218
+ }
219
+ });
220
+ apiRef.current.register('private', {
221
+ virtualizer
222
+ });
223
+ }
@@ -1,4 +1,4 @@
1
- import { GridColumnGroup } from "../../../models/gridColumnGrouping.js";
1
+ import { GridColumnGroup, GridColumnGroupingModel } from "../../../models/gridColumnGrouping.js";
2
2
  export type GridColumnGroupLookup = {
3
3
  [groupId: string]: Omit<GridColumnGroup, 'children'>;
4
4
  };
@@ -13,4 +13,7 @@ export interface GridColumnsGroupingState {
13
13
  [columnField: string]: GridColumnGroup['groupId'][];
14
14
  };
15
15
  maxDepth: number;
16
+ }
17
+ export interface GridColumnGroupingInternalCache {
18
+ lastColumnGroupingModel?: GridColumnGroupingModel;
16
19
  }
@@ -1,4 +1,3 @@
1
- import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
2
1
  import { isLeaf } from "../../../models/gridColumnGrouping.js";
3
2
  // This is the recurrence function that help writing `unwrapGroupingColumnModel()`
4
3
  const recurrentUnwrapGroupingColumnModel = (columnGroupNode, parents, unwrappedGroupingModelToComplete) => {
@@ -37,45 +36,49 @@ export const unwrapGroupingColumnModel = columnGroupingModel => {
37
36
  export const getColumnGroupsHeaderStructure = (orderedColumns, unwrappedGroupingModel, pinnedFields) => {
38
37
  const getParents = field => unwrappedGroupingModel[field] ?? [];
39
38
  const groupingHeaderStructure = [];
40
- const maxDepth = Math.max(...orderedColumns.map(field => getParents(field).length));
41
- const haveSameParents = (field1, field2, depth) => isDeepEqual(getParents(field1).slice(0, depth + 1), getParents(field2).slice(0, depth + 1));
42
- const haveDifferentContainers = (field1, field2) => {
43
- if (pinnedFields?.left && pinnedFields.left.includes(field1) && !pinnedFields.left.includes(field2)) {
44
- return true;
45
- }
46
- if (pinnedFields?.right && !pinnedFields.right.includes(field1) && pinnedFields.right.includes(field2)) {
47
- return true;
39
+ const maxDepth = Math.max(0, ...orderedColumns.map(field => getParents(field).length));
40
+ const haveSameParents = (field1, field2, depth) => {
41
+ const a = getParents(field1);
42
+ const b = getParents(field2);
43
+ for (let i = 0; i <= depth; i += 1) {
44
+ if (a[i] !== b[i]) {
45
+ return false;
46
+ }
48
47
  }
49
- return false;
48
+ return true;
49
+ };
50
+ const haveDifferentContainers = (field1, field2) => {
51
+ const left = pinnedFields?.left;
52
+ const right = pinnedFields?.right;
53
+ const inLeft1 = !!left?.includes(field1);
54
+ const inLeft2 = !!left?.includes(field2);
55
+ const inRight1 = !!right?.includes(field1);
56
+ const inRight2 = !!right?.includes(field2);
57
+ return inLeft1 !== inLeft2 || inRight1 !== inRight2;
50
58
  };
51
59
  for (let depth = 0; depth < maxDepth; depth += 1) {
52
- const depthStructure = orderedColumns.reduce((structure, newField) => {
53
- const groupId = getParents(newField)[depth] ?? null;
54
- if (structure.length === 0) {
55
- return [{
56
- columnFields: [newField],
60
+ const depthStructure = [];
61
+ for (let i = 0; i < orderedColumns.length; i += 1) {
62
+ const field = orderedColumns[i];
63
+ const groupId = getParents(field)[depth] ?? null;
64
+ if (depthStructure.length === 0) {
65
+ depthStructure.push({
66
+ columnFields: [field],
57
67
  groupId
58
- }];
68
+ });
69
+ continue;
59
70
  }
60
- const lastGroup = structure[structure.length - 1];
71
+ const lastGroup = depthStructure[depthStructure.length - 1];
61
72
  const prevField = lastGroup.columnFields[lastGroup.columnFields.length - 1];
62
- const prevGroupId = lastGroup.groupId;
63
- if (prevGroupId !== groupId || !haveSameParents(prevField, newField, depth) ||
64
- // Fix for https://github.com/mui/mui-x/issues/7041
65
- haveDifferentContainers(prevField, newField)) {
66
- // It's a new group
67
- return [...structure, {
68
- columnFields: [newField],
73
+ if (lastGroup.groupId !== groupId || !haveSameParents(prevField, field, depth) || haveDifferentContainers(prevField, field)) {
74
+ depthStructure.push({
75
+ columnFields: [field],
69
76
  groupId
70
- }];
77
+ });
78
+ } else {
79
+ lastGroup.columnFields.push(field);
71
80
  }
72
-
73
- // It extends the previous group
74
- return [...structure.slice(0, structure.length - 1), {
75
- columnFields: [...lastGroup.columnFields, newField],
76
- groupId
77
- }];
78
- }, []);
81
+ }
79
82
  groupingHeaderStructure.push(depthStructure);
80
83
  }
81
84
  return groupingHeaderStructure;
@@ -11,10 +11,11 @@ import { getColumnGroupsHeaderStructure, unwrapGroupingColumnModel } from "./gri
11
11
  import { useGridEvent } from "../../utils/useGridEvent.js";
12
12
  import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from "../columns/index.js";
13
13
  const createGroupLookup = columnGroupingModel => {
14
- let groupLookup = {};
15
- columnGroupingModel.forEach(node => {
14
+ const groupLookup = {};
15
+ for (let i = 0; i < columnGroupingModel.length; i += 1) {
16
+ const node = columnGroupingModel[i];
16
17
  if (isLeaf(node)) {
17
- return;
18
+ continue;
18
19
  }
19
20
  const {
20
21
  groupId,
@@ -24,10 +25,8 @@ const createGroupLookup = columnGroupingModel => {
24
25
  if (!groupId) {
25
26
  throw new Error('MUI X: An element of the columnGroupingModel does not have either `field` or `groupId`.');
26
27
  }
27
- if (process.env.NODE_ENV !== 'production') {
28
- if (!children) {
29
- console.warn(`MUI X: group groupId=${groupId} has no children.`);
30
- }
28
+ if (process.env.NODE_ENV !== 'production' && !children) {
29
+ console.warn(`MUI X: group groupId=${groupId} has no children.`);
31
30
  }
32
31
  const groupParam = _extends({}, other, {
33
32
  groupId
@@ -36,13 +35,15 @@ const createGroupLookup = columnGroupingModel => {
36
35
  if (subTreeLookup[groupId] !== undefined || groupLookup[groupId] !== undefined) {
37
36
  throw new Error(`MUI X: The groupId ${groupId} is used multiple times in the columnGroupingModel.`);
38
37
  }
39
- groupLookup = _extends({}, groupLookup, subTreeLookup, {
40
- [groupId]: groupParam
41
- });
42
- });
43
- return _extends({}, groupLookup);
38
+ Object.assign(groupLookup, subTreeLookup);
39
+ groupLookup[groupId] = groupParam;
40
+ }
41
+ return groupLookup;
44
42
  };
45
43
  export const columnGroupsStateInitializer = (state, props, apiRef) => {
44
+ apiRef.current.caches.columnGrouping = {
45
+ lastColumnGroupingModel: props.columnGroupingModel
46
+ };
46
47
  if (!props.columnGroupingModel) {
47
48
  return state;
48
49
  }
@@ -97,6 +98,7 @@ export const useGridColumnGrouping = (apiRef, props) => {
97
98
  });
98
99
  }, [apiRef, props.columnGroupingModel]);
99
100
  const updateColumnGroupingState = React.useCallback(columnGroupingModel => {
101
+ apiRef.current.caches.columnGrouping.lastColumnGroupingModel = columnGroupingModel;
100
102
  // @ts-expect-error Move this logic to `Pro` package
101
103
  const pinnedColumns = apiRef.current.getPinnedColumns?.() ?? {};
102
104
  const columnFields = gridColumnFieldsSelector(apiRef);
@@ -128,6 +130,9 @@ export const useGridColumnGrouping = (apiRef, props) => {
128
130
  * EFFECTS
129
131
  */
130
132
  React.useEffect(() => {
133
+ if (props.columnGroupingModel === apiRef.current.caches.columnGrouping.lastColumnGroupingModel) {
134
+ return;
135
+ }
131
136
  updateColumnGroupingState(props.columnGroupingModel);
132
- }, [updateColumnGroupingState, props.columnGroupingModel]);
137
+ }, [apiRef, updateColumnGroupingState, props.columnGroupingModel]);
133
138
  };
@@ -31,7 +31,7 @@ export interface GetHeadersParams {
31
31
  type OwnerState = DataGridProcessedProps;
32
32
  export declare const GridColumnHeaderRow: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme> & {
33
33
  ownerState: OwnerState;
34
- }, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement> | keyof React.ClassAttributes<HTMLDivElement>>, {}>;
34
+ }, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
35
35
  export declare const useGridColumnHeaders: (props: UseGridColumnHeadersProps) => {
36
36
  renderContext: GridColumnsRenderContext;
37
37
  leftRenderContext: {
@@ -4,6 +4,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
6
  import { styled } from '@mui/material/styles';
7
+ import { computeOffsetLeft } from '@mui/x-virtualizer';
7
8
  import { useGridSelector } from "../../utils/index.js";
8
9
  import { useGridRootProps } from "../../utils/useGridRootProps.js";
9
10
  import { useGridPrivateApiContext } from "../../utils/useGridPrivateApiContext.js";
@@ -11,7 +12,6 @@ import { useGridEvent } from "../../utils/useGridEvent.js";
11
12
  import { GridColumnHeaderItem } from "../../../components/columnHeaders/GridColumnHeaderItem.js";
12
13
  import { gridColumnsTotalWidthSelector, gridGroupHeaderHeightSelector, gridHasFillerSelector, gridHeaderHeightSelector, gridVerticalScrollbarWidthSelector } from "../dimensions/gridDimensionsSelectors.js";
13
14
  import { gridRenderContextColumnsSelector } from "../virtualization/index.js";
14
- import { computeOffsetLeft } from "../virtualization/useGridVirtualScroller.js";
15
15
  import { GridColumnGroupHeader } from "../../../components/columnHeaders/GridColumnGroupHeader.js";
16
16
  import { gridColumnPositionsSelector, gridVisiblePinnedColumnDefinitionsSelector, gridColumnLookupSelector } from "../columns/index.js";
17
17
  import { gridColumnGroupsUnwrappedModelSelector } from "../columnGrouping/gridColumnGroupsSelector.js";
@@ -85,7 +85,8 @@ export const useGridColumnHeaders = props => {
85
85
  renderContext: currentContext = renderContext
86
86
  } = params || {};
87
87
  const firstColumnToRender = currentContext.firstColumnIndex;
88
- const lastColumnToRender = currentContext.lastColumnIndex;
88
+ // HACK: renderContext ins't always synchronized, this should be handled properly.
89
+ const lastColumnToRender = Math.min(currentContext.lastColumnIndex, visibleColumns.length);
89
90
  const renderedColumns = visibleColumns.slice(firstColumnToRender, lastColumnToRender);
90
91
  return {
91
92
  renderedColumns,
@@ -1,4 +1,4 @@
1
- import { GridColDef, GridStateColDef } from "../../../models/colDef/gridColDef.js";
1
+ import type { GridColDef, GridStateColDef } from "../../../models/colDef/gridColDef.js";
2
2
  import type { GridColumnDimensionProperties } from "./gridColumnsUtils.js";
3
3
  export declare enum GridPinnedColumnPosition {
4
4
  LEFT = "left",
@@ -21,8 +21,8 @@ export interface GridPinnedColumnFields {
21
21
  right?: string[];
22
22
  }
23
23
  export declare const EMPTY_PINNED_COLUMN_FIELDS: {
24
- left: string[];
25
- right: string[];
24
+ left: never[];
25
+ right: never[];
26
26
  };
27
27
  export interface GridPinnedColumns {
28
28
  left: GridStateColDef[];
@@ -1,6 +1,7 @@
1
1
  import { createSelector, createSelectorMemoized, createRootSelector } from "../../../utils/createSelector.js";
2
2
  import { EMPTY_PINNED_COLUMN_FIELDS } from "./gridColumnsInterfaces.js";
3
3
  import { gridIsRtlSelector } from "../../core/gridCoreSelector.js";
4
+ import { gridListColumnSelector, gridListViewSelector } from "../listView/index.js";
4
5
 
5
6
  /**
6
7
  * Get the columns state
@@ -45,7 +46,7 @@ export const gridInitialColumnVisibilityModelSelector = createSelector(gridColum
45
46
  * Get the visible columns as a lookup (an object containing the field for keys and the definition for values).
46
47
  * @category Visible Columns
47
48
  */
48
- export const gridVisibleColumnDefinitionsSelector = createSelectorMemoized(gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, (columns, columnVisibilityModel) => columns.filter(column => columnVisibilityModel[column.field] !== false));
49
+ export const gridVisibleColumnDefinitionsSelector = createSelectorMemoized(gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, gridListViewSelector, gridListColumnSelector, (columns, columnVisibilityModel, listView, listColumn) => listView && listColumn ? [listColumn] : columns.filter(column => columnVisibilityModel[column.field] !== false));
49
50
 
50
51
  /**
51
52
  * Get the field of each visible column.
@@ -70,7 +71,10 @@ export const gridExistingPinnedColumnSelector = createSelectorMemoized(gridPinne
70
71
  * Get the visible pinned columns.
71
72
  * @category Visible Columns
72
73
  */
73
- export const gridVisiblePinnedColumnDefinitionsSelector = createSelectorMemoized(gridColumnsStateSelector, gridPinnedColumnsSelector, gridVisibleColumnFieldsSelector, gridIsRtlSelector, (columnsState, model, visibleColumnFields, isRtl) => {
74
+ export const gridVisiblePinnedColumnDefinitionsSelector = createSelectorMemoized(gridColumnsStateSelector, gridPinnedColumnsSelector, gridVisibleColumnFieldsSelector, gridIsRtlSelector, gridListViewSelector, (columnsState, model, visibleColumnFields, isRtl, listView) => {
75
+ if (listView) {
76
+ return EMPTY_PINNED_COLUMN_FIELDS;
77
+ }
74
78
  const visiblePinnedFields = filterMissingColumns(model, visibleColumnFields, isRtl);
75
79
  const visiblePinnedColumns = {
76
80
  left: visiblePinnedFields.left.map(field => columnsState.lookup[field]),
@@ -242,11 +242,13 @@ export const createColumnsState = ({
242
242
  initialColumnVisibilityModel: updateInitialVisibilityModel ? columnVisibilityModel : currentState.initialColumnVisibilityModel
243
243
  };
244
244
  }
245
- let columnsToKeep = {};
245
+ const columnsToKeep = {};
246
246
  if (keepOnlyColumnsToUpsert && !isInsideStateInitializer) {
247
- columnsToKeep = Object.keys(columnsState.lookup).reduce((acc, key) => _extends({}, acc, {
248
- [key]: false
249
- }), {});
247
+ for (const key in columnsState.lookup) {
248
+ if (Object.prototype.hasOwnProperty.call(columnsState.lookup, key)) {
249
+ columnsToKeep[key] = false;
250
+ }
251
+ }
250
252
  }
251
253
  const columnsToUpsertLookup = {};
252
254
  columnsToUpsert.forEach(newColumn => {