@mui/x-data-grid 5.15.2 → 5.17.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 (286) hide show
  1. package/CHANGELOG.md +177 -2
  2. package/DataGrid/DataGrid.js +3 -1
  3. package/DataGrid/useDataGridComponent.js +5 -0
  4. package/README.md +2 -1
  5. package/components/DataGridColumnHeaders.js +4 -3
  6. package/components/ErrorBoundary.d.ts +1 -0
  7. package/components/GridAutoSizer.js +7 -0
  8. package/components/GridRow.d.ts +2 -1
  9. package/components/GridRow.js +136 -85
  10. package/components/base/GridBody.js +8 -5
  11. package/components/base/GridOverlays.js +4 -7
  12. package/components/cell/GridActionsCellItem.d.ts +2 -2
  13. package/components/cell/GridBooleanCell.js +2 -1
  14. package/components/cell/GridEditBooleanCell.js +2 -1
  15. package/components/cell/GridEditDateCell.js +3 -2
  16. package/components/cell/GridEditInputCell.js +2 -1
  17. package/components/cell/GridEditSingleSelectCell.js +11 -2
  18. package/components/cell/GridSkeletonCell.d.ts +12 -0
  19. package/components/cell/GridSkeletonCell.js +60 -0
  20. package/components/cell/index.d.ts +1 -0
  21. package/components/cell/index.js +2 -1
  22. package/components/columnHeaders/GridColumnGroupHeader.d.ts +14 -0
  23. package/components/columnHeaders/GridColumnGroupHeader.js +122 -0
  24. package/components/columnHeaders/GridColumnHeaderItem.js +55 -71
  25. package/components/columnHeaders/GridColumnHeadersInner.js +2 -1
  26. package/components/columnHeaders/GridGenericColumnHeaderItem.d.ts +32 -0
  27. package/components/columnHeaders/GridGenericColumnHeaderItem.js +104 -0
  28. package/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  29. package/components/containers/GridOverlay.js +7 -1
  30. package/components/containers/GridRoot.js +3 -3
  31. package/components/containers/GridRootStyles.js +16 -2
  32. package/components/menu/GridMenu.d.ts +3 -2
  33. package/components/menu/GridMenu.js +1 -0
  34. package/components/menu/columnMenu/GridColumnHeaderMenu.d.ts +1 -1
  35. package/components/panel/GridColumnsPanel.d.ts +6 -1
  36. package/components/panel/GridColumnsPanel.js +38 -6
  37. package/components/panel/GridPanel.d.ts +1 -1
  38. package/components/panel/GridPanel.js +1 -0
  39. package/components/panel/filterPanel/GridFilterForm.d.ts +4 -0
  40. package/components/panel/filterPanel/GridFilterForm.js +5 -0
  41. package/components/panel/filterPanel/GridFilterInputMultipleValue.d.ts +1 -1
  42. package/components/panel/filterPanel/GridFilterPanel.d.ts +4 -0
  43. package/components/panel/filterPanel/GridFilterPanel.js +5 -0
  44. package/components/toolbar/GridToolbarColumnsButton.d.ts +1 -1
  45. package/components/toolbar/GridToolbarDensitySelector.d.ts +1 -1
  46. package/components/toolbar/GridToolbarExportContainer.d.ts +1 -1
  47. package/constants/defaultGridSlotsComponents.js +2 -1
  48. package/constants/gridClasses.d.ts +24 -0
  49. package/constants/gridClasses.js +1 -1
  50. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -1
  51. package/hooks/features/columnGrouping/gridColumnGroupsInterfaces.d.ts +7 -0
  52. package/hooks/features/columnGrouping/gridColumnGroupsInterfaces.js +1 -0
  53. package/hooks/features/columnGrouping/gridColumnGroupsSelector.d.ts +7 -0
  54. package/hooks/features/columnGrouping/gridColumnGroupsSelector.js +8 -0
  55. package/hooks/features/columnGrouping/index.d.ts +2 -0
  56. package/hooks/features/columnGrouping/index.js +2 -0
  57. package/hooks/features/columnGrouping/useGridColumnGrouping.d.ts +24 -0
  58. package/hooks/features/columnGrouping/useGridColumnGrouping.js +153 -0
  59. package/hooks/features/columnGrouping/useGridColumnGroupingPreProcessors.d.ts +4 -0
  60. package/hooks/features/columnGrouping/useGridColumnGroupingPreProcessors.js +35 -0
  61. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +7 -6
  62. package/hooks/features/columnHeaders/useGridColumnHeaders.js +204 -9
  63. package/hooks/features/density/densitySelector.d.ts +2 -0
  64. package/hooks/features/density/densitySelector.js +3 -1
  65. package/hooks/features/density/densityState.d.ts +1 -0
  66. package/hooks/features/density/useGridDensity.d.ts +1 -1
  67. package/hooks/features/density/useGridDensity.js +45 -9
  68. package/hooks/features/dimensions/useGridDimensions.js +4 -4
  69. package/hooks/features/export/useGridPrintExport.js +3 -3
  70. package/hooks/features/filter/gridFilterSelector.d.ts +3 -3
  71. package/hooks/features/filter/gridFilterUtils.d.ts +1 -1
  72. package/hooks/features/filter/gridFilterUtils.js +55 -54
  73. package/hooks/features/filter/useGridFilter.js +1 -1
  74. package/hooks/features/index.d.ts +1 -0
  75. package/hooks/features/index.js +1 -0
  76. package/hooks/features/pagination/gridPaginationSelector.d.ts +1 -1
  77. package/hooks/features/rows/gridRowsSelector.d.ts +1 -1
  78. package/hooks/features/rows/useGridParamsApi.js +1 -1
  79. package/hooks/features/rows/useGridRows.js +65 -8
  80. package/hooks/features/rows/useGridRowsMeta.js +36 -16
  81. package/hooks/features/selection/gridSelectionSelector.d.ts +1 -1
  82. package/hooks/features/sorting/gridSortingSelector.d.ts +1 -1
  83. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +2 -2
  84. package/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  85. package/hooks/utils/useGridNativeEventListener.d.ts +1 -1
  86. package/hooks/utils/useGridNativeEventListener.js +2 -2
  87. package/hooks/utils/useGridVisibleRows.d.ts +2 -2
  88. package/index.js +1 -1
  89. package/internals/index.d.ts +2 -0
  90. package/internals/index.js +2 -0
  91. package/legacy/DataGrid/DataGrid.js +3 -1
  92. package/legacy/DataGrid/useDataGridComponent.js +5 -0
  93. package/legacy/components/DataGridColumnHeaders.js +4 -3
  94. package/legacy/components/GridAutoSizer.js +7 -0
  95. package/legacy/components/GridRow.js +138 -85
  96. package/legacy/components/base/GridBody.js +8 -5
  97. package/legacy/components/base/GridOverlays.js +4 -7
  98. package/legacy/components/cell/GridBooleanCell.js +2 -1
  99. package/legacy/components/cell/GridEditBooleanCell.js +2 -1
  100. package/legacy/components/cell/GridEditDateCell.js +3 -2
  101. package/legacy/components/cell/GridEditInputCell.js +2 -1
  102. package/legacy/components/cell/GridEditSingleSelectCell.js +11 -2
  103. package/legacy/components/cell/GridSkeletonCell.js +57 -0
  104. package/legacy/components/cell/index.js +2 -1
  105. package/legacy/components/columnHeaders/GridColumnGroupHeader.js +120 -0
  106. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +78 -88
  107. package/legacy/components/columnHeaders/GridColumnHeadersInner.js +2 -1
  108. package/legacy/components/columnHeaders/GridGenericColumnHeaderItem.js +112 -0
  109. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  110. package/legacy/components/containers/GridOverlay.js +7 -1
  111. package/legacy/components/containers/GridRoot.js +3 -3
  112. package/legacy/components/containers/GridRootStyles.js +14 -5
  113. package/legacy/components/menu/GridMenu.js +1 -0
  114. package/legacy/components/panel/GridColumnsPanel.js +41 -6
  115. package/legacy/components/panel/GridPanel.js +1 -0
  116. package/legacy/components/panel/filterPanel/GridFilterForm.js +5 -0
  117. package/legacy/components/panel/filterPanel/GridFilterPanel.js +5 -0
  118. package/legacy/constants/defaultGridSlotsComponents.js +2 -1
  119. package/legacy/constants/gridClasses.js +1 -1
  120. package/legacy/hooks/features/columnGrouping/gridColumnGroupsInterfaces.js +1 -0
  121. package/legacy/hooks/features/columnGrouping/gridColumnGroupsSelector.js +12 -0
  122. package/legacy/hooks/features/columnGrouping/index.js +2 -0
  123. package/legacy/hooks/features/columnGrouping/useGridColumnGrouping.js +151 -0
  124. package/legacy/hooks/features/columnGrouping/useGridColumnGroupingPreProcessors.js +35 -0
  125. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +213 -12
  126. package/legacy/hooks/features/density/densitySelector.js +6 -0
  127. package/legacy/hooks/features/density/useGridDensity.js +44 -6
  128. package/legacy/hooks/features/dimensions/useGridDimensions.js +4 -4
  129. package/legacy/hooks/features/export/useGridPrintExport.js +3 -3
  130. package/legacy/hooks/features/filter/gridFilterUtils.js +61 -56
  131. package/legacy/hooks/features/filter/useGridFilter.js +1 -1
  132. package/legacy/hooks/features/index.js +1 -0
  133. package/legacy/hooks/features/rows/useGridParamsApi.js +1 -1
  134. package/legacy/hooks/features/rows/useGridRows.js +73 -8
  135. package/legacy/hooks/features/rows/useGridRowsMeta.js +45 -18
  136. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +31 -13
  137. package/legacy/hooks/utils/useGridNativeEventListener.js +2 -2
  138. package/legacy/index.js +1 -1
  139. package/legacy/internals/index.js +2 -0
  140. package/legacy/models/api/gridColumnGroupingApi.js +1 -0
  141. package/legacy/models/events/gridEvents.js +2 -0
  142. package/legacy/models/gridColumnGrouping.js +6 -0
  143. package/legacy/models/index.js +2 -1
  144. package/legacy/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  145. package/legacy/models/params/index.js +2 -1
  146. package/legacy/utils/utils.js +18 -0
  147. package/models/api/gridApiCommon.d.ts +2 -1
  148. package/models/api/gridColumnGroupingApi.d.ts +19 -0
  149. package/models/api/gridColumnGroupingApi.js +1 -0
  150. package/models/api/gridDensityApi.d.ts +2 -1
  151. package/models/api/gridParamsApi.d.ts +1 -1
  152. package/models/api/gridRowApi.d.ts +6 -0
  153. package/models/api/gridRowsMetaApi.d.ts +6 -1
  154. package/models/colDef/gridColDef.d.ts +15 -1
  155. package/models/events/gridEventLookup.d.ts +7 -1
  156. package/models/events/gridEvents.d.ts +3 -1
  157. package/models/events/gridEvents.js +2 -0
  158. package/models/gridColumnGrouping.d.ts +67 -0
  159. package/models/gridColumnGrouping.js +6 -0
  160. package/models/gridRows.d.ts +5 -5
  161. package/models/gridSlotsComponent.d.ts +5 -0
  162. package/models/gridStateCommunity.d.ts +2 -1
  163. package/models/index.d.ts +1 -0
  164. package/models/index.js +2 -1
  165. package/models/params/gridCellParams.d.ts +7 -2
  166. package/models/params/gridMenuParams.d.ts +1 -2
  167. package/models/params/gridRenderedRowsIntervalChangeParams.d.ts +10 -0
  168. package/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  169. package/models/params/index.d.ts +1 -0
  170. package/models/params/index.js +2 -1
  171. package/models/props/DataGridProps.d.ts +7 -1
  172. package/modern/DataGrid/DataGrid.js +3 -1
  173. package/modern/DataGrid/useDataGridComponent.js +5 -0
  174. package/modern/components/DataGridColumnHeaders.js +4 -3
  175. package/modern/components/GridAutoSizer.js +7 -0
  176. package/modern/components/GridRow.js +133 -84
  177. package/modern/components/base/GridBody.js +8 -5
  178. package/modern/components/base/GridOverlays.js +4 -7
  179. package/modern/components/cell/GridBooleanCell.js +2 -1
  180. package/modern/components/cell/GridEditBooleanCell.js +2 -1
  181. package/modern/components/cell/GridEditDateCell.js +3 -2
  182. package/modern/components/cell/GridEditInputCell.js +2 -1
  183. package/modern/components/cell/GridEditSingleSelectCell.js +11 -2
  184. package/modern/components/cell/GridSkeletonCell.js +60 -0
  185. package/modern/components/cell/index.js +2 -1
  186. package/modern/components/columnHeaders/GridColumnGroupHeader.js +120 -0
  187. package/modern/components/columnHeaders/GridColumnHeaderItem.js +53 -69
  188. package/modern/components/columnHeaders/GridColumnHeadersInner.js +2 -1
  189. package/modern/components/columnHeaders/GridGenericColumnHeaderItem.js +104 -0
  190. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  191. package/modern/components/containers/GridOverlay.js +7 -1
  192. package/modern/components/containers/GridRoot.js +3 -3
  193. package/modern/components/containers/GridRootStyles.js +16 -2
  194. package/modern/components/menu/GridMenu.js +1 -0
  195. package/modern/components/panel/GridColumnsPanel.js +38 -6
  196. package/modern/components/panel/GridPanel.js +1 -0
  197. package/modern/components/panel/filterPanel/GridFilterForm.js +5 -0
  198. package/modern/components/panel/filterPanel/GridFilterPanel.js +5 -0
  199. package/modern/constants/defaultGridSlotsComponents.js +2 -1
  200. package/modern/constants/gridClasses.js +1 -1
  201. package/modern/hooks/features/columnGrouping/gridColumnGroupsInterfaces.js +1 -0
  202. package/modern/hooks/features/columnGrouping/gridColumnGroupsSelector.js +8 -0
  203. package/modern/hooks/features/columnGrouping/index.js +2 -0
  204. package/modern/hooks/features/columnGrouping/useGridColumnGrouping.js +145 -0
  205. package/modern/hooks/features/columnGrouping/useGridColumnGroupingPreProcessors.js +29 -0
  206. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +186 -9
  207. package/modern/hooks/features/density/densitySelector.js +3 -1
  208. package/modern/hooks/features/density/useGridDensity.js +37 -9
  209. package/modern/hooks/features/dimensions/useGridDimensions.js +4 -4
  210. package/modern/hooks/features/export/useGridPrintExport.js +3 -3
  211. package/modern/hooks/features/filter/gridFilterUtils.js +54 -53
  212. package/modern/hooks/features/filter/useGridFilter.js +1 -1
  213. package/modern/hooks/features/index.js +1 -0
  214. package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
  215. package/modern/hooks/features/rows/useGridRows.js +65 -8
  216. package/modern/hooks/features/rows/useGridRowsMeta.js +36 -16
  217. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  218. package/modern/hooks/utils/useGridNativeEventListener.js +2 -2
  219. package/modern/index.js +1 -1
  220. package/modern/internals/index.js +2 -0
  221. package/modern/models/api/gridColumnGroupingApi.js +1 -0
  222. package/modern/models/events/gridEvents.js +2 -0
  223. package/modern/models/gridColumnGrouping.js +6 -0
  224. package/modern/models/index.js +2 -1
  225. package/modern/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  226. package/modern/models/params/index.js +2 -1
  227. package/modern/utils/utils.js +16 -0
  228. package/node/DataGrid/DataGrid.js +3 -1
  229. package/node/DataGrid/useDataGridComponent.js +7 -0
  230. package/node/components/DataGridColumnHeaders.js +4 -3
  231. package/node/components/GridAutoSizer.js +7 -0
  232. package/node/components/GridRow.js +136 -77
  233. package/node/components/base/GridBody.js +7 -4
  234. package/node/components/base/GridOverlays.js +3 -6
  235. package/node/components/cell/GridBooleanCell.js +2 -1
  236. package/node/components/cell/GridEditBooleanCell.js +2 -1
  237. package/node/components/cell/GridEditDateCell.js +3 -2
  238. package/node/components/cell/GridEditInputCell.js +2 -1
  239. package/node/components/cell/GridEditSingleSelectCell.js +11 -2
  240. package/node/components/cell/GridSkeletonCell.js +81 -0
  241. package/node/components/cell/index.js +13 -0
  242. package/node/components/columnHeaders/GridColumnGroupHeader.js +141 -0
  243. package/node/components/columnHeaders/GridColumnHeaderItem.js +53 -72
  244. package/node/components/columnHeaders/GridColumnHeadersInner.js +2 -1
  245. package/node/components/columnHeaders/GridGenericColumnHeaderItem.js +126 -0
  246. package/node/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  247. package/node/components/containers/GridOverlay.js +7 -1
  248. package/node/components/containers/GridRoot.js +4 -4
  249. package/node/components/containers/GridRootStyles.js +16 -2
  250. package/node/components/menu/GridMenu.js +1 -0
  251. package/node/components/panel/GridColumnsPanel.js +36 -5
  252. package/node/components/panel/GridPanel.js +1 -0
  253. package/node/components/panel/filterPanel/GridFilterForm.js +5 -0
  254. package/node/components/panel/filterPanel/GridFilterPanel.js +5 -0
  255. package/node/constants/defaultGridSlotsComponents.js +1 -0
  256. package/node/constants/gridClasses.js +1 -1
  257. package/node/hooks/features/columnGrouping/gridColumnGroupsInterfaces.js +5 -0
  258. package/node/hooks/features/columnGrouping/gridColumnGroupsSelector.js +18 -0
  259. package/node/hooks/features/columnGrouping/index.js +18 -0
  260. package/node/hooks/features/columnGrouping/useGridColumnGrouping.js +182 -0
  261. package/node/hooks/features/columnGrouping/useGridColumnGroupingPreProcessors.js +55 -0
  262. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +207 -8
  263. package/node/hooks/features/density/densitySelector.js +6 -2
  264. package/node/hooks/features/density/useGridDensity.js +48 -9
  265. package/node/hooks/features/dimensions/useGridDimensions.js +3 -3
  266. package/node/hooks/features/export/useGridPrintExport.js +2 -2
  267. package/node/hooks/features/filter/gridFilterUtils.js +55 -55
  268. package/node/hooks/features/filter/useGridFilter.js +1 -1
  269. package/node/hooks/features/index.js +13 -0
  270. package/node/hooks/features/rows/useGridParamsApi.js +1 -1
  271. package/node/hooks/features/rows/useGridRows.js +60 -7
  272. package/node/hooks/features/rows/useGridRowsMeta.js +35 -15
  273. package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  274. package/node/hooks/utils/useGridNativeEventListener.js +2 -2
  275. package/node/index.js +1 -1
  276. package/node/internals/index.js +22 -0
  277. package/node/models/api/gridColumnGroupingApi.js +5 -0
  278. package/node/models/events/gridEvents.js +2 -0
  279. package/node/models/gridColumnGrouping.js +13 -0
  280. package/node/models/index.js +13 -0
  281. package/node/models/params/gridRenderedRowsIntervalChangeParams.js +5 -0
  282. package/node/models/params/index.js +13 -0
  283. package/node/utils/utils.js +18 -0
  284. package/package.json +3 -3
  285. package/utils/utils.d.ts +1 -0
  286. package/utils/utils.js +16 -0
