@@ -29,6 +29,7 @@ describe('FixedSizeGrid', () => {
2929
3030 // JSdom does not do actual layout and so doesn't return meaningful values here.
3131 // For the purposes of our tests though, we can mock out semi-meaningful values.
32+ // This mock is required for e.g. "onScroll" tests to work properly.
3233 Object . defineProperties ( HTMLElement . prototype , {
3334 clientWidth : {
3435 configurable : true ,
@@ -86,7 +87,7 @@ describe('FixedSizeGrid', () => {
8687
8788 it ( 'should render a grid of items' , ( ) => {
8889 ReactTestRenderer . create ( < FixedSizeGrid { ...defaultProps } /> ) ;
89- expect ( itemRenderer ) . toHaveBeenCalledTimes ( 24 ) ;
90+ expect ( itemRenderer ) . toHaveBeenCalledTimes ( 15 ) ;
9091 expect ( onItemsRendered . mock . calls ) . toMatchSnapshot ( ) ;
9192 } ) ;
9293
@@ -493,9 +494,9 @@ describe('FixedSizeGrid', () => {
493494 expect ( onItemsRendered ) . toHaveBeenLastCalledWith (
494495 expect . objectContaining ( {
495496 visibleColumnStartIndex : 1 ,
496- visibleColumnStopIndex : 3 ,
497+ visibleColumnStopIndex : 2 ,
497498 visibleRowStartIndex : 4 ,
498- visibleRowStopIndex : 8 ,
499+ visibleRowStopIndex : 7 ,
499500 } )
500501 ) ;
501502
@@ -505,7 +506,7 @@ describe('FixedSizeGrid', () => {
505506 expect ( onItemsRendered ) . toHaveBeenLastCalledWith (
506507 expect . objectContaining ( {
507508 visibleColumnStartIndex : 1 ,
508- visibleColumnStopIndex : 3 ,
509+ visibleColumnStopIndex : 2 ,
509510 } )
510511 ) ;
511512
@@ -515,7 +516,7 @@ describe('FixedSizeGrid', () => {
515516 expect ( onItemsRendered ) . toHaveBeenLastCalledWith (
516517 expect . objectContaining ( {
517518 visibleRowStartIndex : 8 ,
518- visibleRowStopIndex : 12 ,
519+ visibleRowStopIndex : 11 ,
519520 } )
520521 ) ;
521522 } ) ;
@@ -569,6 +570,51 @@ describe('FixedSizeGrid', () => {
569570 expect ( onItemsRendered . mock . calls ) . toMatchSnapshot ( ) ;
570571 } ) ;
571572
573+ it ( 'scroll with align = "auto" should work with partially-visible items' , ( ) => {
574+ const rendered = ReactTestRenderer . create (
575+ // Create list where items don't fit exactly into container.
576+ // The container has space for 3 1/3 items.
577+ < FixedSizeGrid { ...defaultProps } columnWidth = { 70 } rowHeight = { 30 } />
578+ ) ;
579+ // Scroll down enough to show row 10 at the bottom a nd column 10 at the right.
580+ // Should show 4 rows: 3 full and one partial at the beginning
581+ // Should show 3 columns: 2 full and one partial at the beginning
582+ rendered
583+ . getInstance ( )
584+ . scrollToItem ( { columnIndex : 10 , rowIndex : 10 , align : 'auto' } ) ;
585+ // No need to scroll again; row and column 9 are already visible.
586+ // Because there's no scrolling, it won't call onItemsRendered.
587+ rendered
588+ . getInstance ( )
589+ . scrollToItem ( { columnIndex : 9 , rowIndex : 9 , align : 'auto' } ) ;
590+ // Scroll to near the end. row 96 and column 97 will be partly visible.
591+ rendered
592+ . getInstance ( )
593+ . scrollToItem ( { columnIndex : 99 , rowIndex : 99 , align : 'auto' } ) ;
594+ // Scroll back to row 91 and column 97.
595+ // This will cause row 99 and column 99 to be partly viisble
596+ // Even though a scroll happened, none of the items rendered have changed.
597+ rendered
598+ . getInstance ( )
599+ . scrollToItem ( { columnIndex : 97 , rowIndex : 96 , align : 'auto' } ) ;
600+ // Scroll forward again. Because row and column #99 were already partly visible,
601+ // all props of the onItemsRendered will be the same.
602+ rendered
603+ . getInstance ( )
604+ . scrollToItem ( { columnIndex : 99 , rowIndex : 99 , align : 'auto' } ) ;
605+ // Scroll to the second row and column.
606+ // This should leave row 4 and column 3 partly visible.
607+ rendered
608+ . getInstance ( )
609+ . scrollToItem ( { columnIndex : 1 , rowIndex : 1 , align : 'auto' } ) ;
610+ // Scroll to the first row and column.
611+ // This should leave row 3 and column 2 partly visible.
612+ rendered
613+ . getInstance ( )
614+ . scrollToItem ( { columnIndex : 0 , rowIndex : 0 , align : 'auto' } ) ;
615+ expect ( onItemsRendered . mock . calls ) . toMatchSnapshot ( ) ;
616+ } ) ;
617+
572618 it ( 'should scroll to the correct item for align = "auto" at the bottom of the grid' , ( ) => {
573619 getScrollbarSize . mockImplementation ( ( ) => 20 ) ;
574620
@@ -948,6 +994,45 @@ describe('FixedSizeGrid', () => {
948994 simulateScroll ( instance , { scrollLeft : 200 , scrollTop : 200 } ) ;
949995 expect ( onScroll . mock . calls [ 0 ] [ 0 ] . scrollUpdateWasRequested ) . toBe ( false ) ;
950996 } ) ;
997+
998+ it ( 'scrolling should report partial items correctly in onItemsRendered' , ( ) => {
999+ // Use ReactDOM renderer so the container ref works correctly.
1000+ const instance = ReactDOM . render (
1001+ < FixedSizeGrid
1002+ { ...defaultProps }
1003+ initialScrollLeft = { 20 }
1004+ initialScrollTop = { 10 }
1005+ /> ,
1006+ document . createElement ( 'div' )
1007+ ) ;
1008+ // grid 200w x 100h
1009+ // columnWidth: 100, rowHeight: 25,
1010+ // columnCount: 100, rowCount: 100
1011+ // Scroll 2 items fwd, but thanks to the initialScrollOffset, we should
1012+ // still be showing partials on both ends.
1013+ instance . scrollTo ( { scrollLeft : 150 , scrollTop : 40 } ) ;
1014+ // Scroll a little fwd to cause partials to be hidden
1015+ instance . scrollTo ( { scrollLeft : 200 , scrollTop : 50 } ) ;
1016+ // Scroll backwards to show partials again
1017+ instance . scrollTo ( { scrollLeft : 150 , scrollTop : 40 } ) ;
1018+ // Scroll near the end so that the last item is shown
1019+ // as a partial.
1020+ instance . scrollTo ( {
1021+ scrollLeft : 98 * 100 - 5 ,
1022+ scrollTop : 96 * 25 - 5 ,
1023+ } ) ;
1024+ // Scroll to the end. No partials.
1025+ instance . scrollTo ( {
1026+ scrollLeft : 98 * 100 ,
1027+ scrollTop : 96 * 25 ,
1028+ } ) ;
1029+ // Verify that backwards scrolling near the end works OK.
1030+ instance . scrollTo ( {
1031+ scrollLeft : 98 * 100 - 5 ,
1032+ scrollTop : 96 * 25 - 5 ,
1033+ } ) ;
1034+ expect ( onItemsRendered . mock . calls ) . toMatchSnapshot ( ) ;
1035+ } ) ;
9511036 } ) ;
9521037
9531038 describe ( 'itemKey' , ( ) => {
0 commit comments