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

Keyboard focus (from a physical keyboard) won't enter TextInput fields on Tab/Shift+Tab in Android #30464

Closed
NatPri opened this issue Nov 24, 2020 · 17 comments
Assignees
Labels
Accessibility Team - Evaluated Accessibility API: Keyboard Component: TextInput Related to the TextInput component. Needs: Triage 🔍 Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@NatPri
Copy link

NatPri commented Nov 24, 2020

Description

On Android devices, when other focusable controls (such as Buttons) are adjacent to a TextInput component, and a physical keyboard is used to interact with the app (e.g. via bluetooth or USB connection), keyboard focus will stop at the focusable element before the TextInput when tabbing or at the one after the TextInput when shift-tabbing.

React Native version:

System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
    Memory: 13.44 GB / 31.94 GB
  Binaries:
    Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.19.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.4 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK:
      AllowAllTrustedApps: Enabled
  IDEs:
    Android Studio: Version  4.0.0.0 AI-193.6911.18.40.6626763
    Visual Studio: 15.9.28307.518 (Visual Studio Enterprise 2017)
  Languages:
    Java: Not Found
    Python: 2.7.11 - C:\Python27\python.EXE
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1
    react-native: https://github.com/expo/react-native/archive/sdk-39.0.4.tar.gz => 0.63.2
    react-native-windows: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Using the Snack below under Android (tested on Pixel 3 with Android 11)

  1. Connect a physical keyboard to the Android device, either using USB or Bluetooth. If using an emulator, you may need to configure it to send keyboard shortcuts to the virtual device; I've had better luck reproing on physical devices, though.
  2. Press Tab and Shift+Tab to move the focus between the Buttons and TextInput
  3. Observe that pressing Tab when focused on the element before the TextInput or Shift+Tab on the element after the TextInput does not move the focus to the TextInput. Additionally, if you tap to activate the TextInput, you cannot press Tab/Shift+Tab to leave the TextInput.

Expected Results

The TextInput should participate in the keyboard tab order. Users may use a physical keyboard for accessibility reasons.

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

https://snack.expo.io/dg2qxBBue

@NatPri
Copy link
Author

NatPri commented Feb 24, 2021

This has been sitting for a few months now, is there anyone that can comment on what sort of timeline we could expect on this bug?

@fabOnReact
Copy link
Contributor

fabOnReact commented Feb 26, 2021

https://developer.android.com/training/keyboard-input/navigation#Tab

All interactive widgets provided by the Android framework (such as Button and EditText) are focusable. This means users can navigate with control devices such as a D-pad or keyboard and each widget glows or otherwise changes its appearance when it gains input focus.

https://reactnative.dev/docs/building-for-tv#code-changes

InputText components do not work for now (i.e. they cannot receive focus).

The reason here
#16500 (comment)

EDIT: It is possible to wrap inputs in Touchable elements and do onFocus={() => textInputRef.current.focus()}

which means you need to add the implementation explained here https://reactnative.dev/docs/building-for-tv#code-changes
and wrap you TextInput in touchables

@kriti18singh
Copy link

@NatPri were you able to get this working?

@NatPri
Copy link
Author

NatPri commented May 7, 2021

I was moved to a different project before I could revisit this, so unfortunately I don't know where this ended up, sorry.

@kriti18singh
Copy link

@fabriziobertoglio1987 the workaround does not seem to work. Wrapping the TextInput in a Touchable and then tabbing never fires the onFocus of the touchable. Tried this a couple of times but it didn't work. onPress of the TouchableHighlight and TouchableNativeFeedback is fired but never onFocus. Also, I have a button below the text input, if the current keyboard focus is on the button - doing shift + tab does not take it back to the input (touchable wrapped input did not work here). Are you aware of any other workarounds?

@msgharpu
Copy link

msgharpu commented Jul 6, 2021

Input in a

@fabriziobertoglio1987 the workaround does not seem to work. Wrapping the TextInput in a Touchable and then tabbing never fires the onFocus of the touchable. Tried this a couple of times but it didn't work. onPress of the TouchableHighlight and TouchableNativeFeedback is fired but never onFocus. Also, I have a button below the text input, if the current keyboard focus is on the button - doing shift + tab does not take it back to the input (touchable wrapped input did not work here). Are you aware of any other workarounds?

Can we add a dummy button and a textinput within the Touchable wrapper? May be focus is not happening as TextInput is the only control within wrapper and for that taking focus is explicitly disbaled here

msgharpu referenced this issue Jul 6, 2021
Summary:
Right now, `requestFocus()` is a no-op if the EditText view thinks it's already focused. In certain cases, though, we still want to focus the view even if it's already focused - for example, if TalkBack is enabled and you dismiss the keyboard, you want to be able to tap on the TextInput again to bring back the keyboard, even though the View never thinks it lost focus.

