1- import { useNavigation } from '@react-navigation/native' ;
2- import { useCallback , useContext , useLayoutEffect , useState } from 'react' ;
1+ import { useFocusEffect , useNavigation } from '@react-navigation/native' ;
2+ import { useCallback , useContext , useLayoutEffect , useRef , useState } from 'react' ;
3+ import { InteractionManager } from 'react-native' ;
4+ import { type KeyboardFocus } from 'react-native-external-keyboard' ;
35
46import * as HeaderButton from '../../../containers/Header/components/HeaderButton' ;
57import i18n from '../../../i18n' ;
68import { useAppSelector } from '../../../lib/hooks/useAppSelector' ;
9+ import { useIsAccessibilityNavigationEnabled } from '../../../lib/hooks/useIsAccessibilityNavigationEnabled' ;
710import { useMasterDetail } from '../../../lib/hooks/useMasterDetail' ;
811import { usePermissions } from '../../../lib/hooks/usePermissions' ;
912import { isTablet } from '../../../lib/methods/helpers' ;
@@ -18,6 +21,8 @@ export const useHeader = () => {
1821
1922 const { searchEnabled, search, startSearch, stopSearch } = useContext ( RoomsSearchContext ) ;
2023 const [ options , setOptions ] = useState < any > ( null ) ;
24+ const isAccessibilityNavigationEnabled = useIsAccessibilityNavigationEnabled ( ) ;
25+ const drawerButtonRef = useRef < KeyboardFocus > ( null ) ;
2126 const supportedVersionsStatus = useAppSelector ( state => state . supportedVersions . status ) ;
2227 const requirePasswordChange = useAppSelector ( state => getUserSelector ( state ) . requirePasswordChange ) ;
2328 const isMasterDetail = useMasterDetail ( ) ;
@@ -101,6 +106,7 @@ export const useHeader = () => {
101106 const options = {
102107 headerLeft : ( ) => (
103108 < HeaderButton . Drawer
109+ ref = { drawerButtonRef }
104110 navigation = { navigation }
105111 testID = 'rooms-list-view-sidebar'
106112 onPress = {
@@ -171,5 +177,21 @@ export const useHeader = () => {
171177 search
172178 ] ) ;
173179
180+ // The rooms list header persists across native-stack navigation, so autoFocus (mount-only)
181+ // won't re-fire on back-return or after the list/banner render asynchronously. Re-assert focus
182+ // on the drawer button every time the screen is focused so external-keyboard/screen-reader
183+ // navigation always starts from a known element. Regular touch users are left untouched.
184+ useFocusEffect (
185+ useCallback ( ( ) => {
186+ if ( ! isAccessibilityNavigationEnabled ) {
187+ return ;
188+ }
189+ const task = InteractionManager . runAfterInteractions ( ( ) => {
190+ drawerButtonRef . current ?. focus ( ) ;
191+ } ) ;
192+ return ( ) => task . cancel ( ) ;
193+ } , [ isAccessibilityNavigationEnabled ] )
194+ ) ;
195+
174196 return { options } ;
175197} ;
0 commit comments