Skip to content

fix: report correct selection in Android onChange event during autofill#57460

Open
nsbarsukov wants to merge 1 commit into
react:mainfrom
nsbarsukov:fix/android-autofill-onchange-selection
Open

fix: report correct selection in Android onChange event during autofill#57460
nsbarsukov wants to merge 1 commit into
react:mainfrom
nsbarsukov:fix/android-autofill-onchange-selection

Conversation

@nsbarsukov

Copy link
Copy Markdown
Contributor

Summary:

On Android, filling a TextInput via platform autofill emits an onChange event whose nativeEvent.selection is {start: 0, end: 0} regardless of the inserted text length, while the same value inserted by pasting (and both paste and autofill on iOS) correctly reports the selection at the end of the inserted text.

The root cause is in the Android framework's autofill flow: TextView.autofill() first calls setText(), which notifies the TextWatchers — where ReactTextInputTextWatcher reads the selection for the topChange event — while the cursor still sits at its pre-autofill position, and only afterwards moves the cursor to the end of the new text. Paste is unaffected because clipboard insertion goes through Editable.replace(), which repositions the cursor before the watchers run.

This change tracks the in-progress autofill on ReactEditText (via an autofill() override setting an isBeingAutofilled flag) and, while it is set, reports the selection at the end of the new text — matching where the framework places the cursor immediately after.

Fixes #57458

Changelog:

[ANDROID] [FIXED] - TextInput onChange event reports stale selection ({start: 0, end: 0}) when text is inserted via platform autofill

Test Plan:

Added ReactTextInputTextWatcherTest (Robolectric), which drives the real framework View.autofill() path and asserts on the dispatched ReactTextChangedEvent payload:

  • testAutofillReportsSelectionAtEndOfText — autofills +15551234567 and asserts the event carries text: "+15551234567" and selection: {start: 12, end: 12}. Without the fix this test fails with selection: {start: 0, end: 0}, reproducing the exact bug from the issue.
  • testTextInsertedAtCursorReportsSelectionAfterInsertedText — regression-guards the paste/typing path (insertion at the cursor via Editable.insert()), which was already correct.
./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests "com.facebook.react.views.textinput.*"

ReactTextInputTextWatcherTest > testAutofillReportsSelectionAtEndOfText PASSED
ReactTextInputTextWatcherTest > testTextInsertedAtCursorReportsSelectionAfterInsertedText PASSED
ReactTextInputPropertyTest > (23 tests) PASSED

BUILD SUCCESSFUL

On Android, filling a TextInput via platform autofill emitted an
onChange event whose nativeEvent.selection was {start: 0, end: 0}
regardless of the inserted text length.

TextView.autofill() first calls setText(), which notifies the
TextWatchers (where ReactTextInputTextWatcher reads the selection for
the topChange event) while the cursor still sits at its pre-autofill
position, and only afterwards moves the cursor to the end of the new
text. Track the in-progress autofill on ReactEditText and report the
selection at the end of the new text, matching where the framework
places the cursor immediately after.

Fixes react#57458
@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 Jul 7, 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 Jul 7, 2026
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.

TextInput emits onChange event with invalid selection on Android browser autofill

1 participant