@@ -7,7 +7,7 @@ import { SpatialNavigationVirtualizedList } from './SpatialNavigationVirtualized
77import { DefaultFocus } from '../../context/DefaultFocusContext' ;
88import testRemoteControlManager from '../tests/helpers/testRemoteControlManager' ;
99import { setComponentLayoutSize } from '../../../testing/setComponentLayoutSize' ;
10- import { useRef } from 'react' ;
10+ import { useMemo , useRef } from 'react' ;
1111import { SpatialNavigationVirtualizedListRef } from '../../types/SpatialNavigationVirtualizedListRef' ;
1212import { SpatialNavigationNode } from '../Node' ;
1313
@@ -26,10 +26,13 @@ describe('SpatialNavigationVirtualizedList', () => {
2626 < TestButton title = { `button ${ index + 1 } ` } onSelect = { item . onSelect } />
2727 ) ;
2828
29- const data = Array . from ( { length : 10 } , ( _ , index ) => ( {
30- onSelect : ( ) => undefined ,
31- currentItemSize : index % 2 === 0 ? 100 : 200 ,
32- } ) ) ;
29+ const generateData = ( size = 10 ) =>
30+ Array . from ( { length : size } , ( _ , index ) => ( {
31+ onSelect : ( ) => undefined ,
32+ currentItemSize : index % 2 === 0 ? 100 : 200 ,
33+ } ) ) ;
34+
35+ const data = generateData ( ) ;
3336
3437 const dataWithVariableSizes = Array . from ( { length : 10 } , ( _ , index ) => ( {
3538 onSelect : ( ) => undefined ,
@@ -56,8 +59,15 @@ describe('SpatialNavigationVirtualizedList', () => {
5659 </ SpatialNavigationRoot > ,
5760 ) ;
5861
59- const VirtualizedListWithNavigationButtons = ( ) => {
60- const listRef = useRef < SpatialNavigationVirtualizedListRef > ( null ) ;
62+ // This is bad practice but easiest way to access the ref from outside the component for testing
63+ let currentListRef : React . RefObject < SpatialNavigationVirtualizedListRef > ;
64+ const VirtualizedListWithNavigationButtons = ( { listSize = 10 } ) => {
65+ currentListRef = useRef < SpatialNavigationVirtualizedListRef > ( null ) ;
66+
67+ const data = useMemo ( ( ) => {
68+ return generateData ( listSize ) ;
69+ } , [ listSize ] ) ;
70+
6171 return (
6272 < SpatialNavigationRoot >
6373 < SpatialNavigationNode orientation = "vertical" >
@@ -70,19 +80,19 @@ describe('SpatialNavigationVirtualizedList', () => {
7080 itemSize = { 100 }
7181 numberOfRenderedItems = { 5 }
7282 numberOfItemsVisibleOnScreen = { 3 }
73- ref = { listRef }
83+ ref = { currentListRef }
7484 />
7585 </ DefaultFocus >
76- < TestButton title = "Go to first" onSelect = { ( ) => listRef . current ?. focus ( 0 ) } />
77- < TestButton title = "Go to last" onSelect = { ( ) => listRef . current ?. focus ( 9 ) } />
86+ < TestButton title = "Go to first" onSelect = { ( ) => currentListRef . current ?. focus ( 0 ) } />
87+ < TestButton title = "Go to last" onSelect = { ( ) => currentListRef . current ?. focus ( 9 ) } />
7888 </ >
7989 </ SpatialNavigationNode >
8090 </ SpatialNavigationRoot >
8191 ) ;
8292 } ;
8393
84- const renderVirtualizedListWithNavigationButtons = ( ) =>
85- render ( < VirtualizedListWithNavigationButtons /> ) ;
94+ const renderVirtualizedListWithNavigationButtons = ( size = 10 ) =>
95+ render ( < VirtualizedListWithNavigationButtons listSize = { size } /> ) ;
8696
8797 it ( 'renders the correct number of item' , async ( ) => {
8898 const component = renderList ( ) ;
@@ -626,4 +636,26 @@ describe('SpatialNavigationVirtualizedList', () => {
626636 expectButtonToHaveFocus ( component , 'button 10' ) ;
627637 expectListToHaveScroll ( listElement , - 700 ) ;
628638 } ) ;
639+
640+ it ( 'jumps to first and last element for a huge list, even while focus is still on the list' , async ( ) => {
641+ const component = renderVirtualizedListWithNavigationButtons ( 1000 ) ;
642+ act ( ( ) => jest . runAllTimers ( ) ) ;
643+
644+ setComponentLayoutSize ( listTestId , component , { width : 300 , height : 300 } ) ;
645+ const listElement = await component . findByTestId ( listTestId ) ;
646+
647+ testRemoteControlManager . handleRight ( ) ;
648+ testRemoteControlManager . handleRight ( ) ;
649+ expectButtonToHaveFocus ( component , 'button 3' ) ;
650+ expectListToHaveScroll ( listElement , - 200 ) ;
651+
652+ act ( ( ) => {
653+ currentListRef ?. current ?. focus ( 999 ) ;
654+ } ) ;
655+ expectButtonToHaveFocus ( component , 'button 1000' ) ;
656+ act ( ( ) => {
657+ currentListRef ?. current ?. focus ( 0 ) ;
658+ } ) ;
659+ expectButtonToHaveFocus ( component , 'button 1' ) ;
660+ } ) ;
629661} ) ;
0 commit comments