@@ -2,4 +2,4 @@ import { generateUtilityClasses, generateUtilityClass } from '@mui/material';
2
2
  export function getDataGridUtilityClass(slot) {
3
3
  return generateUtilityClass('MuiDataGrid', slot);
4
4
  }
5
- export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
5
+ export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'cellSkeleton', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'row--detailPanelExpanded', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
@@ -0,0 +1,8 @@
1
+ import { createSelector } from '../../../utils/createSelector';
2
+
3
+ /**
4
+ * @category ColumnGrouping
5
+ * @ignore - do not document.
6
+ */
7
+ export const gridColumnGroupingSelector = state => state.columnGrouping;
8
+ export const gridColumnGroupsLookupSelector = createSelector(gridColumnGroupingSelector, columnGrouping => columnGrouping.lookup);
@@ -0,0 +1,2 @@
1
+ export * from './gridColumnGroupsSelector';
2
+ export {};
@@ -0,0 +1,145 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["groupId", "children"];
4
+ import * as React from 'react';
5
+ import { isLeaf } from '../../../models/gridColumnGrouping';
6
+ import { gridColumnGroupsLookupSelector } from './gridColumnGroupsSelector';
7
+ import { gridColumnLookupSelector } from '../columns/gridColumnsSelector';
8
+ import { useGridApiMethod } from '../../utils/useGridApiMethod';
9
+ export function hasGroupPath(lookupElement) {
10
+ return lookupElement.groupPath !== undefined;
11
+ }
12
+
13
+ // This is the recurrence function that help writing `unwrapGroupingColumnModel()`
14
+ const recurrentUnwrapGroupingColumnModel = (columnGroupNode, parents, unwrappedGroupingModelToComplet) => {
15
+ if (isLeaf(columnGroupNode)) {
16
+ if (unwrappedGroupingModelToComplet[columnGroupNode.field] !== undefined) {
17
+ throw new Error([`MUI: columnGroupingModel contains duplicated field`, `column field ${columnGroupNode.field} occurrs two times in the grouping model:`, `- ${unwrappedGroupingModelToComplet[columnGroupNode.field].join(' > ')}`, `- ${parents.join(' > ')}`].join('\n'));
18
+ }
19
+
20
+ unwrappedGroupingModelToComplet[columnGroupNode.field] = parents;
21
+ return;
22
+ }
23
+
24
+ const {
25
+ groupId,
26
+ children
27
+ } = columnGroupNode;
28
+ children.forEach(child => {
29
+ recurrentUnwrapGroupingColumnModel(child, [...parents, groupId], unwrappedGroupingModelToComplet);
30
+ });
31
+ };
32
+ /**
33
+ * This is a function that provide for each column the array of its parents.
34
+ * Parents are ordered from the root to the leaf.
35
+ * @param columnGroupingModel The model such as provided in DataGrid props
36
+ * @returns An object `{[field]: groupIds}` where `groupIds` is the parents of the column `field`
37
+ */
38
+
39
+
40
+ export const unwrapGroupingColumnModel = columnGroupingModel => {
41
+ if (!columnGroupingModel) {
42
+ return {};
43
+ }
44
+
45
+ const unwrappedSubTree = {};
46
+ columnGroupingModel.forEach(columnGroupNode => {
47
+ recurrentUnwrapGroupingColumnModel(columnGroupNode, [], unwrappedSubTree);
48
+ });
49
+ return unwrappedSubTree;
50
+ };
51
+
52
+ const createGroupLookup = columnGroupingModel => {
53
+ let groupLookup = {};
54
+ columnGroupingModel.forEach(node => {
55
+ if (isLeaf(node)) {
56
+ return;
57
+ }
58
+
59
+ const {
60
+ groupId,
61
+ children
62
+ } = node,
63
+ other = _objectWithoutPropertiesLoose(node, _excluded);
64
+
65
+ if (!groupId) {
66
+ throw new Error('MUI: An element of the columnGroupingModel does not have either `field` or `groupId`.');
67
+ }
68
+
69
+ if (!children) {
70
+ console.warn(`MUI: group groupId=${groupId} has no children.`);
71
+ }
72
+
73
+ const groupParam = _extends({}, other, {
74
+ groupId
75
+ });
76
+
77
+ const subTreeLookup = createGroupLookup(children);
78
+
79
+ if (subTreeLookup[groupId] !== undefined || groupLookup[groupId] !== undefined) {
80
+ throw new Error(`MUI: The groupId ${groupId} is used multiple times in the columnGroupingModel.`);
81
+ }
82
+
83
+ groupLookup = _extends({}, groupLookup, subTreeLookup, {
84
+ [groupId]: groupParam
85
+ });
86
+ });
87
+ return _extends({}, groupLookup);
88
+ };
89
+
90
+ export const columnGroupsStateInitializer = (state, props) => {
91
+ const groupLookup = createGroupLookup(props.columnGroupingModel ?? []);
92
+ return _extends({}, state, {
93
+ columnGrouping: {
94
+ lookup: groupLookup,
95
+ groupCollapsedModel: {}
96
+ }
97
+ });
98
+ };
99
+ /**
100
+ * @requires useGridColumns (method, event)
101
+ * @requires useGridParamsApi (method)
102
+ */
103
+
104
+ export const useGridColumnGrouping = (apiRef, props) => {
105
+ /**
106
+ * API METHODS
107
+ */
108
+ const getColumnGroupPath = React.useCallback(field => {
109
+ const columnLookup = gridColumnLookupSelector(apiRef);
110
+ return columnLookup[field]?.groupPath ?? [];
111
+ }, [apiRef]);
112
+ const getAllGroupDetails = React.useCallback(() => {
113
+ const columnGroupLookup = gridColumnGroupsLookupSelector(apiRef);
114
+ return columnGroupLookup;
115
+ }, [apiRef]);
116
+ const columnGroupingApi = {
117
+ unstable_getColumnGroupPath: getColumnGroupPath,
118
+ unstable_getAllGroupDetails: getAllGroupDetails
119
+ };
120
+ useGridApiMethod(apiRef, columnGroupingApi, 'GridColumnGroupingApi');
121
+ /**
122
+ * EFFECTS
123
+ */
124
+ // The effect does not track any value defined synchronously during the 1st render by hooks called after `useGridColumns`
125
+ // As a consequence, the state generated by the 1st run of this useEffect will always be equal to the initialization one
126
+
127
+ const isFirstRender = React.useRef(true);
128
+ React.useEffect(() => {
129
+ if (isFirstRender.current) {
130
+ isFirstRender.current = false;
131
+ return;
132
+ }
133
+
134
+ if (!props.experimentalFeatures?.columnGrouping) {
135
+ return;
136
+ }
137
+
138
+ const groupLookup = createGroupLookup(props.columnGroupingModel ?? []);
139
+ apiRef.current.setState(state => _extends({}, state, {
140
+ columnGrouping: _extends({}, state.columnGrouping, {
141
+ lookup: groupLookup
142
+ })
143
+ }));
144
+ }, [apiRef, props.columnGroupingModel, props.experimentalFeatures?.columnGrouping]);
145
+ };
@@ -0,0 +1,29 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
4
+ import { isDeepEqual } from '../../../utils/utils';
5
+ import { unwrapGroupingColumnModel, hasGroupPath } from './useGridColumnGrouping';
6
+ export const useGridColumnGroupingPreProcessors = (apiRef, props) => {
7
+ const addHeaderGroups = React.useCallback(columnsState => {
8
+ if (!props.experimentalFeatures?.columnGrouping) {
9
+ return columnsState;
10
+ }
11
+
12
+ const unwrappedGroupingModel = unwrapGroupingColumnModel(props.columnGroupingModel);
13
+ columnsState.all.forEach(field => {
14
+ const newGroupPath = unwrappedGroupingModel[field] ?? [];
15
+ const lookupElement = columnsState.lookup[field];
16
+
17
+ if (hasGroupPath(lookupElement) && isDeepEqual(newGroupPath, lookupElement?.groupPath)) {
18
+ // Avoid modifying the pointer to allow shadow comparison in https://github.com/mui/mui-x/blob/f90afbf10a1264ee8b453d7549dd7cdd6110a4ed/packages/grid/x-data-grid/src/hooks/features/columns/gridColumnsUtils.ts#L446:L453
19
+ return;
20
+ }
21
+
22
+ columnsState.lookup[field] = _extends({}, columnsState.lookup[field], {
23
+ groupPath: unwrappedGroupingModel[field] ?? []
24
+ });
25
+ });
26
+ return columnsState;
27
+ }, [props.columnGroupingModel, props.experimentalFeatures?.columnGrouping]);
28
+ useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', addHeaderGroups);
29
+ };
@@ -2,12 +2,13 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import * as ReactDOM from 'react-dom';
4
4
  import { useForkRef } from '@mui/material/utils';
