@mui/x-data-grid 7.0.0-alpha.8 → 7.0.0-alpha.9

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 (410) hide show
  1. package/CHANGELOG.md +379 -2
  2. package/DataGrid/DataGrid.js +6 -6
  3. package/DataGrid/useDataGridComponent.js +2 -1
  4. package/DataGrid/useDataGridProps.js +1 -0
  5. package/README.md +1 -1
  6. package/components/GridColumnHeaders.d.ts +3 -2
  7. package/components/GridColumnHeaders.js +3 -11
  8. package/components/GridDetailPanels.d.ts +5 -0
  9. package/components/GridDetailPanels.js +4 -0
  10. package/components/GridHeaders.d.ts +4 -0
  11. package/components/GridHeaders.js +53 -0
  12. package/components/GridPinnedRows.d.ts +7 -0
  13. package/components/GridPinnedRows.js +4 -0
  14. package/components/GridRow.d.ts +7 -4
  15. package/components/GridRow.js +260 -97
  16. package/components/GridScrollbarFillerCell.d.ts +7 -0
  17. package/components/GridScrollbarFillerCell.js +39 -0
  18. package/components/base/GridBody.d.ts +2 -13
  19. package/components/base/GridBody.js +2 -116
  20. package/components/base/GridOverlays.js +10 -21
  21. package/components/cell/GridActionsCellItem.d.ts +2 -2
  22. package/components/cell/GridCell.d.ts +15 -21
  23. package/components/cell/GridCell.js +67 -372
  24. package/components/columnHeaders/GridBaseColumnHeaders.js +1 -6
  25. package/components/columnHeaders/GridColumnHeaderItem.d.ts +2 -1
  26. package/components/columnHeaders/GridColumnHeaderItem.js +7 -3
  27. package/components/columnHeaders/GridColumnHeaderSortIcon.d.ts +1 -0
  28. package/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -2
  29. package/components/columnHeaders/GridColumnHeadersInner.js +1 -2
  30. package/components/containers/GridRoot.js +18 -15
  31. package/components/containers/GridRootStyles.js +307 -204
  32. package/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +1 -1
  33. package/components/panel/GridPanel.js +3 -4
  34. package/components/panel/filterPanel/GridFilterForm.d.ts +6 -4
  35. package/components/panel/filterPanel/GridFilterForm.js +31 -14
  36. package/components/panel/filterPanel/GridFilterPanel.js +46 -20
  37. package/components/toolbar/GridToolbarColumnsButton.d.ts +13 -1
  38. package/components/toolbar/GridToolbarColumnsButton.js +40 -22
  39. package/components/toolbar/GridToolbarDensitySelector.d.ts +13 -1
  40. package/components/toolbar/GridToolbarDensitySelector.js +40 -22
  41. package/components/toolbar/GridToolbarExport.d.ts +10 -1
  42. package/components/toolbar/GridToolbarExport.js +6 -1
  43. package/components/toolbar/GridToolbarExportContainer.d.ts +15 -1
  44. package/components/toolbar/GridToolbarExportContainer.js +41 -23
  45. package/components/toolbar/GridToolbarFilterButton.d.ts +5 -4
  46. package/components/toolbar/GridToolbarFilterButton.js +6 -10
  47. package/components/virtualization/GridBottomContainer.d.ts +2 -0
  48. package/components/virtualization/GridBottomContainer.js +25 -0
  49. package/components/{containers → virtualization}/GridMainContainer.d.ts +2 -0
  50. package/components/virtualization/GridMainContainer.js +20 -0
  51. package/components/virtualization/GridTopContainer.d.ts +2 -0
  52. package/components/virtualization/GridTopContainer.js +35 -0
  53. package/components/virtualization/GridVirtualScrollbar.d.ts +7 -0
  54. package/components/virtualization/GridVirtualScrollbar.js +131 -0
  55. package/components/virtualization/GridVirtualScroller.d.ts +4 -4
  56. package/components/virtualization/GridVirtualScroller.js +69 -16
  57. package/components/virtualization/GridVirtualScrollerFiller.d.ts +4 -0
  58. package/components/virtualization/GridVirtualScrollerFiller.js +71 -0
  59. package/components/virtualization/GridVirtualScrollerRenderZone.js +2 -1
  60. package/constants/defaultGridSlotsComponents.js +6 -2
  61. package/constants/gridClasses.d.ts +60 -8
  62. package/constants/gridClasses.js +1 -1
  63. package/hooks/core/gridCoreSelector.d.ts +6 -0
  64. package/hooks/core/gridCoreSelector.js +5 -0
  65. package/hooks/core/useGridInitialization.js +4 -0
  66. package/hooks/core/useGridRefs.d.ts +3 -0
  67. package/hooks/core/useGridRefs.js +13 -0
  68. package/hooks/core/useGridTheme.d.ts +3 -0
  69. package/hooks/core/useGridTheme.js +19 -0
  70. package/hooks/features/columnGrouping/useGridColumnGrouping.d.ts +1 -1
  71. package/hooks/features/columnGrouping/useGridColumnGrouping.js +7 -14
  72. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +13 -18
  73. package/hooks/features/columnHeaders/useGridColumnHeaders.js +68 -162
  74. package/hooks/features/columnMenu/useGridColumnMenu.js +28 -23
  75. package/hooks/features/columns/gridColumnsInterfaces.d.ts +17 -0
  76. package/hooks/features/columns/gridColumnsInterfaces.js +9 -1
  77. package/hooks/features/columns/gridColumnsSelector.d.ts +14 -1
  78. package/hooks/features/columns/gridColumnsSelector.js +52 -0
  79. package/hooks/features/columns/gridColumnsUtils.d.ts +1 -5
  80. package/hooks/features/columns/gridColumnsUtils.js +10 -12
  81. package/hooks/features/columns/index.d.ts +2 -2
  82. package/hooks/features/columns/index.js +2 -1
  83. package/hooks/features/columns/useGridColumnSpanning.js +62 -61
  84. package/hooks/features/columns/useGridColumns.js +20 -23
  85. package/hooks/features/dimensions/gridDimensionsApi.d.ts +60 -11
  86. package/hooks/features/dimensions/gridDimensionsSelectors.d.ts +2 -0
  87. package/hooks/features/dimensions/gridDimensionsSelectors.js +1 -0
  88. package/hooks/features/dimensions/index.d.ts +2 -0
  89. package/hooks/features/dimensions/index.js +1 -0
  90. package/hooks/features/dimensions/useGridDimensions.d.ts +7 -1
  91. package/hooks/features/dimensions/useGridDimensions.js +216 -148
  92. package/hooks/features/export/serializers/csvSerializer.js +2 -2
  93. package/hooks/features/filter/useGridFilter.js +3 -3
  94. package/hooks/features/focus/gridFocusStateSelector.d.ts +2 -2
  95. package/hooks/features/focus/gridFocusStateSelector.js +2 -6
  96. package/hooks/features/focus/useGridFocus.js +3 -3
  97. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +3 -16
  98. package/hooks/features/pagination/useGridPagination.js +3 -5
  99. package/hooks/features/rows/gridRowsInterfaces.d.ts +1 -0
  100. package/hooks/features/rows/gridRowsSelector.d.ts +2 -2
  101. package/hooks/features/rows/gridRowsSelector.js +5 -5
  102. package/hooks/features/rows/gridRowsUtils.d.ts +1 -1
  103. package/hooks/features/rows/gridRowsUtils.js +4 -4
  104. package/hooks/features/rows/useGridRowsMeta.js +7 -4
  105. package/hooks/features/scroll/useGridScroll.js +8 -10
  106. package/hooks/features/sorting/gridSortingUtils.js +1 -1
  107. package/hooks/features/sorting/useGridSorting.d.ts +1 -1
  108. package/hooks/features/sorting/useGridSorting.js +15 -10
  109. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +14 -0
  110. package/hooks/features/virtualization/gridVirtualizationSelectors.js +22 -2
  111. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +27 -42
  112. package/hooks/features/virtualization/useGridVirtualScroller.js +441 -438
  113. package/hooks/features/virtualization/useGridVirtualization.d.ts +8 -0
  114. package/hooks/features/virtualization/useGridVirtualization.js +8 -1
  115. package/hooks/utils/index.d.ts +3 -0
  116. package/hooks/utils/index.js +4 -1
  117. package/hooks/utils/useGridAriaAttributes.js +1 -2
  118. package/hooks/utils/useGridNativeEventListener.js +4 -9
  119. package/hooks/utils/useResizeObserver.d.ts +2 -0
  120. package/hooks/utils/useResizeObserver.js +36 -0
  121. package/hooks/utils/useRunOnce.d.ts +5 -0
  122. package/hooks/utils/useRunOnce.js +18 -0
  123. package/index.js +1 -1
  124. package/internals/index.d.ts +12 -9
  125. package/internals/index.js +9 -7
  126. package/legacy/DataGrid/DataGrid.js +6 -6
  127. package/legacy/DataGrid/useDataGridComponent.js +2 -1
  128. package/legacy/DataGrid/useDataGridProps.js +1 -0
  129. package/legacy/components/GridColumnHeaders.js +3 -11
  130. package/legacy/components/GridDetailPanels.js +4 -0
  131. package/legacy/components/GridHeaders.js +53 -0
  132. package/legacy/components/GridPinnedRows.js +4 -0
  133. package/legacy/components/GridRow.js +258 -98
  134. package/legacy/components/GridScrollbarFillerCell.js +36 -0
  135. package/legacy/components/base/GridBody.js +2 -114
  136. package/legacy/components/base/GridOverlays.js +10 -25
  137. package/legacy/components/cell/GridCell.js +69 -377
  138. package/legacy/components/columnHeaders/GridBaseColumnHeaders.js +1 -6
  139. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +7 -3
  140. package/legacy/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -2
  141. package/legacy/components/columnHeaders/GridColumnHeadersInner.js +1 -2
  142. package/legacy/components/containers/GridRoot.js +18 -15
  143. package/legacy/components/containers/GridRootStyles.js +215 -137
  144. package/legacy/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +1 -1
  145. package/legacy/components/panel/GridPanel.js +3 -4
  146. package/legacy/components/panel/filterPanel/GridFilterForm.js +30 -13
  147. package/legacy/components/panel/filterPanel/GridFilterPanel.js +49 -20
  148. package/legacy/components/toolbar/GridToolbarColumnsButton.js +40 -21
  149. package/legacy/components/toolbar/GridToolbarDensitySelector.js +40 -21
  150. package/legacy/components/toolbar/GridToolbarExport.js +6 -1
  151. package/legacy/components/toolbar/GridToolbarExportContainer.js +40 -21
  152. package/legacy/components/toolbar/GridToolbarFilterButton.js +6 -10
  153. package/legacy/components/virtualization/GridBottomContainer.js +25 -0
  154. package/legacy/components/virtualization/GridMainContainer.js +20 -0
  155. package/legacy/components/virtualization/GridTopContainer.js +35 -0
  156. package/legacy/components/virtualization/GridVirtualScrollbar.js +129 -0
  157. package/legacy/components/virtualization/GridVirtualScroller.js +67 -16
  158. package/legacy/components/virtualization/GridVirtualScrollerFiller.js +70 -0
  159. package/legacy/components/virtualization/GridVirtualScrollerRenderZone.js +2 -1
  160. package/legacy/constants/defaultGridSlotsComponents.js +6 -2
  161. package/legacy/constants/gridClasses.js +1 -1
  162. package/legacy/hooks/core/gridCoreSelector.js +7 -0
  163. package/legacy/hooks/core/useGridInitialization.js +4 -0
  164. package/legacy/hooks/core/useGridRefs.js +13 -0
  165. package/legacy/hooks/core/useGridTheme.js +21 -0
  166. package/legacy/hooks/features/columnGrouping/useGridColumnGrouping.js +7 -14
  167. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +69 -181
  168. package/legacy/hooks/features/columnMenu/useGridColumnMenu.js +28 -23
  169. package/legacy/hooks/features/columns/gridColumnsInterfaces.js +9 -1
  170. package/legacy/hooks/features/columns/gridColumnsSelector.js +62 -0
  171. package/legacy/hooks/features/columns/gridColumnsUtils.js +10 -16
  172. package/legacy/hooks/features/columns/index.js +2 -1
  173. package/legacy/hooks/features/columns/useGridColumnSpanning.js +60 -59
  174. package/legacy/hooks/features/columns/useGridColumns.js +22 -23
  175. package/legacy/hooks/features/dimensions/gridDimensionsSelectors.js +3 -0
  176. package/legacy/hooks/features/dimensions/index.js +1 -0
  177. package/legacy/hooks/features/dimensions/useGridDimensions.js +226 -151
  178. package/legacy/hooks/features/export/serializers/csvSerializer.js +2 -2
  179. package/legacy/hooks/features/filter/useGridFilter.js +3 -3
  180. package/legacy/hooks/features/focus/gridFocusStateSelector.js +2 -6
  181. package/legacy/hooks/features/focus/useGridFocus.js +3 -3
  182. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +3 -16
  183. package/legacy/hooks/features/pagination/useGridPagination.js +3 -5
  184. package/legacy/hooks/features/rows/gridRowsSelector.js +5 -5
  185. package/legacy/hooks/features/rows/gridRowsUtils.js +4 -4
  186. package/legacy/hooks/features/rows/useGridRowsMeta.js +7 -4
  187. package/legacy/hooks/features/scroll/useGridScroll.js +8 -10
  188. package/legacy/hooks/features/sorting/gridSortingUtils.js +1 -1
  189. package/legacy/hooks/features/sorting/useGridSorting.js +15 -10
  190. package/legacy/hooks/features/virtualization/gridVirtualizationSelectors.js +29 -1
  191. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +490 -483
  192. package/legacy/hooks/features/virtualization/useGridVirtualization.js +8 -1
  193. package/legacy/hooks/utils/index.js +4 -1
  194. package/legacy/hooks/utils/useGridAriaAttributes.js +1 -2
  195. package/legacy/hooks/utils/useGridNativeEventListener.js +4 -9
  196. package/legacy/hooks/utils/useResizeObserver.js +36 -0
  197. package/legacy/hooks/utils/useRunOnce.js +18 -0
  198. package/legacy/index.js +1 -1
  199. package/legacy/internals/index.js +9 -7
  200. package/legacy/locales/hrHR.js +161 -0
  201. package/legacy/locales/index.js +4 -1
  202. package/legacy/locales/ptPT.js +161 -0
  203. package/legacy/locales/zhHK.js +161 -0
  204. package/legacy/models/index.js +0 -1
  205. package/legacy/models/params/index.js +1 -2
  206. package/legacy/utils/utils.js +10 -1
  207. package/locales/hrHR.d.ts +1 -0
  208. package/locales/hrHR.js +149 -0
  209. package/locales/index.d.ts +3 -0
  210. package/locales/index.js +4 -1
  211. package/locales/ptPT.d.ts +1 -0
  212. package/locales/ptPT.js +149 -0
  213. package/locales/zhHK.d.ts +1 -0
  214. package/locales/zhHK.js +149 -0
  215. package/models/api/gridColumnGroupingApi.d.ts +2 -2
  216. package/models/api/gridCoreApi.d.ts +16 -16
  217. package/models/api/gridRowsMetaApi.d.ts +1 -1
  218. package/models/api/gridVirtualizationApi.d.ts +2 -3
  219. package/models/events/gridEventLookup.d.ts +3 -3
  220. package/models/gridFilterModel.d.ts +1 -1
  221. package/models/gridSlotsComponent.d.ts +16 -2
  222. package/models/gridStateCommunity.d.ts +5 -1
  223. package/models/index.d.ts +0 -1
  224. package/models/index.js +0 -1
  225. package/models/params/index.d.ts +0 -1
  226. package/models/params/index.js +1 -2
  227. package/models/props/DataGridProps.d.ts +6 -11
  228. package/modern/DataGrid/DataGrid.js +6 -6
  229. package/modern/DataGrid/useDataGridComponent.js +2 -1
  230. package/modern/DataGrid/useDataGridProps.js +1 -0
  231. package/modern/components/GridColumnHeaders.js +3 -11
  232. package/modern/components/GridDetailPanels.js +4 -0
  233. package/modern/components/GridHeaders.js +53 -0
  234. package/modern/components/GridPinnedRows.js +4 -0
  235. package/modern/components/GridRow.js +258 -96
  236. package/modern/components/GridScrollbarFillerCell.js +39 -0
  237. package/modern/components/base/GridBody.js +2 -116
  238. package/modern/components/base/GridOverlays.js +10 -16
  239. package/modern/components/cell/GridCell.js +65 -369
  240. package/modern/components/columnHeaders/GridBaseColumnHeaders.js +1 -6
  241. package/modern/components/columnHeaders/GridColumnHeaderItem.js +7 -3
  242. package/modern/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -2
  243. package/modern/components/columnHeaders/GridColumnHeadersInner.js +1 -1
  244. package/modern/components/containers/GridRoot.js +18 -14
  245. package/modern/components/containers/GridRootStyles.js +307 -204
  246. package/modern/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +1 -1
  247. package/modern/components/panel/GridPanel.js +3 -4
  248. package/modern/components/panel/filterPanel/GridFilterForm.js +30 -13
  249. package/modern/components/panel/filterPanel/GridFilterPanel.js +46 -20
  250. package/modern/components/toolbar/GridToolbarColumnsButton.js +38 -21
  251. package/modern/components/toolbar/GridToolbarDensitySelector.js +38 -21
  252. package/modern/components/toolbar/GridToolbarExport.js +6 -1
  253. package/modern/components/toolbar/GridToolbarExportContainer.js +39 -22
  254. package/modern/components/toolbar/GridToolbarFilterButton.js +6 -10
  255. package/modern/components/virtualization/GridBottomContainer.js +25 -0
  256. package/modern/components/virtualization/GridMainContainer.js +20 -0
  257. package/modern/components/virtualization/GridTopContainer.js +35 -0
  258. package/modern/components/virtualization/GridVirtualScrollbar.js +131 -0
  259. package/modern/components/virtualization/GridVirtualScroller.js +69 -16
  260. package/modern/components/virtualization/GridVirtualScrollerFiller.js +71 -0
  261. package/modern/components/virtualization/GridVirtualScrollerRenderZone.js +2 -1
  262. package/modern/constants/defaultGridSlotsComponents.js +6 -2
  263. package/modern/constants/gridClasses.js +1 -1
  264. package/modern/hooks/core/gridCoreSelector.js +5 -0
  265. package/modern/hooks/core/useGridInitialization.js +4 -0
  266. package/modern/hooks/core/useGridRefs.js +13 -0
  267. package/modern/hooks/core/useGridTheme.js +19 -0
  268. package/modern/hooks/features/columnGrouping/useGridColumnGrouping.js +5 -12
  269. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +67 -160
  270. package/modern/hooks/features/columnMenu/useGridColumnMenu.js +28 -23
  271. package/modern/hooks/features/columns/gridColumnsInterfaces.js +9 -1
  272. package/modern/hooks/features/columns/gridColumnsSelector.js +51 -0
  273. package/modern/hooks/features/columns/gridColumnsUtils.js +10 -12
  274. package/modern/hooks/features/columns/index.js +2 -1
  275. package/modern/hooks/features/columns/useGridColumnSpanning.js +62 -61
  276. package/modern/hooks/features/columns/useGridColumns.js +19 -21
  277. package/modern/hooks/features/dimensions/gridDimensionsSelectors.js +1 -0
  278. package/modern/hooks/features/dimensions/index.js +1 -0
  279. package/modern/hooks/features/dimensions/useGridDimensions.js +214 -146
  280. package/modern/hooks/features/export/serializers/csvSerializer.js +2 -2
  281. package/modern/hooks/features/filter/useGridFilter.js +3 -3
  282. package/modern/hooks/features/focus/gridFocusStateSelector.js +2 -6
  283. package/modern/hooks/features/focus/useGridFocus.js +3 -3
  284. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +3 -16
  285. package/modern/hooks/features/pagination/useGridPagination.js +3 -5
  286. package/modern/hooks/features/rows/gridRowsSelector.js +2 -2
  287. package/modern/hooks/features/rows/gridRowsUtils.js +4 -4
  288. package/modern/hooks/features/rows/useGridRowsMeta.js +7 -4
  289. package/modern/hooks/features/scroll/useGridScroll.js +8 -9
  290. package/modern/hooks/features/sorting/gridSortingUtils.js +1 -1
  291. package/modern/hooks/features/sorting/useGridSorting.js +15 -10
  292. package/modern/hooks/features/virtualization/gridVirtualizationSelectors.js +22 -2
  293. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +435 -432
  294. package/modern/hooks/features/virtualization/useGridVirtualization.js +8 -1
  295. package/modern/hooks/utils/index.js +4 -1
  296. package/modern/hooks/utils/useGridAriaAttributes.js +1 -1
  297. package/modern/hooks/utils/useGridNativeEventListener.js +3 -9
  298. package/modern/hooks/utils/useResizeObserver.js +36 -0
  299. package/modern/hooks/utils/useRunOnce.js +18 -0
  300. package/modern/index.js +1 -1
  301. package/modern/internals/index.js +9 -7
  302. package/modern/locales/hrHR.js +149 -0
  303. package/modern/locales/index.js +4 -1
  304. package/modern/locales/ptPT.js +149 -0
  305. package/modern/locales/zhHK.js +149 -0
  306. package/modern/models/index.js +0 -1
  307. package/modern/models/params/index.js +1 -2
  308. package/modern/utils/utils.js +10 -1
  309. package/node/DataGrid/DataGrid.js +6 -6
  310. package/node/DataGrid/useDataGridComponent.js +1 -0
  311. package/node/DataGrid/useDataGridProps.js +1 -0
  312. package/node/components/GridColumnHeaders.js +3 -11
  313. package/node/components/GridDetailPanels.js +10 -0
  314. package/node/components/GridHeaders.js +60 -0
  315. package/node/components/GridPinnedRows.js +10 -0
  316. package/node/components/GridRow.js +256 -94
  317. package/node/components/GridScrollbarFillerCell.js +47 -0
  318. package/node/components/base/GridBody.js +7 -118
  319. package/node/components/base/GridOverlays.js +9 -15
  320. package/node/components/cell/GridCell.js +66 -369
  321. package/node/components/columnHeaders/GridBaseColumnHeaders.js +1 -6
  322. package/node/components/columnHeaders/GridColumnHeaderItem.js +8 -4
  323. package/node/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -2
  324. package/node/components/columnHeaders/GridColumnHeadersInner.js +1 -1
  325. package/node/components/containers/GridRoot.js +17 -14
  326. package/node/components/containers/GridRootStyles.js +175 -72
  327. package/node/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.js +1 -1
  328. package/node/components/panel/GridPanel.js +3 -4
  329. package/node/components/panel/filterPanel/GridFilterForm.js +29 -12
  330. package/node/components/panel/filterPanel/GridFilterPanel.js +45 -19
  331. package/node/components/toolbar/GridToolbarColumnsButton.js +36 -20
  332. package/node/components/toolbar/GridToolbarDensitySelector.js +36 -20
  333. package/node/components/toolbar/GridToolbarExport.js +6 -1
  334. package/node/components/toolbar/GridToolbarExportContainer.js +37 -21
  335. package/node/components/toolbar/GridToolbarFilterButton.js +6 -10
  336. package/node/components/virtualization/GridBottomContainer.js +34 -0
  337. package/node/components/{containers → virtualization}/GridMainContainer.js +7 -29
  338. package/node/components/virtualization/GridTopContainer.js +44 -0
  339. package/node/components/virtualization/GridVirtualScrollbar.js +138 -0
  340. package/node/components/virtualization/GridVirtualScroller.js +69 -17
  341. package/node/components/virtualization/GridVirtualScrollerFiller.js +77 -0
  342. package/node/components/virtualization/GridVirtualScrollerRenderZone.js +2 -1
  343. package/node/constants/defaultGridSlotsComponents.js +5 -1
  344. package/node/constants/gridClasses.js +1 -1
  345. package/node/hooks/core/gridCoreSelector.js +12 -0
  346. package/node/hooks/core/useGridInitialization.js +4 -0
  347. package/node/hooks/core/useGridRefs.js +22 -0
  348. package/node/hooks/core/useGridTheme.js +29 -0
  349. package/node/hooks/features/columnGrouping/useGridColumnGrouping.js +5 -12
  350. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +65 -159
  351. package/node/hooks/features/columnMenu/useGridColumnMenu.js +28 -23
  352. package/node/hooks/features/columns/gridColumnsInterfaces.js +11 -1
  353. package/node/hooks/features/columns/gridColumnsSelector.js +52 -1
  354. package/node/hooks/features/columns/gridColumnsUtils.js +10 -13
  355. package/node/hooks/features/columns/index.js +22 -61
  356. package/node/hooks/features/columns/useGridColumnSpanning.js +62 -61
  357. package/node/hooks/features/columns/useGridColumns.js +20 -22
  358. package/node/hooks/features/dimensions/gridDimensionsSelectors.js +8 -0
  359. package/node/hooks/features/dimensions/index.js +11 -0
  360. package/node/hooks/features/dimensions/useGridDimensions.js +215 -144
  361. package/node/hooks/features/export/serializers/csvSerializer.js +2 -2
  362. package/node/hooks/features/filter/useGridFilter.js +2 -2
  363. package/node/hooks/features/focus/gridFocusStateSelector.js +3 -7
  364. package/node/hooks/features/focus/useGridFocus.js +2 -2
  365. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -15
  366. package/node/hooks/features/pagination/useGridPagination.js +3 -5
  367. package/node/hooks/features/rows/gridRowsSelector.js +2 -2
  368. package/node/hooks/features/rows/gridRowsUtils.js +4 -4
  369. package/node/hooks/features/rows/useGridRowsMeta.js +5 -3
  370. package/node/hooks/features/scroll/useGridScroll.js +8 -9
  371. package/node/hooks/features/sorting/gridSortingUtils.js +1 -1
  372. package/node/hooks/features/sorting/useGridSorting.js +15 -10
  373. package/node/hooks/features/virtualization/gridVirtualizationSelectors.js +22 -2
  374. package/node/hooks/features/virtualization/useGridVirtualScroller.js +434 -431
  375. package/node/hooks/features/virtualization/useGridVirtualization.js +9 -1
  376. package/node/hooks/utils/index.js +36 -0
  377. package/node/hooks/utils/useGridAriaAttributes.js +1 -1
  378. package/node/hooks/utils/useGridNativeEventListener.js +3 -9
  379. package/node/hooks/utils/useResizeObserver.js +44 -0
  380. package/node/hooks/utils/useRunOnce.js +27 -0
  381. package/node/index.js +1 -1
  382. package/node/internals/index.js +86 -71
  383. package/node/locales/hrHR.js +155 -0
  384. package/node/locales/index.js +33 -0
  385. package/node/locales/ptPT.js +155 -0
  386. package/node/locales/zhHK.js +155 -0
  387. package/node/models/index.js +0 -11
  388. package/node/models/params/index.js +0 -11
  389. package/node/utils/utils.js +11 -1
  390. package/package.json +6 -6
  391. package/utils/utils.d.ts +6 -0
  392. package/utils/utils.js +10 -1
  393. package/components/DataGridVirtualScroller.d.ts +0 -3
  394. package/components/DataGridVirtualScroller.js +0 -35
  395. package/components/containers/GridMainContainer.js +0 -43
  396. package/legacy/components/DataGridVirtualScroller.js +0 -32
  397. package/legacy/components/containers/GridMainContainer.js +0 -45
  398. package/legacy/models/gridRootContainerRef.js +0 -1
  399. package/legacy/models/params/gridRenderedRowsIntervalChangeParams.js +0 -1
  400. package/models/gridRootContainerRef.d.ts +0 -5
  401. package/models/gridRootContainerRef.js +0 -1
  402. package/models/params/gridRenderedRowsIntervalChangeParams.d.ts +0 -10
  403. package/models/params/gridRenderedRowsIntervalChangeParams.js +0 -1
  404. package/modern/components/DataGridVirtualScroller.js +0 -35
  405. package/modern/components/containers/GridMainContainer.js +0 -42
  406. package/modern/models/gridRootContainerRef.js +0 -1
  407. package/modern/models/params/gridRenderedRowsIntervalChangeParams.js +0 -1
  408. package/node/components/DataGridVirtualScroller.js +0 -42
  409. package/node/models/gridRootContainerRef.js +0 -5
  410. package/node/models/params/gridRenderedRowsIntervalChangeParams.js +0 -5