What I'm doing instead is basically disregarding the View's current focus state if we *would* focus the TextInput, which is in 3 circumstances:

- When the view is attached to a window, if autofocus is true
- When the focus is being requested by JS
- When the focus is being requested by an accessibility action from the OS

Changelog: [Android][Fixed] Change how TextInput responds to requestFocus to fix a11y focus issue

Reviewed By: mdvacca

Differential Revision: D19750312

fbshipit-source-id: 30b9fab40af4a083fa98f57aba7e586540238bea
@RyanCommits
Copy link

I found a workaround for my project:

Create a new InputField component that wraps the existing input field with a Pressable. This will allow you to focus on the input if the user hits Enter on their keyboard. Pressable is invisible to the user, and at least in our application, has the exact same experience when using touch interactions.

Next, only render this solution on Android.

Not the exact same interaction because the user needs one extra interaction to focus on the input, but at least they can get through our application now.

export const InputField = forwardRef<TextInput>((props, ref) => {
  const inputRef = useRef<TextInput>(null);

  ref = ref || inputRef;

  return (
    <Pressable
      onPress={() => {
        if (ref && typeof ref !== 'function' && ref.current) {
          ref.current.focus();
        }
      }}
    >
      <InputFieldIOS ref={ref} {...props} />
    </Pressable>
  );
});
import { InputField as InputFieldIos } from './InputField.ios';
import { InputField as InputFieldAndroid } from './InputField.android';

export const InputField = Platform.select({
  ios: InputFieldIos,
  android: InputFieldAndroid,
})!;

@kriti18singh
Copy link

@RyanCommits Can you shift+tab from button to textinput as well? meaning backward navigation

@stale
Copy link

stale bot commented Jan 9, 2022

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jan 9, 2022
@Jokerwolf
Copy link

Jokerwolf commented Aug 6, 2022

Hey everyone, this issue is still repro unfortunately. It seems like there is no other way, but wrapping TextInput and handling press events. Could you please give us some feedback (maybe it's not an issue at all) or estimations please?

@ShivamJoker
Copy link

I am also having the same issue can't focus on text input

@pandu-supriyono
Copy link

I found a workaround for my project:

Create a new InputField component that wraps the existing input field with a Pressable. This will allow you to focus on the input if the user hits Enter on their keyboard. Pressable is invisible to the user, and at least in our application, has the exact same experience when using touch interactions.

Next, only render this solution on Android.

Not the exact same interaction because the user needs one extra interaction to focus on the input, but at least they can get through our application now.

export const InputField = forwardRef<TextInput>((props, ref) => {
  const inputRef = useRef<TextInput>(null);

  ref = ref || inputRef;

  return (
    <Pressable
      onPress={() => {
        if (ref && typeof ref !== 'function' && ref.current) {
          ref.current.focus();
        }
      }}
    >
      <InputFieldIOS ref={ref} {...props} />
    </Pressable>
  );
});
import { InputField as InputFieldIos } from './InputField.ios';
import { InputField as InputFieldAndroid } from './InputField.android';

export const InputField = Platform.select({
  ios: InputFieldIos,
  android: InputFieldAndroid,
})!;

Hi @RyanCommits, have you tested how this translates for users dependent on screen readers?

@RyanCommits
Copy link

@pandu-supriyono I'm no longer working on the application that had this issue, and haven't looked at it for a while. Best of luck, this is a tough one.

@nedgip
Copy link

nedgip commented Apr 24, 2023

Hi @RyanCommits, have you tested how this translates for users dependent on screen readers?

Hi @pandu-supriyono

I've tested the recommended workaround (wrap the text input in a <Pressable> and then set focus on it) with TalkBack.

When using TalkBack, navigating by swiping left and right, there is no real difference from navigating a native android text field. So all good there, it works as expected.

However, for external keyboard users, who also use a screen reader there is a problem, in that focus moves to the <Pressable> and nothing is announced.

To address this, we had to add an accessibilityLabel as well as the value and associated accessibilityHint text to the pressable, so that it mirrors the announcement of the <TextInput>. This way, external keyboard users who also screen reader can navigate the fields and hear equivalent information.

When you add the accessibilityLabel to the pressable it makes it discoverable to screen reader users. So each field effectively receives focus twice when swiping with TalkBack. It's an annoying trade off, but we felt the additional focus points were a less critical issue than the label and value of the field not being announced at all.

@ArturKalach
Copy link

There are a tricky fix from the native side: https://github.com/ArturKalach/react-native-a11y/blob/master/docs/AndroidInput.md

android-example

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Sep 20, 2023
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 19, 2024
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Accessibility Team - Evaluated Accessibility API: Keyboard Component: TextInput Related to the TextInput component. Needs: Triage 🔍 Platform: Android Android applications. 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