Skip to content

Keep Android disabled-state resets scoped to core views - #58795

Open
Marve10s wants to merge 1 commit into
react:mainfrom
Marve10s:fix/android-cleared-disabled-tap-target
Open

Marve10s wants to merge 1 commit into
react:mainfrom
Marve10s:fix/android-cleared-disabled-tap-target

Conversation

@Marve10s

@Marve10s Marve10s commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

#58799 fixed the original Pressable tap-target reset on main. This follow-up keeps that reset in ReactViewManager. Applying it in every manager can re-enable a non-editable TextInput when accessibility disabled is cleared, because ReactTextInputManager does not derive from ReactViewManager and controls its enabled state through editable.

BaseViewManager now has a protected instance hook, resetDisabledFromAccessibilityState, that does nothing by default. ReactViewManager overrides it to restore the enabled state that accessibility disabled took away, so its subclasses get the same behavior without a class check. setViewState clears the disabled tag itself, so view managers don't need to call super. Other managers keep the enabled state they control.

Since this PR was opened, #59387 started sending the full accessibilityState with Props 2.0 and #59047 re-enables views on recycle, so the earlier C++ prop change and the ReactViewGroup change are no longer part of this PR. The JavaScript components are unchanged.

Changelog:

[ANDROID] [FIXED] - Preserve non-editable text inputs when accessibility disabled is cleared.

Test plan:

With the Android SDK, JDK 21, and Yarn v1 on the environment path:

./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest \
  --tests com.facebook.react.uimanager.BaseViewManagerTest \
  --tests com.facebook.react.views.textinput.ReactTextInputPropertyTest \
  --tests com.facebook.react.views.view.ReactViewGroupTest \
  -Preact.internal.useHermesStable=true --no-daemon --max-workers=2 \
  -Dorg.gradle.jvmargs='-Xmx2g -XX:MaxMetaspaceSize=768m' --console=plain

All 82 tests pass. The non-editable TextInput test fails on main and passes with this change. A ReactViewManager subclass test checks that subclasses inherit the reset.

The ReactAndroid.api lines were checked against the compiled classes with javap. No full Android build, emulator, or device test was run.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 1, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 1, 2026
@javache

javache commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Can we fix this on the Android side instead? The absence of the attributed should be treated as false.

@bigcupcoffee

Copy link
Copy Markdown
Contributor

Hey @javache, I opened a separate PR with a fix on Android side #58799 👀

@Marve10s

Marve10s commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Updated this PR with an Android-side fix and regression tests covering the text-input editability and partial-update issues reproduced in #58799.

meta-codesync Bot pushed a commit that referenced this pull request Oct 2, 2026
Summary:
JSI drops `undefined` keys, so reseting `disabled` from `true` to `undefined` on Touchables/Pressables never runs `setEnabled(true)`

There is props diffing feature flag that fixes this, which is off by default

Also added safety check against explicit `null` & reset on recycling

Fixes #56777 and supersedes #58795

## Changelog:

[ANDROID] [FIXED] - Properly enable Pressable after `disabled` prop resets from `true`

Pull Request resolved: #58799

Test Plan:
Added BaseViewManagerTest as well as videos of testing it on Pressable:

https://github.com/user-attachments/assets/e9a7dcd2-46d5-4cdc-88a3-728bff22e76b

https://github.com/user-attachments/assets/043150ae-64f2-47c9-b13c-abfec5b61747

Reviewed By: javache

Differential Revision: D122872380

Pulled By: zeyap

fbshipit-source-id: f3f1cad378f36f006bbb6c7f3f2e4f9aa8e61541
@Marve10s Marve10s changed the title Restore Android tap targets when disabled is cleared Keep Android disabled-state resets scoped to core views Oct 3, 2026
fabriziocucci added a commit that referenced this pull request Oct 5, 2026
Summary:
JSI drops `undefined` keys, so reseting `disabled` from `true` to `undefined` on Touchables/Pressables never runs `setEnabled(true)`

There is props diffing feature flag that fixes this, which is off by default

Also added safety check against explicit `null` & reset on recycling

Fixes #56777 and supersedes #58795

## Changelog:

[ANDROID] [FIXED] - Properly enable Pressable after `disabled` prop resets from `true`

Pull Request resolved: #58799

Test Plan:
Added BaseViewManagerTest as well as videos of testing it on Pressable:

https://github.com/user-attachments/assets/e9a7dcd2-46d5-4cdc-88a3-728bff22e76b

https://github.com/user-attachments/assets/043150ae-64f2-47c9-b13c-abfec5b61747

Reviewed By: javache

Differential Revision: D122872380

Pulled By: zeyap

fbshipit-source-id: f3f1cad378f36f006bbb6c7f3f2e4f9aa8e61541
(cherry picked from commit 357b699)

@javache javache left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Making resetDisabledFromAccessibilityState an instance method seems legit, but the class-based check isn't.

The default .isEnabled handling should stay in ReactViewManager - maybe pull the view.setTag(R.id.accessibility_state_disabled, null); into setViewState, so view managers don't need to call super? ReactTextInputManagerdoesn't derive fromReactViewManager` so wouldn't auto-derive this behaviour.

tvinhas pushed a commit to tvinhas/react-native-macos that referenced this pull request Oct 21, 2026
Summary:
JSI drops `undefined` keys, so reseting `disabled` from `true` to `undefined` on Touchables/Pressables never runs `setEnabled(true)`

There is props diffing feature flag that fixes this, which is off by default

Also added safety check against explicit `null` & reset on recycling

Fixes react#56777 and supersedes react#58795

## Changelog:

[ANDROID] [FIXED] - Properly enable Pressable after `disabled` prop resets from `true`

Pull Request resolved: react#58799

Test Plan:
Added BaseViewManagerTest as well as videos of testing it on Pressable:

https://github.com/user-attachments/assets/e9a7dcd2-46d5-4cdc-88a3-728bff22e76b

https://github.com/user-attachments/assets/043150ae-64f2-47c9-b13c-abfec5b61747

Reviewed By: javache

Differential Revision: D122872380

Pulled By: zeyap

fbshipit-source-id: f3f1cad378f36f006bbb6c7f3f2e4f9aa8e61541
(cherry picked from commit 357b699)
Clearing accessibilityState.disabled re-enabled every view whose
disabled state came from accessibility, so a TextInput with
editable={false} became editable again.

BaseViewManager now tracks and clears the accessibility disabled tag in
setViewState and calls the protected resetDisabledFromAccessibilityState
hook only when accessibility had disabled the view. The base hook does
nothing; ReactViewManager overrides it to re-enable the view, so core
views and their subclasses keep the Pressable fix while other managers
keep the enabled state they control.
@Marve10s
Marve10s force-pushed the fix/android-cleared-disabled-tap-target branch from da5578d to e0a9ab5 Compare November 3, 2026 11:35

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants