facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.32k stars 24.23k forks source link

[a11y] Accessibility for nested text components #32004

Open frags51 opened 3 years ago

frags51 commented 3 years ago

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 commented 3 years ago

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.

jsamr commented 2 years ago

@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 commented 2 years ago

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

tj-mc commented 2 years ago

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

jsamr commented 2 years ago

@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.

tj-mc commented 2 years ago

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?

fabOnReact commented 2 years ago

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

blavalla commented 2 years ago

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

frags51 commented 2 years ago

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

tanyalsweeney commented 2 years ago

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

pranjal-jately-unmind commented 2 years ago

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.

volpstar commented 2 years ago

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

fabOnReact commented 1 year ago

I tested the following scenarios:

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:

Drew-Gerber commented 1 year ago

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.

carlaTatiana commented 1 year ago

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

stevehanson commented 10 months ago

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.

tj-mc commented 10 months ago

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.

stevehanson commented 10 months ago

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.

frags51 commented 10 months ago

@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.

msftedad commented 7 months ago

Hi team, Any update on this issue?

chriszs commented 5 months ago

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.

msftedad commented 4 months ago

@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.

chriszs commented 4 months ago

@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)?

msftedad commented 3 months ago

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 commented 2 months ago

@chriszs , Any update?

yanachrnsh commented 3 weeks ago

I faced the same issue, if I put Text inside Text with accessibility role "link" and onPress, on the Android emulator it says that link can be opened using swipe up then swipe right, but on iOS it does not recognise as it is link

<Text>Any text 
    <Text accessibilityRole='link' onPress={ ()=>{}}>Link</Text>
</Text>