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

[a11y] Accessibility for nested text components

Open frags51 opened this issue 3 years ago • 23 comments

Description

Same as (stale) https://github.com/facebook/react-native/issues/27147. Consider this example:

<Text>
    <Text> Please click:  </Text>
    <Text accessible={true} accessibilityRole='link' onPress={openLink()}> Link </Text>
</Text>

A screen reader user is not able to click/open the link (i.e. the 2nd nested Text component). Ideally, the screen reader should focus on the link as well. The addition of any permutation of accessibility props on the parent/child Text component does not help.

React Native version:

React native 0.62. React Native Environment Info: System: OS: Windows 10 CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor Memory: 19.72 GB / 31.92 GB Binaries: Node: 12.21.0 - C:\Users\supsing\AppData\Local\Temp\yarn--1628676998345-0.3639484914346074\node.CMD Yarn: 1.22.10 - C:\Users\supsing\AppData\Local\Temp\yarn--1628676998345-0.3639484914346074\yarn.CMD npm: 6.14.11 - C:\Users\supsing\AppData\Local\nvs\default\npm.CMD Watchman: 20210102.202219.0 - E:\watchman-v2021.01.04.00-windows\bin\watchman.EXE

Steps To Reproduce

Write nested text components as shown in the description.

Expected Results

Screen reader (Voiceover/talkback) should be able to tell the user that there is a link and user should be able to click on that link.

In Android (native), talkback adds any links available in a single text view in the accessibility menu (can be opened using swipe up then swipe right). The same should be done by React Native as well. Perhaps it can be achieved with ClickableSpan in Android. There should be similar ways in iOS as well.

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

<Text>
    <Text> Please click:  </Text>
    <Text accessible={true} accessibilityRole='link' onPress={openLink()}> Link </Text>
</Text>

frags51 avatar Aug 11 '21 10:08 frags51

There is no easy solution for this, even if try to create empty, pressable Views just where the pressable link is (using absolute positioning). This is because, onTextLayout/onLayout does not fire for the nested Text elements and hence it is not possible to know their position.

frags51 avatar Aug 12 '21 08:08 frags51

@amarlette, that's a big issue for consumers of our library https://github.com/meliorence/react-native-render-html, do you think this issue could be addressed in the context of the GAAD Pledge?

jsamr avatar Oct 04 '21 19:10 jsamr

Possible duplicate of https://github.com/facebook/react-native/issues/31298

jsamr avatar Oct 16 '21 17:10 jsamr

@jsamr Do you have any related issue threads from react-native-render-html that might help us understanding how this issue is affecting users?

tj-mc avatar Feb 01 '22 07:02 tj-mc

@tj-mc At least one, yes! https://github.com/meliorence/react-native-render-html/issues/285 The issue was also raised in our Discord server, such as here.

jsamr avatar Feb 01 '22 11:02 jsamr

Thanks. I'm doing my best to understand what technical solution would be required here, and if it's within my reach, as I also feel this is an important issue.

I agree @jsamr that this is a duplicate of #31298. @frags51, Would we consider closing this issue, and continuing this conversation in #31298?

tj-mc avatar Feb 02 '22 00:02 tj-mc

In Android (native), talkback adds any links available in a single text view in the accessibility menu (can be opened using swipe up then swipe right). The same should be done by React Native as well.

as documented in my test case https://github.com/fabriziobertoglio1987/react-native-notes/issues/9#issuecomment-1045593386 this was solved with commit https://github.com/facebook/react-native/commit/b352e2da8137452f66717cf1cecb2e72abd727d7 on Android

A screen reader user is not able to click/open the link (i.e. the 2nd nested Text component). Ideally, the screen reader should focus on the link as well.

currently working on https://github.com/fabriziobertoglio1987/react-native-notes/issues/9#issuecomment-1045593164. thanks

fabOnReact avatar Feb 28 '22 08:02 fabOnReact

@frags51 , has this been resolved by @fabriziobertoglio1987 's PR?

blavalla avatar May 18 '22 16:05 blavalla

@fabriziobertoglio1987 Is this working on iOS as well? @blavalla if not, then it needs to be solved for iOS too.

frags51 avatar May 30 '22 14:05 frags51

Is there at least an iOS workaround? I'm experiencing this now

tanyalsweeney avatar Jun 16 '22 23:06 tanyalsweeney

Thanks for addressing this on Android, @fabriziobertoglio1987. This is not working on iOS currently, and it would be great to have a fix for that as well, thanks.