5
+ import { styled } from '@mui/material/styles';
5
6
  import { defaultMemoize } from 'reselect';
6
7
  import { useGridApiContext } from '../../utils/useGridApiContext';
7
8
  import { useGridSelector } from '../../utils/useGridSelector';
8
9
  import { gridVisibleColumnDefinitionsSelector, gridColumnPositionsSelector } from '../columns/gridColumnsSelector';
9
10
  import { gridTabIndexColumnHeaderSelector, gridTabIndexCellSelector, gridFocusColumnHeaderSelector } from '../focus/gridFocusStateSelector';
10
- import { gridDensityHeaderHeightSelector } from '../density/densitySelector';
11
+ import { gridDensityHeaderHeightSelector, gridDensityHeaderGroupingMaxDepthSelector, gridDensityTotalHeaderHeightSelector } from '../density/densitySelector';
11
12
  import { gridFilterActiveItemsLookupSelector } from '../filter/gridFilterSelector';
12
13
  import { gridSortColumnLookupSelector } from '../sorting/gridSortingSelector';
13
14
  import { gridColumnMenuSelector } from '../columnMenu/columnMenuSelector';
@@ -17,7 +18,18 @@ import { GridColumnHeaderItem } from '../../../components/columnHeaders/GridColu
17
18
  import { getFirstColumnIndexToRender } from '../columns/gridColumnsUtils';
