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