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

iOS/Android: Customize the order of accessibility highlighting among sibling elements

Open amarlette opened this issue 4 years ago • 8 comments
trafficstars

Requires API Proposal

This issue requires a new API. An API proposal should be added and discussed before proceeding with implementation. The API proposal can be added in the comments of this issue or linked as a separate issue.

Description

It is currently impossible to specify the ordering of accessibility elements in RN. Talkback/Voiceover will read out elements in a predictable pattern, but this is not always a desired UX. There should be a way to set this for a particular view hierarchy.

React Native version:

v0.63

Expected Behavior

It is still up for discussion how this could actually look in React Native. To be completely stateless, there could be a "priority" assigned to each component that would dynamically dictate a traversal every time the views are updated. Alternatively, to more closely bridge to existing native constructs, an array of views or view references could be given as a way to dictate order.

Android Details

https://developer.android.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.html#settraversalafter

iOS Details

https://developer.apple.com/documentation/uikit/accessibility/uiaccessibilitycontainer?language=objc

Related iOS docs: UIAccessibilityContainer, accessibilityElementAtIndex

SwiftUI (stateless) implementation: https://developer.apple.com/documentation/swiftui/view/accessibilitysortpriority(_:)

amarlette avatar Feb 04 '21 19:02 amarlette

@amarlette I am experiencing the same issue. I wonder is there a way to visually hide an element in React Native and only visible to screen readers? I have tried methods like setting height 0 and opacity 0 to a container and have the relevant text but voiceover does not seems to be picking up when the height is 0.

I have used various css tricks to do the same in web applications and worked perfectly well.

samithaf avatar Feb 13 '21 00:02 samithaf

Would be great to have a way to focus on elements without having a ref/direct editing control of components. Use case is that we might want to focus on elements which have been obtained from an external library, which does not expose a ref to their elements.

frags51 avatar Jul 16 '21 08:07 frags51

I am not sure if it's a good 3-rd party lib that doesn't expose refs to its elements. We use a solution with refs, what do you think about it?

This approach was used on IOS and view.setNextFocusForwardId and view.setAccessibilityTraversalBefore on Android

andriikovall avatar Jan 26 '22 17:01 andriikovall

@ZioVio That's great! Do you know if there is a way to convert it into a library and make it compatible with Expo? Unless this approach is approved from the React Native team, but it is likely to take a long time. Thanks!

brunoprietog avatar Feb 24 '22 06:02 brunoprietog

I am not sure if it's a good 3-rd party lib that doesn't expose refs to its elements. We use a solution with refs, what do you think about it?

This approach was used on IOS and view.setNextFocusForwardId and view.setAccessibilityTraversalBefore on Android

We are using view.setAccessibilityTraversalBefore on android, it works well when components are visible on the screen, but it fails to focus in right order when next component is beneath the screen. Do you experiment the same issue @ZioVio ?

fabien88 avatar Mar 01 '22 09:03 fabien88

I have a use case for this, discussed here

https://stackoverflow.com/questions/73027686/react-native-a11y-grouping-elements-for-better-voiceover-announcement-while-sti

Since customizing the order of elements in not yet available, what are the currently suggested resolutions for such problems ?

gaurav5430 avatar Jul 19 '22 11:07 gaurav5430

@ziovio That's great! Do you know if there is a way to convert it into a library and make it compatible with Expo? Unless this approach is approved from the React Native team, but it is likely to take a long time. Thanks!

@brunoprietog

I might be way too late actually =) but expo provides a comprehensive list of tools available for customising native code for you https://docs.expo.dev/modules/overview/

As for the RN team, I am more than sure that it's not a priority and it's a lot simpler for them to let us, possible contributors, create a package for that

andriikovall avatar Aug 20 '23 13:08 andriikovall

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Feb 17 '24 05:02 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Feb 24 '24 05:02 github-actions[bot]

Hello there,

I finished work on my own focus order library which should help with grouping and focus order. API is really simple and can help with horizontal scroll issue.

https://github.com/ArturKalach/react-native-a11y-order

For example:

import { A11y, IndexCommands } from 'react-native-a11y-order';

// ...

export default function App() {
  return (
    <ScrollView
      style={styles.slider}
      contentContainerStyle={styles.sliderContainer}
      horizontal
    >
      <A11y.Group style={styles.slide}>
        <View>
          <Text>Title: 1</Text>
        </View>
        <View>
          <Text>Desctiption: 1</Text>
        </View>
      </A11y.Group>
      <A11y.Group style={styles.slide}>
        <View>
          <Text>Title: 2</Text>
        </View>
        <View>
          <Text>Desctiption: 2</Text>
        </View>
      </A11y.Group>
    </ScrollView>
  );
}

And


import { A11y } from 'react-native-a11y-order';

// ...

export default function App() {
  return (
    <View style={styles.container}>
      <A11y.Order>
        <A11y.Index index={1}>
          <Text style={styles.font}>
            First
          </Text>
        </A11y.Index>
        <A11y.Index index={3}>
          <Text style={styles.font}>
            Third
          </Text>
        </A11y.Index>
        <A11y.Index index={2}>
          <Text style={styles.font}>
            Second
          </Text>
        </A11y.Index>
      </A11y.Order>
      <Text style={styles.font}>Fourth</Text>
      <Text style={styles.font}>Fifth</Text>
      <Text style={styles.font}>Sixth</Text>
    </View>
  );
}

We can use just indexes to define focus order.

ArturKalach avatar Aug 06 '24 20:08 ArturKalach

Awesome! Thanks @ArturKalach

brunoprietog avatar Aug 07 '24 01:08 brunoprietog