18
19
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
19
20
  import { getRenderableIndexes } from '../virtualization/useGridVirtualScroller';
21
+ import { GridColumnGroupHeader } from '../../../components/columnHeaders/GridColumnGroupHeader';
22
+ import { isDeepEqual } from '../../../utils/utils'; // TODO: add the possibility to switch this value if needed for customization
23
+
20
24
  import { jsx as _jsx } from "react/jsx-runtime";
25
+ const MERGE_EMPTY_CELLS = true;
26
+ const GridColumnHeaderRow = styled('div', {
27
+ name: 'MuiDataGrid',
28
+ slot: 'ColumnHeaderRow',
29
+ overridesResolver: (props, styles) => styles.columnHeaderRow
30
+ })(() => ({
31
+ display: 'flex'
32
+ }));
21
33
 
22
34
  function isUIEvent(event) {
23
35
  return !!event.target;
@@ -37,6 +49,8 @@ export const useGridColumnHeaders = props => {
37
49
  const cellTabIndexState = useGridSelector(apiRef, gridTabIndexCellSelector);
38
50
  const columnHeaderFocus = useGridSelector(apiRef, gridFocusColumnHeaderSelector);
39
51
  const headerHeight = useGridSelector(apiRef, gridDensityHeaderHeightSelector);
52
+ const headerGroupingMaxDepth = useGridSelector(apiRef, gridDensityHeaderGroupingMaxDepthSelector);
53
+ const totalHeaderHeight = useGridSelector(apiRef, gridDensityTotalHeaderHeightSelector);
40
54
  const filterColumnLookup = useGridSelector(apiRef, gridFilterActiveItemsLookupSelector);
41
55
  const sortColumnLookup = useGridSelector(apiRef, gridSortColumnLookupSelector);
42
56
  const columnMenuState = useGridSelector(apiRef, gridColumnMenuSelector);
@@ -130,9 +144,9 @@ export const useGridColumnHeaders = props => {
130
144
  useGridApiEventHandler(apiRef, 'columnResizeStop', handleColumnResizeStop);
131
145
  useGridApiEventHandler(apiRef, 'columnHeaderDragStart', handleColumnReorderStart);
132
146
  useGridApiEventHandler(apiRef, 'columnHeaderDragEnd', handleColumnReorderStop);
133
- useGridApiEventHandler(apiRef, 'rowsScroll', handleScroll);
147
+ useGridApiEventHandler(apiRef, 'rowsScroll', handleScroll); // Helper for computation common between getColumnHeaders and getColumnGroupHeaders
134
148
 
135
- const getColumns = (params, other = {}) => {
149
+ const getColumnsToRender = params => {
136
150
  const {
137
151
  renderContext: nextRenderContext = renderContext,
138
152
  minFirstColumn = minColumnIndex,
@@ -143,7 +157,6 @@ export const useGridColumnHeaders = props => {
143
157
  return null;
144
158
  }
145
159
 
146
- const columns = [];
147
160
  const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
148
161
  firstIndex: nextRenderContext.firstRowIndex,
149
162
  lastIndex: nextRenderContext.lastRowIndex,
@@ -162,6 +175,27 @@ export const useGridColumnHeaders = props => {
162
175
  });
163
176
  const lastColumnToRender = Math.min(nextRenderContext.lastColumnIndex + rootProps.columnBuffer, maxLastColumn);
164
177
  const renderedColumns = visibleColumns.slice(firstColumnToRender, lastColumnToRender);
178
+ return {
179
+ renderedColumns,
180
+ firstColumnToRender,
181
+ lastColumnToRender,
182
+ minFirstColumn,
183
+ maxLastColumn
184
+ };
185
+ };
186
+
187
+ const getColumnHeaders = (params, other = {}) => {
188
+ const columnsToRender = getColumnsToRender(params);
189
+
190
+ if (columnsToRender == null) {
191
+ return null;
192
+ }
193
+
194
+ const {
195
+ renderedColumns,
196
+ firstColumnToRender
197
+ } = columnsToRender;
198
+ const columns = [];
165
199
 
166
200
  for (let i = 0; i < renderedColumns.length; i += 1) {
167
201
  const column = renderedColumns[i];
@@ -186,25 +220,168 @@ export const useGridColumnHeaders = props => {
186
220
  }, other), column.field));
187
221
  }
188
222
 
223
+ return /*#__PURE__*/_jsx(GridColumnHeaderRow, {
224
+ role: "row",
225
+ "aria-rowindex": headerGroupingMaxDepth + 1,
226
+ children: columns
227
+ });
228
+ };
229
+
230
+ const getParents = (path = [], depth) => path.slice(0, depth + 1);
231
+
232
+ const getColumnGroupHeaders = params => {
233
+ if (headerGroupingMaxDepth === 0) {
234
+ return null;
235
+ }
236
+
237
+ const columnsToRender = getColumnsToRender(params);
238
+
239
+ if (columnsToRender == null) {
240
+ return null;
241
+ }
242
+
243
+ const {
244
+ renderedColumns,
245
+ firstColumnToRender,
246
+ lastColumnToRender,
247
+ maxLastColumn
248
+ } = columnsToRender;
249
+ const columns = [];
250
+ const headerToRender = [];
251
+
252
+ for (let depth = 0; depth < headerGroupingMaxDepth; depth += 1) {
253
+ // Initialize the header line with a grouping item containing all the columns on the left of the virtualization which are in the same group as the first group to render
254
+ const initialHeader = [];
255
+ let leftOverflow = 0;
256
+ let columnIndex = firstColumnToRender - 1;
257
+ const firstColumnToRenderGroup = visibleColumns[firstColumnToRender]?.groupPath?.[depth]; // The array of parent is used to manage empty grouping cell
258
+ // When two empty grouping cell are next to each other, we merge them if the belong to the same group.
259
+
260
+ const firstColumnToRenderGroupParents = getParents(visibleColumns[firstColumnToRender]?.groupPath, depth);
261
+
262
+ while (firstColumnToRenderGroup !== null && columnIndex >= minColumnIndex && visibleColumns[columnIndex]?.groupPath && isDeepEqual(getParents(visibleColumns[columnIndex]?.groupPath, depth), firstColumnToRenderGroupParents)) {
263
+ const column = visibleColumns[columnIndex];
264
+ leftOverflow += column.computedWidth ?? 0;
265
+
266
+ if (initialHeader.length === 0) {
267
+ initialHeader.push({
268
+ width: column.computedWidth ?? 0,
269
+ fields: [column.field],
270
+ groupId: firstColumnToRenderGroup,
271
+ groupParents: firstColumnToRenderGroupParents,
272
+ colIndex: columnIndex
273
+ });
274
+ } else {
275
+ initialHeader[0].width += column.computedWidth ?? 0;
276
+ initialHeader[0].fields.push(column.field);
277
+ initialHeader[0].colIndex = columnIndex;
278
+ }
279
+
280
+ columnIndex -= 1;
281
+ }
282
+
283
+ const depthInfo = renderedColumns.reduce((aggregated, column, i) => {
284
+ const lastItem = aggregated[aggregated.length - 1];
285
+
286
+ if (column.groupPath && column.groupPath.length > depth) {
287
+ if (lastItem && lastItem.groupId === column.groupPath[depth]) {
288
+ // Merge with the previous columns
289
+ return [...aggregated.slice(0, aggregated.length - 1), _extends({}, lastItem, {
290
+ width: lastItem.width + (column.computedWidth ?? 0),
291
+ fields: [...lastItem.fields, column.field]
292
+ })];
293
+ } // Create a new grouping
294
+
295
+
296
+ return [...aggregated, {
297
+ groupId: column.groupPath[depth],
298
+ groupParents: getParents(column.groupPath, depth),
299
+ width: column.computedWidth ?? 0,
300
+ fields: [column.field],
301
+ colIndex: firstColumnToRender + i
302
+ }];
303
+ }
304
+
305
+ if (MERGE_EMPTY_CELLS && lastItem && lastItem.groupId === null && isDeepEqual(getParents(column.groupPath, depth), lastItem.groupParents)) {
306
+ // We merge with previous column
307
+ return [...aggregated.slice(0, aggregated.length - 1), _extends({}, lastItem, {
308
+ width: lastItem.width + (column.computedWidth ?? 0),
309
+ fields: [...lastItem.fields, column.field]
310
+ })];
311
+ } // We create new empty cell
312
+
313
+
314
+ return [...aggregated, {
315
+ groupId: null,
316
+ groupParents: getParents(column.groupPath, depth),
317
+ width: column.computedWidth ?? 0,
318
+ fields: [column.field],
319
+ colIndex: firstColumnToRender + i
320
+ }];
321
+ }, initialHeader);
322
+ columnIndex = lastColumnToRender;
323
+ const lastColumnToRenderGroup = depthInfo[depthInfo.length - 1].groupId;
324
+
325
+ while (lastColumnToRenderGroup !== null && columnIndex < maxLastColumn && visibleColumns[columnIndex]?.groupPath && visibleColumns[columnIndex]?.groupPath?.[depth] === lastColumnToRenderGroup) {
326
+ const column = visibleColumns[columnIndex];
327
+ depthInfo[depthInfo.length - 1].width += column.computedWidth ?? 0;
328
+ depthInfo[depthInfo.length - 1].fields.push(column.field);
329
+ columnIndex += 1;
330
+ }
331
+
332
+ headerToRender.push({
333
+ leftOverflow,
334
+ elements: [...depthInfo]
335
+ });
336
+ }
337
+
338
+ headerToRender.forEach((depthInfo, depthIndex) => {
339
+ columns.push( /*#__PURE__*/_jsx(GridColumnHeaderRow, {
340
+ style: {
341
+ height: `${headerHeight}px`,
342
+ transform: `translateX(-${depthInfo.leftOverflow}px)`
343
+ },
344
+ role: "row",
345
+ "aria-rowindex": depthIndex + 1,
346
+ children: depthInfo.elements.map(({
347
+ groupId,
348
+ width,
349
+ fields,
350
+ colIndex
351
+ }, groupIndex) => {
352
+ return /*#__PURE__*/_jsx(GridColumnGroupHeader, {
353
+ groupId: groupId,
354
+ width: width,
355
+ fields: fields,
356
+ colIndex: colIndex,
357
+ depth: depthIndex,
358
+ isLastColumn: colIndex === visibleColumns.length - fields.length,
359
+ extendRowFullWidth: !rootProps.disableExtendRowFullWidth,
360
+ maxDepth: headerToRender.length,
361
+ height: headerHeight
362
+ }, groupIndex);
363
+ })
364
+ }, depthIndex));
365
+ });
189
366
  return columns;
190
367
  };
191
368
 
192
369
  const rootStyle = {
193
- minHeight: headerHeight,
194
- maxHeight: headerHeight,
370
+ minHeight: totalHeaderHeight,
371
+ maxHeight: totalHeaderHeight,
195
372
  lineHeight: `${headerHeight}px`
196
373
  };
197
374
  return {
198
375
  renderContext,
199
- getColumns,
376
+ getColumnHeaders,
377
+ getColumnGroupHeaders,
200
378
  isDragging: !!dragCol,
201
379
  getRootProps: (other = {}) => _extends({
202
380
  style: rootStyle
203
381
  }, other),
204
382
  getInnerProps: () => ({
205
383
  ref: handleInnerRef,
206
- 'aria-rowindex': 1,
207
- role: 'row'
384
+ role: 'rowgroup'
208
385
  })
209
386
  };
210
387
  };
