From a4fe1211aeeb096c56170852127bda0633ef59a7 Mon Sep 17 00:00:00 2001 From: Rajat Date: Wed, 18 Dec 2024 18:58:31 +0530 Subject: [PATCH] [DataGrid] Fix autosizing with virtualized columns (#15116) Co-authored-by: Andrew Cherniavskii --- docs/pages/x/api/data-grid/data-grid-premium.json | 2 +- docs/pages/x/api/data-grid/data-grid-pro.json | 2 +- docs/pages/x/api/data-grid/data-grid.json | 2 +- .../src/DataGridPremium/DataGridPremium.tsx | 1 + .../src/DataGridPro/DataGridPro.tsx | 1 + packages/x-data-grid/src/DataGrid/DataGrid.tsx | 1 + packages/x-data-grid/src/components/GridRow.tsx | 14 ++++++++++++-- .../columnHeaders/useGridColumnHeaders.tsx | 13 ++++++++++--- .../features/columnResize/gridColumnResizeApi.ts | 6 ++++++ .../features/columnResize/useGridColumnResize.tsx | 15 +++++++++++---- 10 files changed, 45 insertions(+), 12 deletions(-) diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 7dd94db6896f..d841582c9886 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -27,7 +27,7 @@ "autosizeOptions": { "type": { "name": "shape", - "description": "{ columns?: Array<string>, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" + "description": "{ columns?: Array<string>, disableColumnVirtualization?: bool, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" } }, "cellModesModel": { "type": { "name": "object" } }, diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json index a0597d65b263..2682a7d8d130 100644 --- a/docs/pages/x/api/data-grid/data-grid-pro.json +++ b/docs/pages/x/api/data-grid/data-grid-pro.json @@ -18,7 +18,7 @@ "autosizeOptions": { "type": { "name": "shape", - "description": "{ columns?: Array<string>, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" + "description": "{ columns?: Array<string>, disableColumnVirtualization?: bool, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" } }, "cellModesModel": { "type": { "name": "object" } }, diff --git a/docs/pages/x/api/data-grid/data-grid.json b/docs/pages/x/api/data-grid/data-grid.json index 314e9a36b0d3..eb747838952c 100644 --- a/docs/pages/x/api/data-grid/data-grid.json +++ b/docs/pages/x/api/data-grid/data-grid.json @@ -18,7 +18,7 @@ "autosizeOptions": { "type": { "name": "shape", - "description": "{ columns?: Array<string>, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" + "description": "{ columns?: Array<string>, disableColumnVirtualization?: bool, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }" } }, "cellModesModel": { "type": { "name": "object" } }, diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index a5608e3d6b2e..3fbd5323b4a8 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -133,6 +133,7 @@ DataGridPremiumRaw.propTypes = { */ autosizeOptions: PropTypes.shape({ columns: PropTypes.arrayOf(PropTypes.string), + disableColumnVirtualization: PropTypes.bool, expand: PropTypes.bool, includeHeaders: PropTypes.bool, includeOutliers: PropTypes.bool, diff --git a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx index 06245c8f526b..7d0107cbbe1f 100644 --- a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx +++ b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx @@ -120,6 +120,7 @@ DataGridProRaw.propTypes = { */ autosizeOptions: PropTypes.shape({ columns: PropTypes.arrayOf(PropTypes.string), + disableColumnVirtualization: PropTypes.bool, expand: PropTypes.bool, includeHeaders: PropTypes.bool, includeOutliers: PropTypes.bool, diff --git a/packages/x-data-grid/src/DataGrid/DataGrid.tsx b/packages/x-data-grid/src/DataGrid/DataGrid.tsx index 0e20490cff65..c892565ea160 100644 --- a/packages/x-data-grid/src/DataGrid/DataGrid.tsx +++ b/packages/x-data-grid/src/DataGrid/DataGrid.tsx @@ -130,6 +130,7 @@ DataGridRaw.propTypes = { */ autosizeOptions: PropTypes.shape({ columns: PropTypes.arrayOf(PropTypes.string), + disableColumnVirtualization: PropTypes.bool, expand: PropTypes.bool, includeHeaders: PropTypes.bool, includeOutliers: PropTypes.bool, diff --git a/packages/x-data-grid/src/components/GridRow.tsx b/packages/x-data-grid/src/components/GridRow.tsx index a80e112aefb8..8407642c37f6 100644 --- a/packages/x-data-grid/src/components/GridRow.tsx +++ b/packages/x-data-grid/src/components/GridRow.tsx @@ -29,6 +29,7 @@ import { GridScrollbarFillerCell as ScrollbarFiller } from './GridScrollbarFille import { getPinnedCellOffset } from '../internals/utils/getPinnedCellOffset'; import { useGridConfiguration } from '../hooks/utils/useGridConfiguration'; import { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext'; +import { gridVirtualizationColumnEnabledSelector } from '../hooks'; export interface GridRowProps extends React.HTMLAttributes { row: GridRowModel; @@ -133,7 +134,7 @@ const GridRow = React.forwardRef(function GridRow( const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width; const editing = apiRef.current.getRowMode(rowId) === GridRowModes.Edit; const editable = rootProps.editMode === GridEditModes.Row; - + const hasColumnVirtualization = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector); const hasFocusCell = focusedColumnIndex !== undefined; const hasVirtualFocusCellLeft = hasFocusCell && @@ -418,8 +419,17 @@ const GridRow = React.forwardRef(function GridRow( ), ); } + let firstColumnIndex; + let lastColumnIndex; + if (!rootProps.disableVirtualization && !hasColumnVirtualization) { + firstColumnIndex = 0; + lastColumnIndex = visibleColumns.length; + } else { + firstColumnIndex = renderContext.firstColumnIndex; + lastColumnIndex = renderContext.lastColumnIndex; + } - for (let i = renderContext.firstColumnIndex; i < renderContext.lastColumnIndex; i += 1) { + for (let i = firstColumnIndex; i < lastColumnIndex; i += 1) { const column = visibleColumns[i]; const indexInSection = i - pinnedColumns.left.length; diff --git a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx index 2e9804d6c51f..aae228e6aeb4 100644 --- a/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx +++ b/packages/x-data-grid/src/hooks/features/columnHeaders/useGridColumnHeaders.tsx @@ -101,7 +101,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { const isRtl = useRtl(); const rootProps = useGridRootProps(); const dimensions = useGridSelector(apiRef, gridDimensionsSelector); - const hasVirtualization = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector); + const hasColumnVirtualization = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector); const columnGroupsModel = useGridSelector(apiRef, gridColumnGroupsUnwrappedModelSelector); const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector); const renderContext = useGridSelector(apiRef, gridRenderContextColumnsSelector); @@ -162,8 +162,15 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => { const { renderContext: currentContext = renderContext, maxLastColumn = visibleColumns.length } = params || {}; - const firstColumnToRender = currentContext.firstColumnIndex; - const lastColumnToRender = !hasVirtualization ? maxLastColumn : currentContext.lastColumnIndex; + let firstColumnToRender; + let lastColumnToRender; + if (!rootProps.disableVirtualization && !hasColumnVirtualization) { + firstColumnToRender = 0; + lastColumnToRender = maxLastColumn; + } else { + firstColumnToRender = currentContext.firstColumnIndex; + lastColumnToRender = currentContext.lastColumnIndex; + } const renderedColumns = visibleColumns.slice(firstColumnToRender, lastColumnToRender); return { diff --git a/packages/x-data-grid/src/hooks/features/columnResize/gridColumnResizeApi.ts b/packages/x-data-grid/src/hooks/features/columnResize/gridColumnResizeApi.ts index 3b0e62969221..88b8b3a0fcc7 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/gridColumnResizeApi.ts +++ b/packages/x-data-grid/src/hooks/features/columnResize/gridColumnResizeApi.ts @@ -5,6 +5,7 @@ export const DEFAULT_GRID_AUTOSIZE_OPTIONS = { includeOutliers: false, outliersFactor: 1.5, expand: false, + disableColumnVirtualization: true, }; export type GridAutosizeOptions = { @@ -32,6 +33,11 @@ export type GridAutosizeOptions = { * @default false */ expand?: boolean; + /** + * If false, column virtualization is not disabled while resizing. + * @default true + */ + disableColumnVirtualization?: boolean; }; /** diff --git a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx index fb778d30871e..133661062d5e 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx @@ -278,6 +278,7 @@ export const useGridColumnResize = ( | 'disableAutosize' | 'onColumnResize' | 'onColumnWidthChange' + | 'disableVirtualization' >, ) => { const isRtl = useRtl(); @@ -685,6 +686,7 @@ export const useGridColumnResize = ( apiRef.current.autosizeColumns({ ...props.autosizeOptions, + disableColumnVirtualization: false, columns: [column.field], }); }); @@ -717,8 +719,10 @@ export const useGridColumnResize = ( const columns = options.columns.map((c) => apiRef.current.state.columns.lookup[c]); try { - apiRef.current.unstable_setColumnVirtualization(false); - await columnVirtualizationDisabled(); + if (!props.disableVirtualization && options.disableColumnVirtualization) { + apiRef.current.unstable_setColumnVirtualization(false); + await columnVirtualizationDisabled(); + } const widthByField = extractColumnWidths(apiRef, options, columns); @@ -764,11 +768,14 @@ export const useGridColumnResize = ( } }); } finally { - apiRef.current.unstable_setColumnVirtualization(true); + if (!props.disableVirtualization) { + apiRef.current.unstable_setColumnVirtualization(true); + } + isAutosizingRef.current = false; } }, - [apiRef, columnVirtualizationDisabled], + [apiRef, columnVirtualizationDisabled, props.disableVirtualization], ); /**