react-native icon indicating copy to clipboard operation
react-native copied to clipboard

[a11y][iOS] Nested accessibility items inside Text not accessible

Open xmflsct opened this issue 3 years ago • 8 comments

Description

Same as this issue https://github.com/facebook/react-native/issues/27147 Inline elements are not accessible. Such element can be <Text>This is a sentence, that has a <Text onPress={() => {}}>#hashtag</Text>, as well as a <Image /></Text>. Example such as a tweet that has inline hashtags, mentions, etc.

React Native version:

System:
    OS: macOS 11.2.3
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 1.05 GB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.15.3 - /var/folders/jk/v93zkv010j1dkt0vhtt0qw906bd4gy/T/yarn--1617574215615-0.8276275399979687/node
    Yarn: 1.22.10 - /var/folders/jk/v93zkv010j1dkt0vhtt0qw906bd4gy/T/yarn--1617574215615-0.8276275399979687/yarn
    npm: 7.8.0 - ~/.nvm/versions/node/v14.15.3/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK:
      API Levels: 29, 30
      Build Tools: 28.0.3, 29.0.2, 30.0.3
      System Images: android-29 | Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.6953283
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.9 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1 
    react-native: ~0.64.0 => 0.64.0 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Use an example such as <Text>This is a sentence, that has a <Text onPress={() => {}}>#hashtag</Text>, as well as a <Image /></Text>
  2. On iPhone physical device, turn on VoiceOver

Expected Results

There should be a way to make inline elements accessible. Looking at Twitter official client's example, these inline elements can be announced after reading through the full text.

Snack, code example, screenshot, or link to a repository:

In case this helpe, https://github.com/tooot-app/app/blob/main/src/components/Parse/HTML.tsx

xmflsct avatar Apr 04 '21 22:04 xmflsct

This is a real problem and the same happens on Android too. (Edit: some work has been done here on Android https://github.com/facebook/react-native/commit/b352e2da8137452f66717cf1cecb2e72abd727d7) We've had to work around it by detecting if the screen reader is active and if it is, swapping in interactive View-based blocks like TouchableOpacity in place of inline clickable text.

This is an ugly workaround because it looks and reads like this:

This is a paragraph with some info, if you want more info, please visit our

[screenreader stops awaiting a swipe]

official website ["link"]

[screenreader stops awaiting a swipe]

which has more info. Continuing the paragraph, ...

...and it doesn't use any of the screenreader features or patterns for links users are used to, but at least it's (barely) usable.

Please don't let this issue go stale again, team.

AlanSl avatar May 14 '21 11:05 AlanSl

@AlanSl I see the commit in your edit about the update on Android, and I see the changes in the react native node modules folder locally, but I cannot get nested links to be read on android Talk Back described in the commit. Has the latest android version broken these changes? Is anyone else able to get the screen reader to locate these links when nested in text components?

gp3gp3gp3 avatar Dec 06 '21 05:12 gp3gp3gp3

@gp3gp3gp3 Last time I looked into this issue, I was getting weird behaviour where a <Text> containing a single pressable <Text> would, on Android TalkBack, be read like "Contains links" even though it only contains one link; then you'd have to do the special accessibility action to get a list of links, expecting a menu of multiple links, and TalkBack would open a menu containing just one link. Meanwhile, if you had multiple links in one block/paragraph of Text (and so therefore you actually wanted TalkBack users to be offered this menu of links), the links would be ignored and no menu was offered at all.

It certainly seemed to me like the behaviour was not fixed, but rather, was now differently broken on each platform. However, I didn't look into it in depth, I just concluded that we weren't yet able to retire the hacky workaround described above. It's possible there was something I missed or overlooked.

AlanSl avatar Dec 06 '21 10:12 AlanSl

That is unfortunate. We also need nested text on press to be focusable with hardware keyboards. The new RN version includes the focusable prop, but these only exist on Views and not Text.

gp3gp3gp3 avatar Dec 06 '21 15:12 gp3gp3gp3

+1 This issue has to be resolved, since it is one of the main accessibility needs

moddatherrashed avatar Jan 28 '22 15:01 moddatherrashed

+1 Also having this issue, it's creating big problems for us and for the users that use the accessibility features on iOS.

mjdelb avatar Jan 31 '22 08:01 mjdelb

Links should now be working in the new Fabric renderer.

<View style={styles.container}>
  <Text style={styles.paragraph}>
    {'This is a test of '}
    <Text style={styles.link} accessibilityRole="link" onPress={() =>{ alert('clicked')}}>inline links</Text>
    {' in Fabric. Here is '}
    <Text style={styles.link} accessibilityRole="link" onPress={() =>{ alert('clicked')}}>another link</Text>
    {'.'}
  </Text>
</View>

https://user-images.githubusercontent.com/1518064/186504872-de0aaee7-d6d2-49e0-a1be-6b85da29bc86.mp4

Images aren't currently supported, but the logic would be similar for supporting links, you'd just need to look for <Image>'s in the same way we look for links and buttons here:

https://github.com/facebook/react-native/blob/7b05b091fd97f95b778369277ac2147730abc7b8/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm#L79

And add them as additional elements to the accessibilityElements array.

blavalla avatar Aug 24 '22 20:08 blavalla

@blavalla thanks mate, in which version was that fixed? is there "Fabric renderer" package, or is it within React Native?
I'm using react native 0.64 and still having the issue

akkadaya avatar Oct 21 '22 01:10 akkadaya

@akkadaya, this should be fixed in 0.69 via this commit (https://github.com/facebook/react-native/commit/7b5b114d578142d18bf4a7a5279b179a9ac8d958)

blavalla avatar Oct 21 '22 20:10 blavalla

While nested talkback is a critically important feature, we also need to be able to focus on nested text with hardware keyboards. If the focusable prop was exposed on text and allowed on press to respond to the hardware keyboard that would allow apps to meet WCAG compliance without resorting to buggy webviews.

And of course as mentioned, would be great to have this on iOS as well.

gp3gp3gp3 avatar Oct 28 '22 20:10 gp3gp3gp3

@gp3gp3gp3 thanks for the comment! Since you're highlighting something outside the scope of the original issue, we're going to close this one out but please go ahead and submit a new one with your insights.

alextait1 avatar Nov 02 '22 17:11 alextait1

@alextait1 Happy to open a new issue for the focusable prop, but this issue is still valid, since for non fabric builds iOS is still not working for screenreader on nested text components.

gp3gp3gp3 avatar Nov 02 '22 18:11 gp3gp3gp3