@@ -3,4 +3,6 @@ export const gridDensitySelector = state => state.density;
3
3
  export const gridDensityValueSelector = createSelector(gridDensitySelector, density => density.value);
4
4
  export const gridDensityRowHeightSelector = createSelector(gridDensitySelector, density => density.rowHeight);
5
5
  export const gridDensityHeaderHeightSelector = createSelector(gridDensitySelector, density => density.headerHeight);
6
- export const gridDensityFactorSelector = createSelector(gridDensitySelector, density => density.factor);
6
+ export const gridDensityHeaderGroupingMaxDepthSelector = createSelector(gridDensitySelector, density => density.headerGroupingMaxDepth);
7
+ export const gridDensityFactorSelector = createSelector(gridDensitySelector, density => density.factor);
8
+ export const gridDensityTotalHeaderHeightSelector = createSelector(gridDensitySelector, density => density.headerHeight * (1 + density.headerGroupingMaxDepth));
@@ -5,16 +5,20 @@ import { useGridLogger } from '../../utils/useGridLogger';
5
5
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
6
6
  import { gridDensitySelector } from './densitySelector';
7
7
  import { isDeepEqual } from '../../../utils/utils';
8
+ import { useGridSelector } from '../../utils/useGridSelector';
9
+ import { gridVisibleColumnDefinitionsSelector } from '../columns';
10
+ import { unwrapGroupingColumnModel } from '../columnGrouping/useGridColumnGrouping';
8
11
  export const COMPACT_DENSITY_FACTOR = 0.7;
9
12
  export const COMFORTABLE_DENSITY_FACTOR = 1.3; // TODO v6: revise keeping headerHeight and rowHeight in state
10
13
 
11
- const getUpdatedDensityState = (newDensity, newHeaderHeight, newRowHeight) => {
14
+ const getUpdatedDensityState = (newDensity, newHeaderHeight, newRowHeight, newMaxDepth) => {
12
15
  switch (newDensity) {
13
16
  case GridDensityTypes.Compact:
14
17
  return {
15
18
  value: newDensity,
16
19
  headerHeight: Math.floor(newHeaderHeight * COMPACT_DENSITY_FACTOR),
17
20
  rowHeight: Math.floor(newRowHeight * COMPACT_DENSITY_FACTOR),
21
+ headerGroupingMaxDepth: newMaxDepth,
18
22
  factor: COMPACT_DENSITY_FACTOR
19
23
  };
20
24
 
@@ -23,6 +27,7 @@ const getUpdatedDensityState = (newDensity, newHeaderHeight, newRowHeight) => {
23
27
  value: newDensity,
24
28
  headerHeight: Math.floor(newHeaderHeight * COMFORTABLE_DENSITY_FACTOR),
25
29
  rowHeight: Math.floor(newRowHeight * COMFORTABLE_DENSITY_FACTOR),
30
+ headerGroupingMaxDepth: newMaxDepth,
26
31
  factor: COMFORTABLE_DENSITY_FACTOR
27
32
  };
28
33
 
@@ -31,21 +36,44 @@ const getUpdatedDensityState = (newDensity, newHeaderHeight, newRowHeight) => {
31
36
  value: newDensity,
32
37
  headerHeight: newHeaderHeight,
33
38
  rowHeight: newRowHeight,
39
+ headerGroupingMaxDepth: newMaxDepth,
34
40
  factor: 1
35
41
  };
36
42
  }
37
43
  };
38
44
 
39
- export const densityStateInitializer = (state, props) => _extends({}, state, {
40
- density: getUpdatedDensityState(props.density, props.headerHeight, props.rowHeight)
41
- });
45
+ export const densityStateInitializer = (state, props) => {
46
+ // TODO: think about improving this initialization. Could it be done in the useColumn initializer?
47
+ // TODO: manage to remove ts-ignore
48
+ let maxDepth;
49
+
50
+ if (props.columnGroupingModel == null || Object.keys(props.columnGroupingModel).length === 0) {
51
+ maxDepth = 0;
52
+ } else {
53
+ const unwrappedGroupingColumnModel = unwrapGroupingColumnModel(props.columnGroupingModel);
54
+ const columnsState = state.columns;
55
+ const visibleColumns = columnsState.all.filter(field => columnsState.columnVisibilityModel[field] !== false);
56
+
57
+ if (visibleColumns.length === 0) {
58
+ maxDepth = 0;
59
+ } else {
60
+ maxDepth = Math.max(...visibleColumns.map(field => unwrappedGroupingColumnModel[field]?.length ?? 0));
61
+ }
62
+ }
63
+
64
+ return _extends({}, state, {
65
+ density: getUpdatedDensityState(props.density, props.headerHeight, props.rowHeight, maxDepth)
66
+ });
67
+ };
42
68
  export const useGridDensity = (apiRef, props) => {
69
+ const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
70
+ const maxDepth = visibleColumns.length > 0 ? Math.max(...visibleColumns.map(column => column.groupPath?.length ?? 0)) : 0;
43
71
  const logger = useGridLogger(apiRef, 'useDensity');
44
- const setDensity = React.useCallback((newDensity, newHeaderHeight = props.headerHeight, newRowHeight = props.rowHeight) => {
72
+ const setDensity = React.useCallback((newDensity, newHeaderHeight = props.headerHeight, newRowHeight = props.rowHeight, newMaxDepth = maxDepth) => {
45
73
  logger.debug(`Set grid density to ${newDensity}`);
46
74
  apiRef.current.setState(state => {
47
75
  const currentDensityState = gridDensitySelector(state);
48
- const newDensityState = getUpdatedDensityState(newDensity, newHeaderHeight, newRowHeight);
76
+ const newDensityState = getUpdatedDensityState(newDensity, newHeaderHeight, newRowHeight, newMaxDepth);
49
77
 
50
78
  if (isDeepEqual(currentDensityState, newDensityState)) {
51
79
  return state;
@@ -56,10 +84,10 @@ export const useGridDensity = (apiRef, props) => {
56
84
  });
57
85
  });
58
86
  apiRef.current.forceUpdate();
59
- }, [logger, apiRef, props.headerHeight, props.rowHeight]);
87
+ }, [logger, apiRef, props.headerHeight, props.rowHeight, maxDepth]);
60
88
  React.useEffect(() => {
61
- apiRef.current.setDensity(props.density, props.headerHeight, props.rowHeight);
62
- }, [apiRef, props.density, props.rowHeight, props.headerHeight]);
89
+ apiRef.current.setDensity(props.density, props.headerHeight, props.rowHeight, maxDepth);
90
+ }, [apiRef, props.density, props.rowHeight, props.headerHeight, maxDepth]);
63
91
  const densityApi = {
64
92
  setDensity
65
93
  };
