fix(android): preserve cursor position when centered TextInput is cleared#56615
Open
HarshitMadhav wants to merge 1 commit intofacebook:mainfrom
Open
fix(android): preserve cursor position when centered TextInput is cleared#56615HarshitMadhav wants to merge 1 commit intofacebook:mainfrom
HarshitMadhav wants to merge 1 commit intofacebook:mainfrom
Conversation
6486b7d to
d352c57
Compare
…ared On Android, clearing a TextInput with `textAlign: "center"` caused the cursor to jump to the right edge of the field instead of staying centered. The cause was `setText(null)` in `ReactEditText.maybeSetText`, which replaces the underlying `Editable` buffer; recreating the buffer loses the gravity-based caret positioning that `Gravity.CENTER_HORIZONTAL` relies on. Instead of swapping the buffer, remove any composing spans from the existing `Editable` (preserving the original "buggy keyboards don't clear composing text" intent) and clear its contents in place via `Editable.replace(...)`. This mirrors the approach already used by the non-empty branch a few lines below and keeps gravity-based positioning intact, so the cursor stays centered (or right-aligned for RTL/right gravity) after clearing. Adds a Robolectric regression test in `ReactTextInputPropertyTest` that asserts the underlying `Editable` instance is preserved across a clear (the discriminating behavioral difference vs. `setText(null)`). The test was verified to fail against the original buggy code and pass against the fix. Fixes facebook#55457.
d352c57 to
712bf0b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
On Android, clearing a
TextInputwithtextAlign: "center"caused the cursor to jump to the right edge of the field instead of staying centered. iOS was not affected. See #55457 for a video reproduction.The cause is
setText(null)inReactEditText.maybeSetText. OnAppCompatEditText, that call replaces the underlyingEditablebuffer with a freshly constructed one, and the new buffer doesn't carry forward the gravity-based caret positioning thatGravity.CENTER_HORIZONTALrelies on. The cursor then snaps to the layout's natural edge — the right side for LTR centered text — until the user taps the field again.This PR fixes the issue by clearing the text in place on the existing
Editablerather than swapping the buffer:BaseInputConnection.removeComposingSpans(currentText)— preserves the original "some buggy keyboards don't clear the composing text on their own" intent that motivated the originalsetText(null).currentText.replace(0, currentText.length, "")— empties the buffer without re-creating it.This mirrors the approach already used a few lines below for the non-empty branch (
checkNotNull(text).replace(0, length(), spannableStringBuilder)), so the empty-text path is now consistent with the non-empty path. Gravity is preserved on the sameEditable, so the cursor stays centered (or right-aligned for RTL) after clearing.Fixes #55457.
Changelog:
[ANDROID] [FIXED] - Cursor no longer jumps to the right edge when a centered
TextInputis clearedTest Plan:
Added a Robolectric regression test
ReactTextInputPropertyTest.testClearingTextPreservesEditableBufferAndGravitythat:textAlign: "center"and asserts gravity isGravity.CENTER_HORIZONTAL."hello"viaReactTextUpdateand capturesview.editableTextasbufferBeforeClear.ReactTextUpdatewith an empty string.view.editableTextis the same instance asbufferBeforeClear— this is the discriminating behavioral guarantee of the fix vs.setText(null), which would replace the buffer.selectionStart/selectionEndare both0.The test is a true regression test:
text = nullcode withExpecting actual: hello and actual: "" to refer to the same object.Ran:
Result:
All 22 pre-existing tests in the class continue to pass, so no behavior is regressed by the fix.