diff --git a/source/Grid/Grid.jest.js b/source/Grid/Grid.jest.js index e030b9f1..4a3c18fc 100644 --- a/source/Grid/Grid.jest.js +++ b/source/Grid/Grid.jest.js @@ -558,6 +558,26 @@ describe('Grid', () => { expect(grid.state.scrollTop).toEqual(1900); }); + it('should preserve scrollTop state after scrollToCell when scrollTop prop is unchanged', () => { + // Render with autoHeight=true and an explicit scrollTop=0 prop, as WindowScroller would apply initially. + const grid = render( + getMarkup({ + autoHeight: true, + scrollTop: 0, + }), + ); + expect(grid.state.scrollTop).toEqual(0); + + // Call scrollToCell imperatively (equivalent to list.scrollToRow()). + // It should result in a scroll movement, ignoring the scrollTop prop. + grid.scrollToCell({rowIndex: 49}); + + // 100 rows * 20px rowHeight = 2,000px total height + // viewport height = 100px → 5 rows visible + // Minimum scroll to show row 49 at bottom = 49*20 + 20 - 100 = 900 + expect(grid.state.scrollTop).toEqual(900); + }); + it('should support scrollToPosition() public method', () => { const grid = render(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); diff --git a/source/Grid/Grid.js b/source/Grid/Grid.js index e7caff40..c1d9347b 100644 --- a/source/Grid/Grid.js +++ b/source/Grid/Grid.js @@ -235,6 +235,8 @@ type InstanceProps = { prevIsScrolling: boolean, prevScrollToColumn: number, prevScrollToRow: number, + prevScrollLeft?: number, + prevScrollTop?: number, columnSizeAndPositionManager: ScalingCellSizeAndPositionManager, rowSizeAndPositionManager: ScalingCellSizeAndPositionManager, @@ -346,6 +348,8 @@ class Grid extends React.PureComponent { prevIsScrolling: props.isScrolling === true, prevScrollToColumn: props.scrollToColumn, prevScrollToRow: props.scrollToRow, + prevScrollLeft: props.scrollToColumn, + prevScrollTop: props.scrollToRow, scrollbarSize: 0, scrollbarSizeMeasured: false, @@ -826,6 +830,8 @@ class Grid extends React.PureComponent { ): $Shape { const newState = {}; + let {instanceProps} = prevState; + if ( (nextProps.columnCount === 0 && prevState.scrollLeft !== 0) || (nextProps.rowCount === 0 && prevState.scrollTop !== 0) @@ -836,9 +842,12 @@ class Grid extends React.PureComponent { // only use scroll{Left,Top} from props if scrollTo{Column,Row} isn't specified // scrollTo{Column,Row} should override scroll{Left,Top} } else if ( - (nextProps.scrollLeft !== prevState.scrollLeft && + (nextProps.scrollLeft !== instanceProps.prevScrollLeft && + nextProps.scrollLeft !== prevState.scrollLeft && nextProps.scrollToColumn < 0) || - (nextProps.scrollTop !== prevState.scrollTop && nextProps.scrollToRow < 0) + (nextProps.scrollTop !== instanceProps.prevScrollTop && + nextProps.scrollTop !== prevState.scrollTop && + nextProps.scrollToRow < 0) ) { Object.assign( newState, @@ -850,8 +859,6 @@ class Grid extends React.PureComponent { ); } - let {instanceProps} = prevState; - // Initially we should not clearStyleCache newState.needToResetStyleCache = false; if ( @@ -948,6 +955,8 @@ class Grid extends React.PureComponent { instanceProps.prevRowHeight = nextProps.rowHeight; instanceProps.prevScrollToColumn = nextProps.scrollToColumn; instanceProps.prevScrollToRow = nextProps.scrollToRow; + instanceProps.prevScrollLeft = nextProps.scrollLeft; + instanceProps.prevScrollTop = nextProps.scrollTop; // getting scrollBarSize (moved from componentWillMount) instanceProps.scrollbarSize = nextProps.getScrollbarSize();