@@ -4,7 +4,7 @@ import { useGridApiEventHandler, useGridApiOptionHandler } from '../../utils/use
4
4
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
5
5
  import { useGridLogger } from '../../utils/useGridLogger';
6
6
  import { gridColumnsTotalWidthSelector } from '../columns';
7
- import { gridDensityHeaderHeightSelector, gridDensityRowHeightSelector } from '../density';
7
+ import { gridDensityTotalHeaderHeightSelector, gridDensityRowHeightSelector } from '../density';
8
8
  import { useGridSelector } from '../../utils';
9
9
  import { getVisibleRows } from '../../utils/useGridVisibleRows';
10
10
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
@@ -42,7 +42,7 @@ export function useGridDimensions(apiRef, props) {
42
42
  const rootDimensionsRef = React.useRef(null);
43
43
  const fullDimensionsRef = React.useRef(null);
44
44
  const rowsMeta = useGridSelector(apiRef, gridRowsMetaSelector);
45
- const headerHeight = useGridSelector(apiRef, gridDensityHeaderHeightSelector);
45
+ const totalHeaderHeight = useGridSelector(apiRef, gridDensityTotalHeaderHeightSelector);
46
46
  const updateGridDimensionsRef = React.useCallback(() => {
47
47
  const rootElement = apiRef.current.rootElementRef?.current;
48
48
  const columnsTotalWidth = gridColumnsTotalWidthSelector(apiRef);
@@ -85,7 +85,7 @@ export function useGridDimensions(apiRef, props) {
85
85
  } else {
86
86
  viewportOuterSize = {
87
87
  width: rootDimensionsRef.current.width,
88
- height: rootDimensionsRef.current.height - headerHeight
88
+ height: rootDimensionsRef.current.height - totalHeaderHeight
89
89
  };
90
90
  const scrollInformation = hasScroll({
91
91
  content: {
@@ -119,7 +119,7 @@ export function useGridDimensions(apiRef, props) {
119
119
  if (newFullDimensions.viewportInnerSize.width !== prevDimensions?.viewportInnerSize.width || newFullDimensions.viewportInnerSize.height !== prevDimensions?.viewportInnerSize.height) {
120
120
  apiRef.current.publishEvent('viewportInnerSizeChange', newFullDimensions.viewportInnerSize);
121
121
  }
122
- }, [apiRef, props.scrollbarSize, props.autoHeight, headerHeight, rowsMeta.currentPageTotalHeight]);
122
+ }, [apiRef, props.scrollbarSize, props.autoHeight, totalHeaderHeight, rowsMeta.currentPageTotalHeight]);
123
123
  const resize = React.useCallback(() => {
124
124
  updateGridDimensionsRef();
125
125
  apiRef.current.publishEvent('debouncedResize', rootDimensionsRef.current);
@@ -4,7 +4,7 @@ import { ownerDocument } from '@mui/material/utils';
4
4
  import { useGridLogger } from '../../utils/useGridLogger';
5
5
  import { gridVisibleRowCountSelector } from '../filter/gridFilterSelector';
6
6
  import { gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector } from '../columns/gridColumnsSelector';
7
- import { gridDensityHeaderHeightSelector } from '../density/densitySelector';
7
+ import { gridDensityTotalHeaderHeightSelector } from '../density/densitySelector';
8
8
  import { gridClasses } from '../../../constants/gridClasses';
9
9
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
10
10
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
@@ -77,7 +77,7 @@ export const useGridPrintExport = (apiRef, props) => {
77
77
  return;
78
78
  }
79
79
 
80
- const headerHeight = gridDensityHeaderHeightSelector(apiRef);
80
+ const totalHeaderHeight = gridDensityTotalHeaderHeightSelector(apiRef);
81
81
  const rowsMeta = gridRowsMetaSelector(apiRef.current.state);
82
82
  const gridRootElement = apiRef.current.rootElementRef.current;
83
83
  const gridClone = gridRootElement.cloneNode(true);
@@ -107,7 +107,7 @@ export const useGridPrintExport = (apiRef, props) => {
107
107
  } // Expand container height to accommodate all rows
108
108
 
109
109
 
110
- gridClone.style.height = `${rowsMeta.currentPageTotalHeight + headerHeight + gridToolbarElementHeight + gridFooterElementHeight}px`; // Remove all loaded elements from the current host
110
+ gridClone.style.height = `${rowsMeta.currentPageTotalHeight + totalHeaderHeight + gridToolbarElementHeight + gridFooterElementHeight}px`; // Remove all loaded elements from the current host
111
111
 
112
112
  printDoc.body.innerHTML = '';
113
113
  printDoc.body.appendChild(gridClone);