@@ -4,11 +4,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.areRenderContextsEqual = void 0;
8
- exports.binarySearch = binarySearch;
9
- exports.useGridVirtualScroller = exports.getRenderableIndexes = void 0;
7
+ exports.EMPTY_DETAIL_PANELS = void 0;
8
+ exports.areRenderContextsEqual = areRenderContextsEqual;
9
+ exports.useGridVirtualScroller = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
- var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
12
11
  var React = _interopRequireWildcard(require("react"));
13
12
  var ReactDOM = _interopRequireWildcard(require("react-dom"));
14
13
  var _utils = require("@mui/utils");
@@ -17,303 +16,139 @@ var _reselect = require("reselect");
17
16
  var _useGridPrivateApiContext = require("../../utils/useGridPrivateApiContext");
18
17
  var _useGridRootProps = require("../../utils/useGridRootProps");
19
18
  var _useGridSelector = require("../../utils/useGridSelector");
19
+ var _useLazyRef = require("../../utils/useLazyRef");
20
+ var _useResizeObserver = require("../../utils/useResizeObserver");
21
+ var _useRunOnce = require("../../utils/useRunOnce");
20
22
  var _gridColumnsSelector = require("../columns/gridColumnsSelector");
23
+ var _gridDimensionsSelectors = require("../dimensions/gridDimensionsSelectors");
24
+ var _gridRowsSelector = require("../rows/gridRowsSelector");
21
25
  var _gridFocusStateSelector = require("../focus/gridFocusStateSelector");