pranjal-jately-unmind avatar Jun 20 '22 21:06 pranjal-jately-unmind

Why wouldn't you just wrap the text in a Touchable? Semantically, this is more accurate I think.

volpstar avatar Jul 28 '22 18:07 volpstar

I tested the following scenarios:

  • the Nested Text has accessibilityRole link
  • It is possible to focus with the screenreader on the link
  • Voiceover announces the link
  • It is possible to click on the link (I tested with a console.log)

The functionality works on the main branch. I remain available. Thanks

Testing iOS nested text without accessibilityRole link

https://user-images.githubusercontent.com/24992535/208450529-0a8b3382-fcef-476a-b781-f92c011a508d.mp4

Related Links:

fabOnReact avatar Dec 16 '22 16:12 fabOnReact

We're considering using this approach for handling inline links on iOS: https://benjie.ca/blog/2021/09/21/accessible-inline-links-react-native.html

It's not perfect, but at least makes the links available to VoiceOver users. An alternative approach might be to use an accessibility action.

Drew-Gerber avatar Apr 03 '23 19:04 Drew-Gerber

I have the same problem!

<Text>My text {' '} <Text accessibilityRole='link' onPress={ ()=> openFirstLink}>First link</Text> <Text accessibilityRole='link' onPress={ ()=> openSecondLink}>Second link</Text> </Text>

In my case, I have 2 nested links. On Android, the screen reader recognize the links, but on iOS it doesn't

carlaTatiana avatar Jun 22 '23 16:06 carlaTatiana

Has anyone found a solution for this that works for more than one link in a paragraph? I am building a news app for a major publication. We must meet WCAG AA, which I believe all apps should aim for, and I am struggling to find a path forward. This issue has been literally keeping me up at night.

We don't have the time or resources at this stage in the project to upgrade to the new architecture, which seems risky anyways, given that Expo only just now released experimental support (we're on Expo), and a quick spike I did that uncovered some bugs we'd have to resolve.

I'm shocked that React Native has such a fundamental accessibility gap here and that there hasn't been an effort to port the fix to the old architecture.

stevehanson avatar Oct 30 '23 19:10 stevehanson

I agree this is an unfortunate gap. Is it solved in the new architecture?

Perhaps if you have rich text content, an inline webview might be a better solution. You can load local HTML and render without a loading time if it's static.

It seems like most news apps I use are native wrappers around web layouts.

tj-mc avatar Oct 31 '23 10:10 tj-mc

Thanks for this suggestion, @tj-mc! I converted this portion of my app to use webviews instead, and this completely solved my accessibility issues. Screen reader, voice control, keyboard all work exactly as expected. It's a shame that we have to use webviews as an escape hatch, and I certainly wouldn't consider this issue as solved because of that option, but I am glad to have found a way to move forward.

stevehanson avatar Nov 03 '23 16:11 stevehanson

@stevehanson The changes shown in this PR could be a workaround.

Webview/HTML definitely helps but do consider the perf/memory implications of using one.

frags51 avatar Nov 04 '23 06:11 frags51

Hi team, Any update on this issue?

msftedad avatar Feb 08 '24 08:02 msftedad

After testing with Accessibility Inspector on iOS Simulator and TalkBack on the Android emulator, my conclusion is that this does appear to be adequately solved on the new architecture on iOS and with TalkBack on the old renderer, but is not solved on the old renderer on iOS, as also noted in #35193.

In the old architecture on iOS, VoiceOver reads the content of the link, but it is not possible to independently select it with VoiceOver or open the link using VoiceOver alone. This could vary on actual devices, but that's what I'm seeing in the simulator.

I realize this amounts to a summary of what others have concluded above, but I was confused reading through the comments on this issue and wanted to confirm whether it had been addressed and the scope.

chriszs avatar Apr 18 '24 07:04 chriszs

@chriszs, The role of link must be announced to user as if it does not announce the role user who depends on Voiceover will be impacted , Also Voice over is announcing it as Static text with no other information like double tap to activate the link.

msftedad avatar Apr 23 '24 11:04 msftedad

@msftedad Good point. Do you think that works okay on the new architecture and Android (where Android offers to provide a list of links after the paragraph has been read)?

chriszs avatar Apr 23 '24 12:04 chriszs

Hi @chriszs, This was discussed and as per the Inputs, this will be read on Android as well, so user will be aware of the information in paragraph.

msftedad avatar Jun 11 '24 10:06 msftedad

@chriszs , Any update?

msftedad avatar Jun 26 '24 07:06 msftedad