-
Notifications
You must be signed in to change notification settings - Fork 25.1k
Description
Description
On my project I want to move the accessibility (f.e. VoiceOver) focus on a different component, but I can't find any good, well documented, approach. The use-case is f.e. that after clicking the button I want to open the modal and focus proper component inside that modal.
I found two different solutions, but both of them has some flaws:
- Move focus with help of
AccessibilityInfo.setAccessibilityFocus. But this method requiresreactTagwhich can be only obtained with deprecatedfindNodeHandlefunction - Use
AccessibilityInfo.sendAccessibilityEventpassing "focus" and component ref. The problem with this one is that it's not documented method.
In documentation I've also found the usage on focus() method on ref, but it's not defined on the accessible and focusable View component (No command found with name "focus").
What is the correct way of moving accessibility focus in "post-findNodeHandle" world?
React Native Version
0.70.5
Output of npx react-native info
System:
OS: macOS 13.1
CPU: (10) arm64 Apple M1 Pro
Memory: 72.63 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 19.7.0 - ~/.nvm/versions/node/v19.7.0/bin/node
Yarn: 1.22.19 - ~/.yarn/bin/yarn
npm: 9.5.1 - ~/.nvm/versions/node/v19.7.0/bin/npm
Watchman: 2023.02.13.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
Android SDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8815526
Xcode: 14.2/14C18 - /usr/bin/xcodebuild
Languages:
Java: 11.0.14.1 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.5 => 0.70.5
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
Steps to reproduce
- Add to your app 2 accessible views, and the Pressable component which will trigger moving accessibility focus function. View, which we want to be focused programatically should be above in hierarchy to button, the other one should be below it.
- Turn on the screen reader functionality (on iOS it would be VoiceOver)
- Click the button with screen reader on, accessibility focus should move accordingly to the defined View
Snack, code example, screenshot, or link to a repository
https://snack.expo.dev/@rooobi/accessibility-focus
import * as React from 'react';
import { Text, View, StyleSheet, Pressable, AccessibilityInfo, findNodeHandle } from 'react-native';
export default function App() {
const ref = React.useRef(null);
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text ref={ref} style={{marginBottom: 60}}>
Should be focused after clicking the button
</Text>
<Pressable onPress={() => {
//move focus with AccessibilityInfo.setAccessibilityFocus
const reactTag = findNodeHandle(ref.current);
AccessibilityInfo.setAccessibilityFocus(reactTag);
//move focus with AccessibilityInfo.sendAccessibilityEvent
// AccessibilityInfo.sendAccessibilityEvent(ref.current);
//ref.current.focus is no method
// ref.current?.focus();
}}>
<Text>Click to move focus up</Text>
</Pressable>
<Text focusable accessible style={{marginTop: 60}}>
Next in line to focus
</Text>
</View>
);
}