22
26
  var _useGridVisibleRows = require("../../utils/useGridVisibleRows");
23
- var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler");
24
27
  var _utils2 = require("../../../utils/utils");
25
28
  var _gridRowSelectionSelector = require("../rowSelection/gridRowSelectionSelector");
26
29
  var _gridRowsMetaSelector = require("../rows/gridRowsMetaSelector");
27
30
  var _gridColumnsUtils = require("../columns/gridColumnsUtils");
28
31
  var _gridRowsUtils = require("../rows/gridRowsUtils");
29
32
  var _gridVirtualizationSelectors = require("./gridVirtualizationSelectors");
33
+ var _useGridVirtualization = require("./useGridVirtualization");
30
34
  var _jsxRuntime = require("react/jsx-runtime");
31
- const _excluded = ["style"],
32
- _excluded2 = ["style"]; // Uses binary search to avoid looping through all possible positions
33
35
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
34
36
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
35
- function binarySearch(offset, positions, sliceStart = 0, sliceEnd = positions.length) {
36
- if (positions.length <= 0) {
37
- return -1;
38
- }
39
- if (sliceStart >= sliceEnd) {
40
- return sliceStart;
41
- }
42
- const pivot = sliceStart + Math.floor((sliceEnd - sliceStart) / 2);
43
- const itemOffset = positions[pivot];
44
- return offset <= itemOffset ? binarySearch(offset, positions, sliceStart, pivot) : binarySearch(offset, positions, pivot + 1, sliceEnd);
45
- }
46
- function exponentialSearch(offset, positions, index) {
47
- let interval = 1;
48
- while (index < positions.length && Math.abs(positions[index]) < offset) {
49
- index += interval;
50
- interval *= 2;
51
- }
52
- return binarySearch(offset, positions, Math.floor(index / 2), Math.min(index, positions.length));
53
- }
54
- const getRenderableIndexes = ({
55
- firstIndex,
56
- lastIndex,
57
- buffer,
58
- minFirstIndex,
59
- maxLastIndex
60
- }) => {
61
- return [(0, _utils2.clamp)(firstIndex - buffer, minFirstIndex, maxLastIndex), (0, _utils2.clamp)(lastIndex + buffer, minFirstIndex, maxLastIndex)];
62
- };
63
- exports.getRenderableIndexes = getRenderableIndexes;
64
- const areRenderContextsEqual = (context1, context2) => {
65
- if (context1 === context2) {
66
- return true;
67
- }
68
- return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
69
- };
70
- exports.areRenderContextsEqual = areRenderContextsEqual;
71
- // The `maxSize` is 3 so that reselect caches the `renderedColumns` values for the pinned left,
72
- // unpinned, and pinned right sections.
73
- const MEMOIZE_OPTIONS = {
74
- maxSize: 3
75
- };
76
- const useGridVirtualScroller = props => {
37
+ const EMPTY_DETAIL_PANELS = exports.EMPTY_DETAIL_PANELS = Object.freeze(new Map());
38
+ const useGridVirtualScroller = () => {
77
39
  const apiRef = (0, _useGridPrivateApiContext.useGridPrivateApiContext)();
78
40
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
79
41
  const visibleColumns = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridVisibleColumnDefinitionsSelector);
80
42
  const enabled = (0, _useGridSelector.useGridSelector)(apiRef, _gridVirtualizationSelectors.gridVirtualizationEnabledSelector);
81
43
  const enabledForColumns = (0, _useGridSelector.useGridSelector)(apiRef, _gridVirtualizationSelectors.gridVirtualizationColumnEnabledSelector);
82
- const {
83
- ref,
84
- onRenderZonePositioning,
85
- renderZoneMinColumnIndex = 0,
86
- renderZoneMaxColumnIndex = visibleColumns.length,
87
- getRowProps
88
- } = props;
44
+ const dimensions = (0, _useGridSelector.useGridSelector)(apiRef, _gridDimensionsSelectors.gridDimensionsSelector);
45
+ const outerSize = dimensions.viewportOuterSize;
46
+ const pinnedRows = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsSelector.gridPinnedRowsSelector);
47
+ const pinnedColumns = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridVisiblePinnedColumnDefinitionsSelector);
48
+ const hasBottomPinnedRows = pinnedRows.bottom.length > 0;
49
+ const [panels, setPanels] = React.useState(EMPTY_DETAIL_PANELS);
89
50
  const theme = (0, _styles.useTheme)();
