Skip to content

Commit d5e7b02

Browse files
alanleedevfacebook-github-bot
authored andcommitted
Add selection to TextInput onChange event (native) (facebook#55044)
Summary: This change adds `selection` data to the `TextInput.onChange` event for both iOS and Android platforms. NOTE: `selection` only represents the cursor location when returned via `onChange` as this will not be invoked on a pure selection change without text change. We should also add this note to the documentation. ## Why On the web, text input elements provide `selectionStart` and `selectionEnd` properties that are always accessible during input events. React Native's `onChange` event previously included `selection` on iOS (Fabric), but this was removed in PR [facebook#51051](facebook#51051) to unify with Android (which never had it). This change restores and extends this capability to both platforms, better aligning React Native with web standards. This is also to support pollyfill added in `react-strict-dom`; facebook/react-strict-dom#435 ## What Changed 1. **iOS/macOS (C++)**: Enable selection in `onChange` event via `TextInputEventEmitter` 2. **Android (Kotlin)**: Added selection data to `ReactTextChangedEvent` Changelog: [General][Added] - TextInput onChange event now includes selection data (cursor location) on iOS and Android Reviewed By: cipolleschi, javache Differential Revision: D90123295
1 parent dcfe7f5 commit d5e7b02

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ internal class ReactTextChangedEvent(
1717
viewId: Int,
1818
private val text: String,
1919
private val eventCount: Int,
20+
private val selectionStart: Int,
21+
private val selectionEnd: Int,
2022
) : Event<ReactTextChangedEvent>(surfaceId, viewId) {
2123
override fun getEventName(): String = EVENT_NAME
2224

@@ -25,6 +27,12 @@ internal class ReactTextChangedEvent(
2527
putString("text", text)
2628
putInt("eventCount", eventCount)
2729
putInt("target", viewTag)
30+
val selectionData =
31+
Arguments.createMap().apply {
32+
putInt("start", selectionStart)
33+
putInt("end", selectionEnd)
34+
}
35+
putMap("selection", selectionData)
2836
}
2937
}
3038

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputTextWatcher.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ internal class ReactTextInputTextWatcher(
6363
editText.id,
6464
s.toString(),
6565
editText.incrementAndGetEventCounter(),
66+
editText.selectionStart,
67+
editText.selectionEnd,
6668
)
6769
)
6870
}

packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ void TextInputEventEmitter::onBlur(const Metrics& textInputMetrics) const {
140140
}
141141

142142
void TextInputEventEmitter::onChange(const Metrics& textInputMetrics) const {
143-
dispatchTextInputEvent("change", textInputMetrics);
143+
dispatchTextInputEvent(
144+
"change", textInputMetrics, /* includeSelectionState */ true);
144145
}
145146

146147
void TextInputEventEmitter::onContentSizeChange(

0 commit comments

Comments
 (0)