diff --git a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js index 8438a0eac100c1..5b3d3dbdf7f0ab 100644 --- a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js +++ b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js @@ -29,6 +29,7 @@ type TextInputChangeEventData = $ReadOnly<{ eventCount: number, target: number, text: string, + selection?: Selection, }>; export type TextInputChangeEvent = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.kt index b4e4a7caad87f8..f4c0daabb00071 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.kt @@ -17,6 +17,8 @@ internal class ReactTextChangedEvent( viewId: Int, private val text: String, private val eventCount: Int, + private val selectionStart: Int, + private val selectionEnd: Int, ) : Event(surfaceId, viewId) { override fun getEventName(): String = EVENT_NAME @@ -25,6 +27,12 @@ internal class ReactTextChangedEvent( putString("text", text) putInt("eventCount", eventCount) putInt("target", viewTag) + val selectionData = + Arguments.createMap().apply { + putInt("start", selectionStart) + putInt("end", selectionEnd) + } + putMap("selection", selectionData) } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputTextWatcher.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputTextWatcher.kt index 887251ccbbce8f..e6e13a00955a57 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputTextWatcher.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputTextWatcher.kt @@ -63,6 +63,8 @@ internal class ReactTextInputTextWatcher( editText.id, s.toString(), editText.incrementAndGetEventCounter(), + editText.selectionStart, + editText.selectionEnd, ) ) } diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp index a9bc219f8bf729..909c4521bc9310 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp @@ -140,7 +140,7 @@ void TextInputEventEmitter::onBlur(const Metrics& textInputMetrics) const { } void TextInputEventEmitter::onChange(const Metrics& textInputMetrics) const { - dispatchTextInputEvent("change", textInputMetrics); + dispatchTextInputEvent("change", textInputMetrics, true); } void TextInputEventEmitter::onContentSizeChange( diff --git a/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts index 1663252c3ed27f..cca5cb350aee78 100644 --- a/packages/react-native/ReactNativeApi.d.ts +++ b/packages/react-native/ReactNativeApi.d.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<249ca589a73aaef41a965bcf3a2c0208>> * * This file was generated by scripts/js-api/build-types/index.js. */ @@ -5277,6 +5277,7 @@ declare type TextInputChangeEvent = NativeSyntheticEvent declare type TextInputChangeEventData = { readonly eventCount: number + readonly selection?: Selection readonly target: number readonly text: string } @@ -6189,15 +6190,15 @@ export { TaskProvider, // 266dedf2 Text, // e55ac2e2 TextContentType, // 239b3ecc - TextInput, // cf7a3331 + TextInput, // 2e89b91d TextInputAndroidProps, // 3f09ce49 - TextInputChangeEvent, // 380cbe93 + TextInputChangeEvent, // 6821f629 TextInputContentSizeChangeEvent, // 5fba3f54 TextInputEndEditingEvent, // 8c22fac3 TextInputFocusEvent, // c36e977c TextInputIOSProps, // 0d05a855 TextInputKeyPressEvent, // 967178c2 - TextInputProps, // a817a7f7 + TextInputProps, // c75f0362 TextInputSelectionChangeEvent, // a1a7622f TextInputSubmitEditingEvent, // 48d903af TextLayoutEvent, // 45b0a8d7 diff --git a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js index 2de5275b9dd290..2e789412f981ef 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js @@ -393,7 +393,14 @@ class TextEventsExample extends React.Component<{...}, $FlowFixMe> { onFocus={() => this.updateText('onFocus')} onBlur={() => this.updateText('onBlur')} onChange={event => - this.updateText('onChange text: ' + event.nativeEvent.text) + this.updateText( + 'onChange text: ' + + event.nativeEvent.text + + ', selection: ' + + (event.nativeEvent.selection != null + ? JSON.stringify(event.nativeEvent.selection) + : 'undefined'), + ) } onContentSizeChange={event => this.updateText(