11import { render } from 'preact' ;
2- import { useRef } from 'preact/hooks' ;
2+ import { useCallback , useMemo , useRef , useState } from 'preact/hooks' ;
33import { act } from 'preact/test-utils' ;
44
55import { waitFor } from '../../test-util/wait' ;
66import { useArrowKeyNavigation } from '../use-arrow-key-navigation' ;
77
88function Toolbar ( { navigationOptions = { } } ) {
99 const containerRef = useRef ( ) ;
10+ const visible = navigationOptions . containerVisible ?? true ;
1011
1112 useArrowKeyNavigation ( containerRef , navigationOptions ) ;
1213
1314 return (
14- < div ref = { containerRef } data-testid = "toolbar" tabIndex = { - 1 } >
15+ < div
16+ ref = { containerRef }
17+ data-testid = "toolbar"
18+ tabIndex = { - 1 }
19+ style = { { display : visible ? 'block' : 'none' } }
20+ >
1521 < button data-testid = "bold" > Bold</ button >
1622 < button data-testid = "italic" > Italic</ button >
1723 < button data-testid = "underline" > Underline</ button >
@@ -22,6 +28,24 @@ function Toolbar({ navigationOptions = {} }) {
2228 ) ;
2329}
2430
31+ function ToolbarWithToggle ( { navigationOptions = { } } ) {
32+ const [ visible , setVisible ] = useState ( false ) ;
33+ const toggleVisible = useCallback ( ( ) => setVisible ( prev => ! prev ) , [ ] ) ;
34+ const options = useMemo (
35+ ( ) => ( { ...navigationOptions , containerVisible : visible } ) ,
36+ [ navigationOptions , visible ] ,
37+ ) ;
38+
39+ return (
40+ < >
41+ < button data-testid = "toggle" onClick = { toggleVisible } >
42+ Toggle
43+ </ button >
44+ < Toolbar navigationOptions = { options } />
45+ </ >
46+ ) ;
47+ }
48+
2549describe ( 'useArrowKeyNavigation' , ( ) => {
2650 let container ;
2751 let toolbar ;
@@ -349,4 +373,20 @@ describe('useArrowKeyNavigation', () => {
349373 pressKey ( 'ArrowLeft' ) ;
350374 assert . equal ( currentItem ( ) , 'Bold' ) ;
351375 } ) ;
376+
377+ it ( 'should re-check focus sequence when container visibility changes' , async ( ) => {
378+ await act ( ( ) =>
379+ render (
380+ < ToolbarWithToggle navigationOptions = { { autofocus : true } } /> ,
381+ container ,
382+ ) ,
383+ ) ;
384+
385+ // No button should be initially focused
386+ assert . equal ( document . activeElement , document . body ) ;
387+
388+ // Once we toggle the list open, the first item will be focused
389+ findElementByTestId ( 'toggle' ) . click ( ) ;
390+ await waitFor ( ( ) => document . activeElement === findElementByTestId ( 'bold' ) ) ;
391+ } ) ;
352392} ) ;
0 commit comments