90
51
  const columnPositions = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridColumnPositionsSelector);
91
- const columnsTotalWidth = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridColumnsTotalWidthSelector);
92
52
  const cellFocus = (0, _useGridSelector.useGridSelector)(apiRef, _gridFocusStateSelector.gridFocusCellSelector);
93
53
  const cellTabIndex = (0, _useGridSelector.useGridSelector)(apiRef, _gridFocusStateSelector.gridTabIndexCellSelector);
94
54
  const rowsMeta = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsMetaSelector.gridRowsMetaSelector);
95
55
  const selectedRowsLookup = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowSelectionSelector.selectedIdsLookupSelector);
96
56
  const currentPage = (0, _useGridVisibleRows.useGridVisibleRows)(apiRef, rootProps);
57
+ const gridRootRef = apiRef.current.rootElementRef;
58
+ const mainRef = apiRef.current.mainElementRef;
59
+ const scrollerRef = apiRef.current.virtualScrollerRef;
97
60
  const renderZoneRef = React.useRef(null);
98
- const rootRef = React.useRef(null);
99
- const handleRef = (0, _utils.unstable_useForkRef)(ref, rootRef);
100
- const [renderContext, setRenderContextState] = React.useState(null);
101
- const prevRenderContext = React.useRef(renderContext);
61
+ const scrollbarVerticalRef = React.useRef(null);
62
+ const scrollbarHorizontalRef = React.useRef(null);
63
+ const contentHeight = dimensions.contentSize.height;
64
+ const columnsTotalWidth = dimensions.columnsTotalWidth;
65
+ (0, _useResizeObserver.useResizeObserver)(mainRef, () => apiRef.current.resize());
66
+ const previousContext = React.useRef(_useGridVirtualization.EMPTY_RENDER_CONTEXT);
67
+ const previousRowContext = React.useRef(_useGridVirtualization.EMPTY_RENDER_CONTEXT);
68
+ const renderContext = (0, _useGridSelector.useGridSelector)(apiRef, _gridVirtualizationSelectors.gridRenderContextSelector);
102
69
  const scrollPosition = React.useRef({
103
70
  top: 0,
104
71
  left: 0
105
- });
106
- const [containerDimensions, setContainerDimensions] = React.useState({
107
- width: null,
108
- height: null
109
- });
72
+ }).current;
110
73
  const prevTotalWidth = React.useRef(columnsTotalWidth);
