Skip to content

Conversation

@kligarski
Copy link
Contributor

@kligarski kligarski commented Sep 24, 2025

Description

Fixes keyboard navigation focus handling for form sheets on Android.

Previously, it was possible to focus elements in the view displayed below the form sheet.

Closes #3188.

before after
focus_before.mp4
focus_after.mp4

Context

In ScreenStack, there is already logic to handle accessibility focus via importantForAccessibility prop. I checked that the prop is changed correctly - there were no regressions here.

I stumbled upon an issue in react-native repo where one of the users explained that Android handles screen readers focus and keyboard navigation focus differently. In order to block keyboard navigation focus, you need to set focusable and descendantFocusability properties - when implemented in ScreenStack, this started working correctly (after clicking arrow-down, focus did not leave the formsheet).

Another problem that appeared is that the button used to open the form sheet remained focused after form sheet had been already opened. I attempted to use requestFocus() on the form sheet's screen but if there is a text input in the form sheet, it started working as if we set autoFocus on the input field.

focus_withRequestFocus.mp4

This also impacted regular touch navigation. I decided to use clearFocus on previous screen instead - this works as expected: first button in the screen is focused after opening the form sheet.

One thing I noticed is that when you go back from a screen, nothing is focused (I checked with layout inspector) - this is not a regression but we should have a look at it in the future. Native app (settings) on API 36 keeps focus when screen is popped. I created an issue to investigate this: https://github.com/software-mansion/react-native-screens-labs/issues/474.

Changing focusability on Android

Starting from API 26, focusable can be set to NOT_FOCUSABLE/FOCUSABLE/FOCUSABLE_AUTO. Prior to API 26, this was a boolean prop - that's why there is some extra code to handle both cases (changeFocusability and changeFocusabilityCompat functions in Screen.kt).

Changes

  • add methods to set focusability for Screen for API <= 25 and API >= 26
  • change focusability in sync with importantForAccessibility
  • set focusable to false/NOT_FOCUSABLE for DimmingView (this caused missing focus after popping a push screen that was pushed over form sheet)
  • clear focus from previous top screen in ScreenStack's onUpdate

Test code and steps to reproduce

Run TestFormSheet and use the keyboard to navigate.

Checklist

Copy link
Contributor

@t0maboro t0maboro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@kkafar
Copy link
Member

kkafar commented Nov 7, 2025

@kkafar

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so important thing here is that the form sheet on Android is not a modal view byt it's own.

We use something called "standard bottom sheet" & it is a set of views attached directly to the hierarchy in place where the Screen component is mounted. It does not behave like modal: it does not create separate DecorView & does not mount above all contents (that's something we'd like to support in next major).

Therefore I'm not all for emulating all modal features here.

What we could do is to expose a prop Android only prop to control this. OR alternatively block the focusability ONLY when dimming view is present. The presence of dimming view indicates to the user that he should focus on the sheets contents utterly, not on the background.

So yeah, what do you think @kligarski? Does that sound sensible?

@kligarski kligarski self-assigned this Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Form sheet does not enclose the external keyboard focus

4 participants