Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct way to move accessibility focus #37015

Closed
robertKozik opened this issue Apr 21, 2023 · 9 comments
Closed

Correct way to move accessibility focus #37015

robertKozik opened this issue Apr 21, 2023 · 9 comments
Labels
Needs: Triage 🔍 Newer Patch Available Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@robertKozik
Copy link

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 requires reactTag which can be only obtained with deprecated findNodeHandle function
  • Use AccessibilityInfo.sendAccessibilityEvent passing "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

  1. 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.
  2. Turn on the screen reader functionality (on iOS it would be VoiceOver)
  3. 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>
  );
}
@github-actions
Copy link

⚠️ Newer Version of React Native is Available!
ℹ️ You are on a supported minor version, but it looks like there's a newer patch available. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.

@ArturKalach
Copy link

ArturKalach commented Apr 22, 2023

Hello @robertKozik ,
I guess there are no any good solution so far, I researched new arch and so on, and unfortunately they use reactTag.
I wrote a lib for supporting a11y, you can try focus helpers from it https://www.npmjs.com/package/react-native-a11y.

Proves (0.71.5):
image
image

@consuelo-sanna
Copy link

consuelo-sanna commented Sep 13, 2023

Hi guys,
I've also heard about the findNodeHandle being deprecated but can't find documentation about it

@robertKozik I've read the conversation you had about this on the expensify's github (url), would you be so kind to sent me the video link if it's on youtube?

Copy link

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 github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Mar 12, 2024
Copy link

github-actions bot commented Apr 4, 2024

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

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 4, 2024
@LCseniordev
Copy link

@robertKozik Have you found solution for that? Facing the same issue

@brianangulo
Copy link

I see this got closed due to inactivity but this is very much still an issue on our end

@trcoffman
Copy link

This needs to be reopened.

@ArturKalach
Copy link

ArturKalach commented Jul 30, 2024

Hello there,

Based on the original post and information about findNodeHandle and HostComponent, I've created a workaround for a11y (screen reader) focus.

https://www.npmjs.com/package/react-native-a11y-focus

import { A11yFocusView } from "react-native-a11y-focus";

// ...

  const focusRef = useRef<A11yFocusViewType>(null);
  
  return (
    <View style={styles.container}>
      <A11yFocusView
        ref={focusRef}
        style={styles.box}
      >
        <Button title="Target component" />
      </A11yFocusView>
      <Button title="Focus target component" onPress={() => focusRef.current?.focus?.()} />
    </View>
  )

Why?:
Unfortunately, I haven't found any information about plans or approaches to focus it via React Native tools. Based on my experience, resolving a11y issues often takes a lot of time and is usually closed due to no activity. Using external libraries and workarounds is one of the possible solutions for now.

P.S. It makes sense to extend the library with additional functionality, such as autofocus and keyboard focus. I will consider this and try to add it in the upcoming releases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Triage 🔍 Newer Patch Available Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

6 participants