111
- // Each visible row (not to be confused with a filter result) is composed of a central row element
112
- // and up to two additional row elements for pinned columns (left and right).
113
- // When hovering any of these elements, the :hover styles are applied only to the row element that
114
- // was actually hovered, not its additional siblings. To make it look like a contiguous row,
115
- // we add/remove the .Mui-hovered class to all of the row elements inside one visible row.
116
- const [hoveredRowId, setHoveredRowId] = React.useState(null);
117
- const rowStyleCache = React.useRef(Object.create(null));
118
- const prevGetRowProps = React.useRef();
119
- const prevRootRowStyle = React.useRef();
120
- const getRenderedColumnsRef = React.useRef((0, _reselect.defaultMemoize)((columns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, indexOfColumnWithFocusedCell) => {
121
- // If the selected column is not within the current range of columns being displayed,
122
- // we need to render it at either the left or right of the columns,
123
- // depending on whether it is above or below the range.
124
- let focusedCellColumnIndexNotInRange;
125
- const renderedColumns = columns.slice(firstColumnToRender, lastColumnToRender);
126
- if (indexOfColumnWithFocusedCell > -1) {
127
- // check if it is not on the left pinned column.
128
- if (firstColumnToRender > indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell >= minFirstColumn) {
129
- focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
130
- }
131
- // check if it is not on the right pinned column.
132
- else if (lastColumnToRender < indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell < maxLastColumn) {
133
- focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
134
- }
74
+ const getRenderedColumns = (0, _useLazyRef.useLazyRef)(createGetRenderedColumns).current;
75
+ const indexOfRowWithFocusedCell = React.useMemo(() => {
76
+ if (cellFocus !== null) {
77
+ return currentPage.rows.findIndex(row => row.id === cellFocus.id);
135
78
  }
136
- return {
137
- focusedCellColumnIndexNotInRange,
138
- renderedColumns
139
- };
140
- }, MEMOIZE_OPTIONS));
79
+ return -1;
80
+ }, [cellFocus, currentPage.rows]);
141
81
  const indexOfColumnWithFocusedCell = React.useMemo(() => {
142
82
  if (cellFocus !== null) {
143
83
  return visibleColumns.findIndex(column => column.field === cellFocus.field);
144
84
  }
145
85
  return -1;
146
86
  }, [cellFocus, visibleColumns]);
147
- const getNearestIndexToRender = React.useCallback(offset => {
148
- const lastMeasuredIndexRelativeToAllRows = apiRef.current.getLastMeasuredRowIndex();
149
- let allRowsMeasured = lastMeasuredIndexRelativeToAllRows === Infinity;
150
- if (currentPage.range?.lastRowIndex && !allRowsMeasured) {
151
- // Check if all rows in this page are already measured
152
- allRowsMeasured = lastMeasuredIndexRelativeToAllRows >= currentPage.range.lastRowIndex;
153
- }
154
- const lastMeasuredIndexRelativeToCurrentPage = (0, _utils2.clamp)(lastMeasuredIndexRelativeToAllRows - (currentPage.range?.firstRowIndex || 0), 0, rowsMeta.positions.length);
155
- if (allRowsMeasured || rowsMeta.positions[lastMeasuredIndexRelativeToCurrentPage] >= offset) {
156
- // If all rows were measured (when no row has "auto" as height) or all rows before the offset
157
- // were measured, then use a binary search because it's faster.
158
- return binarySearch(offset, rowsMeta.positions);
159
- }
160
-
161
- // Otherwise, use an exponential search.
162
- // If rows have "auto" as height, their positions will be based on estimated heights.
163
- // In this case, we can skip several steps until we find a position higher than the offset.
164
- // Inspired by https://github.com/bvaughn/react-virtualized/blob/master/source/Grid/utils/CellSizeAndPositionManager.js
165
- return exponentialSearch(offset, rowsMeta.positions, lastMeasuredIndexRelativeToCurrentPage);
166
- }, [apiRef, currentPage.range?.firstRowIndex, currentPage.range?.lastRowIndex, rowsMeta.positions]);
167
- const computeRenderContext = React.useCallback(() => {
168
- if (!enabled) {
169
- return {
170
- firstRowIndex: 0,
171
- lastRowIndex: currentPage.rows.length,
172
- firstColumnIndex: 0,
173
- lastColumnIndex: visibleColumns.length
174
- };
175
- }
176
- const {
177
- top,
178
- left
179
- } = scrollPosition.current;
180
-
181
- // Clamp the value because the search may return an index out of bounds.
182
- // In the last index, this is not needed because Array.slice doesn't include it.
183
- const firstRowIndex = Math.min(getNearestIndexToRender(top), rowsMeta.positions.length - 1);
184
- const lastRowIndex = rootProps.autoHeight ? firstRowIndex + currentPage.rows.length : getNearestIndexToRender(top + containerDimensions.height);
185
- let firstColumnIndex = 0;
186
- let lastColumnIndex = columnPositions.length;
187
- if (enabledForColumns) {
188
- let hasRowWithAutoHeight = false;
189
- const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
190
- firstIndex: firstRowIndex,
191
- lastIndex: lastRowIndex,
192
- minFirstIndex: 0,
193
- maxLastIndex: currentPage.rows.length,
194
- buffer: rootProps.rowBuffer
195
- });
196
- for (let i = firstRowToRender; i < lastRowToRender && !hasRowWithAutoHeight; i += 1) {
197
- const row = currentPage.rows[i];
198
- hasRowWithAutoHeight = apiRef.current.rowHasAutoHeight(row.id);
199
- }
200
- if (!hasRowWithAutoHeight) {
201
- firstColumnIndex = binarySearch(Math.abs(left), columnPositions);
202
- lastColumnIndex = binarySearch(Math.abs(left) + containerDimensions.width, columnPositions);
203
- }
204
- }
205
- return {
206
- firstRowIndex,
207
- lastRowIndex,
208
- firstColumnIndex,
209
- lastColumnIndex
210
- };
211
- }, [enabled, enabledForColumns, getNearestIndexToRender, rowsMeta.positions.length, rootProps.autoHeight, rootProps.rowBuffer, currentPage.rows, columnPositions, visibleColumns.length, apiRef, containerDimensions]);
212
- (0, _utils.unstable_useEnhancedEffect)(() => {
213
- if (enabled) {
214
- // TODO a scroll reset should not be necessary
215
- rootRef.current.scrollLeft = 0;
216
- rootRef.current.scrollTop = 0;
217
- } else {
218
- renderZoneRef.current.style.transform = `translate3d(0px, 0px, 0px)`;
87
+ React.useEffect(() => {
88
+ const direction = theme.direction === 'ltr' ? 1 : -1;
89
+ const top = (0, _gridRowsMetaSelector.gridRowsMetaSelector)(apiRef.current.state).positions[renderContext.firstRowIndex];
90
+ const left = direction * columnPositions[renderContext.firstColumnIndex] - columnPositions[pinnedColumns.left.length];
91
+ gridRootRef.current?.style.setProperty('--DataGrid-offsetTop', `${top}px`);
92
+ gridRootRef.current?.style.setProperty('--DataGrid-offsetLeft', `${left}px`);
93
+ }, [apiRef, gridRootRef, theme.direction, columnPositions, pinnedColumns.left.length, renderContext]);
94
+ const updateRenderContext = React.useCallback((nextRenderContext, rawRenderContext) => {
95
+ if (areRenderContextsEqual(nextRenderContext, apiRef.current.state.virtualization.renderContext)) {
96
+ return;
219
97
  }
220
- }, [enabled]);
221
- (0, _utils.unstable_useEnhancedEffect)(() => {
222
- setContainerDimensions({
223
- width: rootRef.current.clientWidth,
224
- height: rootRef.current.clientHeight
225
- });
226
- }, [rowsMeta.currentPageTotalHeight]);
227
- const handleResize = React.useCallback(() => {
228
- if (rootRef.current) {
229
- setContainerDimensions({
230
- width: rootRef.current.clientWidth,
231
- height: rootRef.current.clientHeight
98
+ const didRowsIntervalChange = nextRenderContext.firstRowIndex !== previousRowContext.current.firstRowIndex || nextRenderContext.lastRowIndex !== previousRowContext.current.lastRowIndex;
99
+ apiRef.current.setState(state => {
100
+ return (0, _extends2.default)({}, state, {
101
+ virtualization: (0, _extends2.default)({}, state.virtualization, {
102
+ renderContext: nextRenderContext
103
+ })
232
104
  });
233
- }
234
- }, []);
235
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'debouncedResize', handleResize);
236
- const updateRenderZonePosition = React.useCallback(nextRenderContext => {
237
- const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
238
- firstIndex: nextRenderContext.firstRowIndex,
239
- lastIndex: nextRenderContext.lastRowIndex,
240
- minFirstIndex: 0,
241
- maxLastIndex: currentPage.rows.length,
242
- buffer: rootProps.rowBuffer
243
- });
244
- const [initialFirstColumnToRender] = getRenderableIndexes({
245
- firstIndex: nextRenderContext.firstColumnIndex,
246
- lastIndex: nextRenderContext.lastColumnIndex,
247
- minFirstIndex: renderZoneMinColumnIndex,
248
- maxLastIndex: renderZoneMaxColumnIndex,
249
- buffer: rootProps.columnBuffer
250
- });
251
- const firstColumnToRender = (0, _gridColumnsUtils.getFirstNonSpannedColumnToRender)({
252
- firstColumnToRender: initialFirstColumnToRender,
253
- apiRef,
254
- firstRowToRender,
255
- lastRowToRender,
256
- visibleRows: currentPage.rows
257
105
  });
258
- const direction = theme.direction === 'ltr' ? 1 : -1;
259
- const top = (0, _gridRowsMetaSelector.gridRowsMetaSelector)(apiRef.current.state).positions[firstRowToRender];
260
- const left = direction * (0, _gridColumnsSelector.gridColumnPositionsSelector)(apiRef)[firstColumnToRender]; // Call directly the selector because it might be outdated when this method is called
261
- renderZoneRef.current.style.transform = `translate3d(${left}px, ${top}px, 0px)`;
262
- if (typeof onRenderZonePositioning === 'function') {
263
- onRenderZonePositioning({
264
- top,
265
- left
266
- });
106
+
107
+ // The lazy-loading hook is listening to `renderedRowsIntervalChange`,
108
+ // but only does something if the dimensions are also available.
109
+ // So we wait until we have valid dimensions before publishing the first event.
110
+ if (dimensions.isReady && didRowsIntervalChange) {
111
+ previousRowContext.current = nextRenderContext;
112
+ apiRef.current.publishEvent('renderedRowsIntervalChange', nextRenderContext);
267
113
  }
268
- }, [apiRef, currentPage.rows, onRenderZonePositioning, renderZoneMinColumnIndex, renderZoneMaxColumnIndex, rootProps.columnBuffer, rootProps.rowBuffer, theme.direction]);
269
- const getRenderContext = React.useCallback(() => prevRenderContext.current, []);
270
- const setRenderContext = React.useCallback(nextRenderContext => {
271
- if (prevRenderContext.current && areRenderContextsEqual(nextRenderContext, prevRenderContext.current)) {
272
- updateRenderZonePosition(nextRenderContext);
273
- return;
114
+ previousContext.current = rawRenderContext;
115
+ prevTotalWidth.current = dimensions.columnsTotalWidth;
116
+ }, [apiRef, dimensions.isReady, dimensions.columnsTotalWidth]);
117
+ const triggerUpdateRenderContext = () => {
118
+ const inputs = inputsSelector(apiRef, rootProps, enabled, enabledForColumns);
119
+ const [nextRenderContext, rawRenderContext] = computeRenderContext(inputs, scrollPosition);
120
+
121
+ // Since previous render, we have scrolled...
122
+ const topRowsScrolled = Math.abs(rawRenderContext.firstRowIndex - previousContext.current.firstRowIndex);
123
+ const bottomRowsScrolled = Math.abs(rawRenderContext.lastRowIndex - previousContext.current.lastRowIndex);
124
+ const topColumnsScrolled = Math.abs(rawRenderContext.firstColumnIndex - previousContext.current.firstColumnIndex);
125
+ const bottomColumnsScrolled = Math.abs(rawRenderContext.lastColumnIndex - previousContext.current.lastColumnIndex);
126
+ const shouldUpdate = topRowsScrolled >= rootProps.rowThreshold || bottomRowsScrolled >= rootProps.rowThreshold || topColumnsScrolled >= rootProps.columnThreshold || bottomColumnsScrolled >= rootProps.columnThreshold || prevTotalWidth.current !== dimensions.columnsTotalWidth;
127
+ if (!shouldUpdate) {
128
+ return previousContext.current;
274
129
  }
275
- setRenderContextState(nextRenderContext);
276
- updateRenderZonePosition(nextRenderContext);
277
- const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
278
- firstIndex: nextRenderContext.firstRowIndex,
279
- lastIndex: nextRenderContext.lastRowIndex,
280
- minFirstIndex: 0,
281
- maxLastIndex: currentPage.rows.length,
282
- buffer: rootProps.rowBuffer
283
- });
284
- apiRef.current.publishEvent('renderedRowsIntervalChange', {
285
- firstRowToRender,
286
- lastRowToRender
130
+
131
+ // Prevents batching render context changes
132
+ ReactDOM.flushSync(() => {
133
+ updateRenderContext(nextRenderContext, rawRenderContext);
287
134
  });
288
- prevRenderContext.current = nextRenderContext;
289
- }, [apiRef, setRenderContextState, prevRenderContext, currentPage.rows.length, rootProps.rowBuffer, updateRenderZonePosition]);
290
- (0, _utils.unstable_useEnhancedEffect)(() => {
291
- if (containerDimensions.width == null) {
292
- return;
293
- }
294
- const initialRenderContext = computeRenderContext();
295
- setRenderContext(initialRenderContext);
296
- const {
297
- top,
298
- left
299
- } = scrollPosition.current;
300
- const params = {
301
- top,
302
- left,
303
- renderContext: initialRenderContext
304
- };
305
- apiRef.current.publishEvent('scrollPositionChange', params);
306
- }, [apiRef, computeRenderContext, containerDimensions.width, setRenderContext]);
135
+ return nextRenderContext;
136
+ };
137
+ const forceUpdateRenderContext = () => {
138
+ const inputs = inputsSelector(apiRef, rootProps, enabled, enabledForColumns);
139
+ const [nextRenderContext, rawRenderContext] = computeRenderContext(inputs, scrollPosition);
140
+ updateRenderContext(nextRenderContext, rawRenderContext);
141
+ };
307
142
  const handleScroll = (0, _utils.unstable_useEventCallback)(event => {
308
143
  const {
309
144
  scrollTop,
310
145
  scrollLeft
311
146
  } = event.currentTarget;
312
- scrollPosition.current.top = scrollTop;
313
- scrollPosition.current.left = scrollLeft;
147
+ scrollPosition.top = scrollTop;
148
+ scrollPosition.left = scrollLeft;
314
149
 
315
150
  // On iOS and macOS, negative offsets are possible when swiping past the start
316
- if (!prevRenderContext.current || scrollTop < 0) {
151
+ if (scrollTop < 0) {
317
152
  return;
318
153
  }
319
154
  if (theme.direction === 'ltr') {
@@ -326,26 +161,12 @@ const useGridVirtualScroller = props => {
326
161
  return;
327
162
  }
328
163
  }
329
-
330
- // When virtualization is disabled, the context never changes during scroll
331
- const nextRenderContext = enabled ? computeRenderContext() : prevRenderContext.current;
332
- const topRowsScrolledSincePreviousRender = Math.abs(nextRenderContext.firstRowIndex - prevRenderContext.current.firstRowIndex);
333
- const bottomRowsScrolledSincePreviousRender = Math.abs(nextRenderContext.lastRowIndex - prevRenderContext.current.lastRowIndex);
334
- const topColumnsScrolledSincePreviousRender = Math.abs(nextRenderContext.firstColumnIndex - prevRenderContext.current.firstColumnIndex);
335
- const bottomColumnsScrolledSincePreviousRender = Math.abs(nextRenderContext.lastColumnIndex - prevRenderContext.current.lastColumnIndex);
336
- const shouldSetState = topRowsScrolledSincePreviousRender >= rootProps.rowThreshold || bottomRowsScrolledSincePreviousRender >= rootProps.rowThreshold || topColumnsScrolledSincePreviousRender >= rootProps.columnThreshold || bottomColumnsScrolledSincePreviousRender >= rootProps.columnThreshold || prevTotalWidth.current !== columnsTotalWidth;
164
+ const nextRenderContext = triggerUpdateRenderContext();
337
165
  apiRef.current.publishEvent('scrollPositionChange', {
338
166
  top: scrollTop,
339
167
  left: scrollLeft,
340
- renderContext: shouldSetState ? nextRenderContext : prevRenderContext.current
341
- }, event);
342
- if (shouldSetState) {
343
- // Prevents batching render context changes
344
- ReactDOM.flushSync(() => {
345
- setRenderContext(nextRenderContext);
346
- });
347
- prevTotalWidth.current = columnsTotalWidth;
348
- }
168
+ renderContext: nextRenderContext
169
+ });
349
170
  });
350
171
  const handleWheel = (0, _utils.unstable_useEventCallback)(event => {
351
172
  apiRef.current.publishEvent('virtualScrollerWheel', {}, event);
@@ -353,128 +174,81 @@ const useGridVirtualScroller = props => {
353
174
  const handleTouchMove = (0, _utils.unstable_useEventCallback)(event => {
354
175
  apiRef.current.publishEvent('virtualScrollerTouchMove', {}, event);
355
176
  });
356
- const indexOfRowWithFocusedCell = React.useMemo(() => {
357
- if (cellFocus !== null) {
358
- return currentPage.rows.findIndex(row => row.id === cellFocus.id);
177
+ const minFirstColumn = pinnedColumns.left.length;
178
+ const maxLastColumn = visibleColumns.length - pinnedColumns.right.length;
179
+ const getRows = (params = {}) => {
180
+ const isLastSection = !hasBottomPinnedRows && params.position === undefined || hasBottomPinnedRows && params.position === 'bottom';
181
+ const isPinnedSection = params.position !== undefined;
182
+ let rowIndexOffset;
183
+ // FIXME: Why is the switch check exhaustiveness not validated with typescript-eslint?
184
+ // eslint-disable-next-line default-case
185
+ switch (params.position) {
186
+ case 'top':
187
+ rowIndexOffset = 0;
188
+ break;
189
+ case 'bottom':
190
+ rowIndexOffset = pinnedRows.top.length + currentPage.rows.length;
191
+ break;
192
+ case undefined:
193
+ rowIndexOffset = pinnedRows.top.length;
194
+ break;
359
195
  }
360
- return -1;
361
- }, [cellFocus, currentPage.rows]);
362
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'rowMouseOver', (params, event) => {
363
- if (event.currentTarget.contains(event.relatedTarget)) {
364
- return;
365
- }
366
- setHoveredRowId(params.id ?? null);
367
- });
368
- (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'rowMouseOut', (params, event) => {
369
- if (event.currentTarget.contains(event.relatedTarget)) {
370
- return;
371
- }
372
- setHoveredRowId(null);
373
- });
374
- const getRows = (params = {
375
- renderContext
376
- }) => {
377
- const {
378
- onRowRender,
379
- renderContext: nextRenderContext,
380
- minFirstColumn = renderZoneMinColumnIndex,
381
- maxLastColumn = renderZoneMaxColumnIndex,
382
- availableSpace = containerDimensions.width,
383
- rowIndexOffset = 0,
384
- position = 'center'
385
- } = params;
386
- if (!nextRenderContext || availableSpace == null) {
387
- return null;
388
- }
389
- const rowBuffer = enabled ? rootProps.rowBuffer : 0;
390
- const columnBuffer = enabled ? rootProps.columnBuffer : 0;
391
- const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
392
- firstIndex: nextRenderContext.firstRowIndex,
393
- lastIndex: nextRenderContext.lastRowIndex,
394
- minFirstIndex: 0,
395
- maxLastIndex: currentPage.rows.length,
396
- buffer: rowBuffer
397
- });
398
- const renderedRows = [];
399
- if (params.rows) {
400
- params.rows.forEach(row => {
401
- renderedRows.push(row);
402
- apiRef.current.calculateColSpan({
403
- rowId: row.id,
404
- minFirstColumn,
405
- maxLastColumn,
406
- columns: visibleColumns
407
- });
408
- });
409
- } else {
410
- if (!currentPage.range) {
411
- return null;
412
- }
413
- for (let i = firstRowToRender; i < lastRowToRender; i += 1) {
414
- const row = currentPage.rows[i];
415
- renderedRows.push(row);
416
- apiRef.current.calculateColSpan({
417
- rowId: row.id,
418
- minFirstColumn,
419
- maxLastColumn,
420
- columns: visibleColumns
421
- });
422
- }
196
+ const firstRowToRender = renderContext.firstRowIndex;
197
+ const lastRowToRender = renderContext.lastRowIndex;
198
+ const firstColumnToRender = renderContext.firstColumnIndex;
199
+ const lastColumnToRender = renderContext.lastColumnIndex;
200
+ if (!params.rows && !currentPage.range) {
201
+ return [];
423
202
  }
203
+ const renderedRows = params.rows ?? currentPage.rows.slice(firstRowToRender, lastRowToRender);
204
+
424
205
  // If the selected row is not within the current range of rows being displayed,
425
206
  // we need to render it at either the top or bottom of the rows,
426
207
  // depending on whether it is above or below the range.
427
-
428
208
  let isRowWithFocusedCellNotInRange = false;
429
- if (indexOfRowWithFocusedCell > -1) {
209
+ if (!isPinnedSection && indexOfRowWithFocusedCell > -1 && (firstRowToRender > indexOfRowWithFocusedCell || lastRowToRender < indexOfRowWithFocusedCell)) {
210
+ isRowWithFocusedCellNotInRange = true;
430
211
  const rowWithFocusedCell = currentPage.rows[indexOfRowWithFocusedCell];
431
- if (firstRowToRender > indexOfRowWithFocusedCell || lastRowToRender < indexOfRowWithFocusedCell) {
432
- isRowWithFocusedCellNotInRange = true;
433
- if (indexOfRowWithFocusedCell > firstRowToRender) {
434
- renderedRows.push(rowWithFocusedCell);
435
- } else {
436
- renderedRows.unshift(rowWithFocusedCell);
437
- }
438
- apiRef.current.calculateColSpan({
439
- rowId: rowWithFocusedCell.id,
440
- minFirstColumn,
441
- maxLastColumn,
442
- columns: visibleColumns
443
- });
212
+ if (indexOfRowWithFocusedCell > firstRowToRender) {
213
+ renderedRows.push(rowWithFocusedCell);
214
+ } else {
215
+ renderedRows.unshift(rowWithFocusedCell);
444
216
  }
445
217
  }
446
- const [initialFirstColumnToRender, lastColumnToRender] = getRenderableIndexes({
447
- firstIndex: nextRenderContext.firstColumnIndex,
448
- lastIndex: nextRenderContext.lastColumnIndex,
449
- minFirstIndex: minFirstColumn,
450
- maxLastIndex: maxLastColumn,
451
- buffer: columnBuffer
452
- });
453
- const firstColumnToRender = (0, _gridColumnsUtils.getFirstNonSpannedColumnToRender)({
454
- firstColumnToRender: initialFirstColumnToRender,
455
- apiRef,
456
- firstRowToRender,
457
- lastRowToRender,
458
- visibleRows: currentPage.rows
459
- });
460
218
  let isColumnWihFocusedCellNotInRange = false;
461
- if (firstColumnToRender > indexOfColumnWithFocusedCell || lastColumnToRender < indexOfColumnWithFocusedCell) {
219
+ if (!isPinnedSection && (firstColumnToRender > indexOfColumnWithFocusedCell || lastColumnToRender < indexOfColumnWithFocusedCell)) {
462
220
  isColumnWihFocusedCellNotInRange = true;
463
221
  }
464
222
  const {
465
223
  focusedCellColumnIndexNotInRange,
466
224
  renderedColumns
467
- } = getRenderedColumnsRef.current(visibleColumns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, isColumnWihFocusedCellNotInRange ? indexOfColumnWithFocusedCell : -1);
468
- const _ref = rootProps.slotProps?.row || {},
469
- {
470
- style: rootRowStyle
471
- } = _ref,
472
- rootRowProps = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
473
- const invalidatesCachedRowStyle = prevGetRowProps.current !== getRowProps || prevRootRowStyle.current !== rootRowStyle;
474
- if (invalidatesCachedRowStyle) {
475
- rowStyleCache.current = Object.create(null);
476
- }
225
+ } = getRenderedColumns(visibleColumns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, isColumnWihFocusedCellNotInRange ? indexOfColumnWithFocusedCell : -1);
226
+ renderedRows.forEach(row => {
227
+ apiRef.current.calculateColSpan({
228
+ rowId: row.id,
229
+ minFirstColumn,
230
+ maxLastColumn,
231
+ columns: visibleColumns
232
+ });
233
+ if (pinnedColumns.left.length > 0) {
234
+ apiRef.current.calculateColSpan({
235
+ rowId: row.id,
236
+ minFirstColumn: 0,
237
+ maxLastColumn: pinnedColumns.left.length,
238
+ columns: visibleColumns
239
+ });
240
+ }
241
+ if (pinnedColumns.right.length > 0) {
242
+ apiRef.current.calculateColSpan({
243
+ rowId: row.id,
244
+ minFirstColumn: visibleColumns.length - pinnedColumns.right.length,
245
+ maxLastColumn: visibleColumns.length,
246
+ columns: visibleColumns
247
+ });
248
+ }
249
+ });
477
250
  const rows = [];
251
+ const rowProps = rootProps.slotProps?.row;
478
252
  let isRowWithFocusedCellRendered = false;
479
253
  for (let i = 0; i < renderedRows.length; i += 1) {
480
254
  const {
@@ -482,7 +256,6 @@ const useGridVirtualScroller = props => {
482
256
  model
483
257
  } = renderedRows[i];
484
258
  const isRowNotVisible = isRowWithFocusedCellNotInRange && cellFocus.id === id;
485
- const lastVisibleRowIndex = isRowWithFocusedCellNotInRange ? firstRowToRender + i === currentPage.rows.length : firstRowToRender + i === currentPage.rows.length - 1;
486
259
  const baseRowHeight = !apiRef.current.rowHasAutoHeight(id) ? apiRef.current.unstable_getRowHeight(id) : 'auto';
487
260
  let isSelected;
488
261
  if (selectedRowsLookup[id] == null) {
@@ -490,8 +263,21 @@ const useGridVirtualScroller = props => {
490
263
  } else {
491
264
  isSelected = apiRef.current.isRowSelectable(id);
492
265
  }
493
- if (onRowRender) {
494
- onRowRender(id);
266
+ let isFirstVisible = false;
267
+ if (params.position === undefined) {
268
+ isFirstVisible = i === 0;
269
+ }
270
+ let isLastVisible = false;
271
+ if (isLastSection) {
272
+ if (!isPinnedSection) {
273
+ const lastIndex = currentPage.rows.length - 1;
274
+ const isLastVisibleRowIndex = isRowWithFocusedCellNotInRange ? firstRowToRender + i === lastIndex + 1 : firstRowToRender + i === lastIndex;
275
+ if (isLastVisibleRowIndex) {
276
+ isLastVisible = true;
277
+ }
278
+ } else {
279
+ isLastVisible = i === renderedRows.length - 1;
280
+ }
495
281
  }
496
282
  const focusedCell = cellFocus !== null && cellFocus.id === id ? cellFocus.field : null;
497
283
  const columnWithFocusedCellNotInRange = focusedCellColumnIndexNotInRange !== undefined && visibleColumns[focusedCellColumnIndexNotInRange];
@@ -501,15 +287,6 @@ const useGridVirtualScroller = props => {
501
287
  const cellParams = apiRef.current.getCellParams(id, cellTabIndex.field);
502
288
  tabbableCell = cellParams.cellMode === 'view' ? cellTabIndex.field : null;
503
289
  }
504
- const _ref2 = typeof getRowProps === 'function' && getRowProps(id, model) || {},
505
- {
506
- style: rowStyle
507
- } = _ref2,
508
- rowProps = (0, _objectWithoutPropertiesLoose2.default)(_ref2, _excluded2);
509
- if (!rowStyleCache.current[id]) {
510
- const style = (0, _extends2.default)({}, rowStyle, rootRowStyle);
511
- rowStyleCache.current[id] = style;
512
- }
513
290
  let index = rowIndexOffset + (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i;
514
291
  if (isRowWithFocusedCellNotInRange && cellFocus?.id === id) {
515
292
  index = indexOfRowWithFocusedCell;
@@ -520,88 +297,314 @@ const useGridVirtualScroller = props => {
520
297
  rows.push( /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.row, (0, _extends2.default)({
521
298
  row: model,
522
299
  rowId: id,
523
- focusedCellColumnIndexNotInRange: focusedCellColumnIndexNotInRange,
524
- isNotVisible: isRowNotVisible,
300
+ index: index,
525
301
  rowHeight: baseRowHeight,
526
302
  focusedCell: focusedCell,
527
303
  tabbableCell: tabbableCell,
304
+ focusedCellColumnIndexNotInRange: focusedCellColumnIndexNotInRange,
528
305
  renderedColumns: renderedColumnsWithFocusedCell,
529
306
  visibleColumns: visibleColumns,
307
+ pinnedColumns: pinnedColumns,
530
308
  firstColumnToRender: firstColumnToRender,
531
309
  lastColumnToRender: lastColumnToRender,
532
310
  selected: isSelected,
533
- index: index,
534
- containerWidth: availableSpace,
535
- isLastVisible: lastVisibleRowIndex,
536
- position: position
537
- }, rowProps, rootRowProps, {
538
- hovered: hoveredRowId === id,
539
- style: rowStyleCache.current[id]
540
- }), id));
311
+ dimensions: dimensions,
312
+ isFirstVisible: isFirstVisible,
313
+ isLastVisible: isLastVisible,
314
+ isNotVisible: isRowNotVisible
315
+ }, rowProps), id));
316
+ const panel = panels.get(id);
317
+ if (panel) {
318
+ rows.push(panel);
319
+ }
541
320
  }
542
- prevGetRowProps.current = getRowProps;
543
- prevRootRowStyle.current = rootRowStyle;
544
321
  return rows;
545
322
  };
546
- const needsHorizontalScrollbar = containerDimensions.width && columnsTotalWidth >= containerDimensions.width;
323
+ const needsHorizontalScrollbar = outerSize.width && columnsTotalWidth >= outerSize.width;
324
+ const scrollerStyle = React.useMemo(() => ({
325
+ overflowX: !needsHorizontalScrollbar ? 'hidden' : undefined,
326
+ overflowY: rootProps.autoHeight ? 'hidden' : undefined
327
+ }), [needsHorizontalScrollbar, rootProps.autoHeight]);
547
328
  const contentSize = React.useMemo(() => {
548
329
  // In cases where the columns exceed the available width,
549
330
  // the horizontal scrollbar should be shown even when there're no rows.
550
331
  // Keeping 1px as minimum height ensures that the scrollbar will visible if necessary.
551
- const height = Math.max(rowsMeta.currentPageTotalHeight, 1);
552
- let shouldExtendContent = false;
553
- if (rootRef?.current && height <= rootRef?.current.clientHeight) {
554
- shouldExtendContent = true;
555
- }
332
+ const height = Math.max(contentHeight, 1);
556
333
  const size = {
557
334
  width: needsHorizontalScrollbar ? columnsTotalWidth : 'auto',
558
- height,
559
- minHeight: shouldExtendContent ? '100%' : 'auto'
335
+ height
560
336
  };
561
- if (rootProps.autoHeight && currentPage.rows.length === 0) {
562
- size.height = (0, _gridRowsUtils.getMinimalContentHeight)(apiRef, rootProps.rowHeight); // Give room to show the overlay when there no rows.
337
+ if (rootProps.autoHeight) {
338
+ if (currentPage.rows.length === 0) {
339
+ size.height = (0, _gridRowsUtils.getMinimalContentHeight)(apiRef); // Give room to show the overlay when there no rows.
340
+ } else {
341
+ size.height = contentHeight;
342
+ }
563
343
  }
564
344
  return size;
565
- }, [apiRef, rootRef, columnsTotalWidth, rowsMeta.currentPageTotalHeight, needsHorizontalScrollbar, rootProps.autoHeight, rootProps.rowHeight, currentPage.rows.length]);
345
+ }, [apiRef, columnsTotalWidth, contentHeight, needsHorizontalScrollbar, rootProps.autoHeight, currentPage.rows.length]);
566
346
  React.useEffect(() => {
567
347
  apiRef.current.publishEvent('virtualScrollerContentSizeChange');
568
348
  }, [apiRef, contentSize]);
569
- const rootStyle = React.useMemo(() => {
570
- const style = {};
571
- if (!needsHorizontalScrollbar) {
572
- style.overflowX = 'hidden';
573
- }
574
- if (rootProps.autoHeight) {
575
- style.overflowY = 'hidden';
349
+ (0, _utils.unstable_useEnhancedEffect)(() => {
350
+ // FIXME: Is this really necessary?
351
+ apiRef.current.resize();
352
+ }, [apiRef, rowsMeta.currentPageTotalHeight]);
353
+ (0, _utils.unstable_useEnhancedEffect)(() => {
354
+ if (enabled) {
355
+ // TODO a scroll reset should not be necessary
356
+ scrollerRef.current.scrollLeft = 0;
357
+ scrollerRef.current.scrollTop = 0;
358
+ } else {
359
+ gridRootRef.current?.style.setProperty('--DataGrid-offsetTop', '0px');
360
+ gridRootRef.current?.style.setProperty('--DataGrid-offsetLeft', '0px');
576
361
  }
577
- return style;
578
- }, [needsHorizontalScrollbar, rootProps.autoHeight]);
362
+ }, [enabled, gridRootRef, scrollerRef]);
363
+ (0, _useRunOnce.useRunOnce)(outerSize.width !== 0, () => {
364
+ const inputs = inputsSelector(apiRef, rootProps, enabled, enabledForColumns);
365
+ const [initialRenderContext, rawRenderContext] = computeRenderContext(inputs, scrollPosition);
366
+ updateRenderContext(initialRenderContext, rawRenderContext);
367
+ apiRef.current.publishEvent('scrollPositionChange', {
368
+ top: scrollPosition.top,
369
+ left: scrollPosition.left,
370
+ renderContext: initialRenderContext
371
+ });
372
+ });
579
373
  apiRef.current.register('private', {
580
- getRenderContext
374
+ updateRenderContext: forceUpdateRenderContext
581
375
  });
582
376
  return {
583
377
  renderContext,
584
- updateRenderZonePosition,
378
+ setPanels,
585
379
  getRows,
586
- getRootProps: (inputProps = {}) => (0, _extends2.default)({
587
- ref: handleRef,
380
+ getContainerProps: () => ({
381
+ ref: mainRef
382
+ }),
383
+ getScrollerProps: () => ({
384
+ ref: scrollerRef,
385
+ tabIndex: -1,
588
386
  onScroll: handleScroll,
589
387
  onWheel: handleWheel,
590
- onTouchMove: handleTouchMove
591
- }, inputProps, {
592
- style: inputProps.style ? (0, _extends2.default)({}, inputProps.style, rootStyle) : rootStyle,
388
+ onTouchMove: handleTouchMove,
389
+ style: scrollerStyle,
593
390
  role: 'presentation'
594
391
  }),
595
- getContentProps: ({
596
- style
597
- } = {}) => ({
598
- style: style ? (0, _extends2.default)({}, style, contentSize) : contentSize,
392
+ getContentProps: () => ({
393
+ style: contentSize,
599
394
  role: 'presentation'
600
395
  }),
601
396
  getRenderZoneProps: () => ({
602
397
  ref: renderZoneRef,
603
398
  role: 'rowgroup'
399
+ }),
400
+ getScrollbarVerticalProps: () => ({
401
+ ref: scrollbarVerticalRef,
402
+ role: 'presentation'
403
+ }),
404
+ getScrollbarHorizontalProps: () => ({
405
+ ref: scrollbarHorizontalRef,
406
+ role: 'presentation'
604
407
  })
605
408
  };
606
409
  };
607
- exports.useGridVirtualScroller = useGridVirtualScroller;
410
+ exports.useGridVirtualScroller = useGridVirtualScroller;
411
+ function createGetRenderedColumns() {
412
+ return (0, _reselect.defaultMemoize)((columns, firstColumnToRender, lastColumnToRender, minFirstColumn, maxLastColumn, indexOfColumnWithFocusedCell) => {
413
+ // If the selected column is not within the current range of columns being displayed,
414
+ // we need to render it at either the left or right of the columns,
415
+ // depending on whether it is above or below the range.
416
+ let focusedCellColumnIndexNotInRange;
417
+ const renderedColumns = columns.slice(firstColumnToRender, lastColumnToRender);
418
+ if (indexOfColumnWithFocusedCell > -1) {
419
+ // check if it is not on the left pinned column.
420
+ if (firstColumnToRender > indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell >= minFirstColumn) {
421
+ focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
422
+ }
423
+ // check if it is not on the right pinned column.
424
+ else if (lastColumnToRender < indexOfColumnWithFocusedCell && indexOfColumnWithFocusedCell < maxLastColumn) {
425
+ focusedCellColumnIndexNotInRange = indexOfColumnWithFocusedCell;
426
+ }
427
+ }
428
+ return {
429
+ focusedCellColumnIndexNotInRange,
430
+ renderedColumns
431
+ };
432
+ });
433
+ }
434
+ function inputsSelector(apiRef, rootProps, enabled, enabledForColumns) {
435
+ const dimensions = (0, _gridDimensionsSelectors.gridDimensionsSelector)(apiRef.current.state);
436
+ const currentPage = (0, _useGridVisibleRows.getVisibleRows)(apiRef, rootProps);
437
+ return {
438
+ enabled,
439
+ enabledForColumns,
440
+ apiRef,
441
+ autoHeight: rootProps.autoHeight,
442
+ rowBuffer: rootProps.rowBuffer,
443
+ columnBuffer: rootProps.columnBuffer,
444
+ leftPinnedWidth: dimensions.leftPinnedWidth,
445
+ columnsTotalWidth: dimensions.columnsTotalWidth,
446
+ viewportInnerWidth: dimensions.viewportInnerSize.width,
447
+ viewportInnerHeight: dimensions.viewportInnerSize.height,
448
+ rowsMeta: (0, _gridRowsMetaSelector.gridRowsMetaSelector)(apiRef.current.state),
449
+ columnPositions: (0, _gridColumnsSelector.gridColumnPositionsSelector)(apiRef),
450
+ rows: currentPage.rows,
451
+ range: currentPage.range,
452
+ pinnedColumns: (0, _gridColumnsSelector.gridVisiblePinnedColumnDefinitionsSelector)(apiRef),
453
+ visibleColumns: (0, _gridColumnsSelector.gridVisibleColumnDefinitionsSelector)(apiRef)
454
+ };
455
+ }
456
+ function computeRenderContext(inputs, scrollPosition) {
457
+ let renderContext;
458
+ if (!inputs.enabled) {
459
+ renderContext = {
460
+ firstRowIndex: 0,
461
+ lastRowIndex: inputs.rows.length,
462
+ firstColumnIndex: 0,
463
+ lastColumnIndex: inputs.visibleColumns.length
464
+ };
465
+ } else {
466
+ const {
467
+ top,
468
+ left
469
+ } = scrollPosition;
470
+ const realLeft = Math.abs(left) + inputs.leftPinnedWidth;
471
+
472
+ // Clamp the value because the search may return an index out of bounds.
473
+ // In the last index, this is not needed because Array.slice doesn't include it.
474
+ const firstRowIndex = Math.min(getNearestIndexToRender(inputs, top), inputs.rowsMeta.positions.length - 1);
475
+ const lastRowIndex = inputs.autoHeight ? firstRowIndex + inputs.rows.length : getNearestIndexToRender(inputs, top + inputs.viewportInnerHeight);
476
+ let firstColumnIndex = 0;
477
+ let lastColumnIndex = inputs.columnPositions.length;
478
+ if (inputs.enabledForColumns) {
479
+ let hasRowWithAutoHeight = false;
480
+ const [firstRowToRender, lastRowToRender] = getIndexesToRender({
481
+ firstIndex: firstRowIndex,
482
+ lastIndex: lastRowIndex,
483
+ minFirstIndex: 0,
484
+ maxLastIndex: inputs.rows.length,
485
+ buffer: inputs.rowBuffer
486
+ });
487
+ for (let i = firstRowToRender; i < lastRowToRender && !hasRowWithAutoHeight; i += 1) {
488
+ const row = inputs.rows[i];
489
+ hasRowWithAutoHeight = inputs.apiRef.current.rowHasAutoHeight(row.id);
490
+ }
491
+ if (!hasRowWithAutoHeight) {
492
+ firstColumnIndex = binarySearch(realLeft, inputs.columnPositions, {
493
+ atStart: true,
494
+ lastPosition: inputs.columnsTotalWidth
495
+ });
496
+ lastColumnIndex = binarySearch(realLeft + inputs.viewportInnerWidth, inputs.columnPositions);
497
+ }
498
+ }
499
+ renderContext = {
500
+ firstRowIndex,
501
+ lastRowIndex,
502
+ firstColumnIndex,
503
+ lastColumnIndex
504
+ };
505
+ }
506
+ const actualRenderContext = deriveRenderContext(inputs.apiRef, inputs.rowBuffer, inputs.columnBuffer, inputs.rows, inputs.pinnedColumns, inputs.visibleColumns, renderContext);
507
+ return [actualRenderContext, renderContext];
508
+ }
509
+ function getNearestIndexToRender(inputs, offset) {
510
+ const lastMeasuredIndexRelativeToAllRows = inputs.apiRef.current.getLastMeasuredRowIndex();
511
+ let allRowsMeasured = lastMeasuredIndexRelativeToAllRows === Infinity;
512
+ if (inputs.range?.lastRowIndex && !allRowsMeasured) {
513
+ // Check if all rows in this page are already measured
514
+ allRowsMeasured = lastMeasuredIndexRelativeToAllRows >= inputs.range.lastRowIndex;
515
+ }
516
+ const lastMeasuredIndexRelativeToCurrentPage = (0, _utils2.clamp)(lastMeasuredIndexRelativeToAllRows - (inputs.range?.firstRowIndex || 0), 0, inputs.rowsMeta.positions.length);
517
+ if (allRowsMeasured || inputs.rowsMeta.positions[lastMeasuredIndexRelativeToCurrentPage] >= offset) {
518
+ // If all rows were measured (when no row has "auto" as height) or all rows before the offset
519
+ // were measured, then use a binary search because it's faster.
520
+ return binarySearch(offset, inputs.rowsMeta.positions);
521
+ }
522
+
523
+ // Otherwise, use an exponential search.
524
+ // If rows have "auto" as height, their positions will be based on estimated heights.
525
+ // In this case, we can skip several steps until we find a position higher than the offset.
526
+ // Inspired by https://github.com/bvaughn/react-virtualized/blob/master/source/Grid/utils/CellSizeAndPositionManager.js
527
+ return exponentialSearch(offset, inputs.rowsMeta.positions, lastMeasuredIndexRelativeToCurrentPage);
528
+ }
529
+
530
+ /**
531
+ * Accepts as input a raw render context (the area visible in the viewport) and adds
532
+ * computes the actual render context based on pinned elements, buffer dimensions and
533
+ * spanning.
534
+ */
535
+ function deriveRenderContext(apiRef, rowBuffer, columnBuffer, rows, pinnedColumns, visibleColumns, nextRenderContext) {
536
+ const [firstRowToRender, lastRowToRender] = getIndexesToRender({
537
+ firstIndex: nextRenderContext.firstRowIndex,
538
+ lastIndex: nextRenderContext.lastRowIndex,
539
+ minFirstIndex: 0,
540
+ maxLastIndex: rows.length,
541
+ buffer: rowBuffer
542
+ });
543
+ const [initialFirstColumnToRender, lastColumnToRender] = getIndexesToRender({
544
+ firstIndex: nextRenderContext.firstColumnIndex,
545
+ lastIndex: nextRenderContext.lastColumnIndex,
546
+ minFirstIndex: pinnedColumns.left.length,
547
+ maxLastIndex: visibleColumns.length - pinnedColumns.right.length,
548
+ buffer: columnBuffer
549
+ });
550
+ const firstColumnToRender = (0, _gridColumnsUtils.getFirstNonSpannedColumnToRender)({
551
+ firstColumnToRender: initialFirstColumnToRender,
552
+ apiRef,
553
+ firstRowToRender,
554
+ lastRowToRender,
555
+ visibleRows: rows
556
+ });
557
+ return {
558
+ firstRowIndex: firstRowToRender,
559
+ lastRowIndex: lastRowToRender,
560
+ firstColumnIndex: firstColumnToRender,
561
+ lastColumnIndex: lastColumnToRender
562
+ };
563
+ }
564
+ /**
565
+ * Use binary search to avoid looping through all possible positions.
566
+ * The `options.atStart` provides the possibility to match for the first element that
567
+ * intersects the screen, even if said element's start position is before `offset`. In
568
+ * other words, we search for `offset + width`.
569
+ */
570
+ function binarySearch(offset, positions, options = undefined, sliceStart = 0, sliceEnd = positions.length) {
571
+ if (positions.length <= 0) {
572
+ return -1;
573
+ }
574
+ if (sliceStart >= sliceEnd) {
575
+ return sliceStart;
576
+ }
577
+ const pivot = sliceStart + Math.floor((sliceEnd - sliceStart) / 2);
578
+ const position = positions[pivot];
579
+ let isBefore;
580
+ if (options?.atStart) {
581
+ const width = (pivot === positions.length - 1 ? options.lastPosition : positions[pivot + 1]) - position;
582
+ isBefore = offset - width < position;
583
+ } else {
584
+ isBefore = offset <= position;
585
+ }
586
+ return isBefore ? binarySearch(offset, positions, options, sliceStart, pivot) : binarySearch(offset, positions, options, pivot + 1, sliceEnd);
587
+ }
588
+ function exponentialSearch(offset, positions, index) {
589
+ let interval = 1;
590
+ while (index < positions.length && Math.abs(positions[index]) < offset) {
591
+ index += interval;
592
+ interval *= 2;
593
+ }
594
+ return binarySearch(offset, positions, undefined, Math.floor(index / 2), Math.min(index, positions.length));
595
+ }
596
+ function getIndexesToRender({
597
+ firstIndex,
598
+ lastIndex,
599
+ buffer,
600
+ minFirstIndex,
601
+ maxLastIndex
602
+ }) {
603
+ return [(0, _utils2.clamp)(firstIndex - buffer, minFirstIndex, maxLastIndex), (0, _utils2.clamp)(lastIndex + buffer, minFirstIndex, maxLastIndex)];
604
+ }
605
+ function areRenderContextsEqual(context1, context2) {
606
+ if (context1 === context2) {
607
+ return true;
608
+ }
609
+ return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
610
+ }