|
| 1 | +diff --git a/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js b/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js |
| 2 | +index 88d3cc8..8e60c9e 100644 |
| 3 | +--- a/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js |
| 4 | ++++ b/node_modules/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js |
| 5 | +@@ -97,6 +97,9 @@ const RCTTextInputViewConfig = { |
| 6 | + topChangeSync: { |
| 7 | + registrationName: 'onChangeSync', |
| 8 | + }, |
| 9 | ++ topClear: { |
| 10 | ++ registrationName: 'onClear', |
| 11 | ++ }, |
| 12 | + }, |
| 13 | + validAttributes: { |
| 14 | + fontSize: true, |
| 15 | +diff --git a/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts b/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts |
| 16 | +index 2c0c099..26a477f 100644 |
| 17 | +--- a/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts |
| 18 | ++++ b/node_modules/react-native/Libraries/Components/TextInput/TextInput.d.ts |
| 19 | +@@ -707,6 +707,13 @@ export interface TextInputProps |
| 20 | + | ((e: NativeSyntheticEvent<TextInputFocusEventData>) => void) |
| 21 | + | undefined; |
| 22 | + |
| 23 | ++ /** |
| 24 | ++ * Callback that is called when the text input was cleared using the native clear command. |
| 25 | ++ */ |
| 26 | ++ onClear?: |
| 27 | ++ | ((e: NativeSyntheticEvent<TextInputChangeEventData>) => void) |
| 28 | ++ | undefined; |
| 29 | ++ |
| 30 | + /** |
| 31 | + * Callback that is called when the text input's text changes. |
| 32 | + */ |
| 33 | +diff --git a/node_modules/react-native/Libraries/Components/TextInput/TextInput.js b/node_modules/react-native/Libraries/Components/TextInput/TextInput.js |
| 34 | +index 481938f..346acaa 100644 |
| 35 | +--- a/node_modules/react-native/Libraries/Components/TextInput/TextInput.js |
| 36 | ++++ b/node_modules/react-native/Libraries/Components/TextInput/TextInput.js |
| 37 | +@@ -1329,6 +1329,11 @@ function InternalTextInput(props: Props): React.Node { |
| 38 | + }); |
| 39 | + }; |
| 40 | + |
| 41 | ++ const _onClear = (event: ChangeEvent) => { |
| 42 | ++ setMostRecentEventCount(event.nativeEvent.eventCount); |
| 43 | ++ props.onClear && props.onClear(event); |
| 44 | ++ }; |
| 45 | ++ |
| 46 | + const _onFocus = (event: FocusEvent) => { |
| 47 | + TextInputState.focusInput(inputRef.current); |
| 48 | + if (props.onFocus) { |
| 49 | +@@ -1462,6 +1467,7 @@ function InternalTextInput(props: Props): React.Node { |
| 50 | + nativeID={id ?? props.nativeID} |
| 51 | + onBlur={_onBlur} |
| 52 | + onKeyPressSync={props.unstable_onKeyPressSync} |
| 53 | ++ onClear={_onClear} |
| 54 | + onChange={_onChange} |
| 55 | + onChangeSync={useOnChangeSync === true ? _onChangeSync : null} |
| 56 | + onContentSizeChange={props.onContentSizeChange} |
| 57 | +@@ -1516,6 +1522,7 @@ function InternalTextInput(props: Props): React.Node { |
| 58 | + nativeID={id ?? props.nativeID} |
| 59 | + numberOfLines={props.rows ?? props.numberOfLines} |
| 60 | + onBlur={_onBlur} |
| 61 | ++ onClear={_onClear} |
| 62 | + onChange={_onChange} |
| 63 | + onFocus={_onFocus} |
| 64 | + /* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match |
| 65 | +diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm |
| 66 | +index a19b555..4785987 100644 |
| 67 | +--- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm |
| 68 | ++++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm |
| 69 | +@@ -62,6 +62,7 @@ @implementation RCTBaseTextInputViewManager { |
| 70 | + |
| 71 | + RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) |
| 72 | + RCT_EXPORT_VIEW_PROPERTY(onKeyPressSync, RCTDirectEventBlock) |
| 73 | ++RCT_EXPORT_VIEW_PROPERTY(onClear, RCTDirectEventBlock) |
| 74 | + RCT_EXPORT_VIEW_PROPERTY(onChangeSync, RCTDirectEventBlock) |
| 75 | + RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) |
| 76 | + RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock) |
| 77 | +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm |
| 78 | +index 7ce04da..70754bf 100644 |
| 79 | +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm |
| 80 | ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm |
| 81 | +@@ -452,6 +452,19 @@ - (void)blur |
| 82 | + [_backedTextInputView resignFirstResponder]; |
| 83 | + } |
| 84 | + |
| 85 | ++- (void)clear |
| 86 | ++{ |
| 87 | ++ auto metrics = [self _textInputMetrics]; |
| 88 | ++ [self setTextAndSelection:_mostRecentEventCount value:@"" start:0 end:0]; |
| 89 | ++ |
| 90 | ++ _mostRecentEventCount++; |
| 91 | ++ metrics.eventCount = _mostRecentEventCount; |
| 92 | ++ |
| 93 | ++ // Notify JS that the event counter has changed |
| 94 | ++ const auto &textInputEventEmitter = static_cast<const TextInputEventEmitter &>(*_eventEmitter); |
| 95 | ++ textInputEventEmitter.onClear(metrics); |
| 96 | ++} |
| 97 | ++ |
| 98 | + - (void)setTextAndSelection:(NSInteger)eventCount |
| 99 | + value:(NSString *__nullable)value |
| 100 | + start:(NSInteger)start |
| 101 | +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h |
| 102 | +index fe3376a..6889eed 100644 |
| 103 | +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h |
| 104 | ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h |
| 105 | +@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN |
| 106 | + @protocol RCTTextInputViewProtocol <NSObject> |
| 107 | + - (void)focus; |
| 108 | + - (void)blur; |
| 109 | ++- (void)clear; |
| 110 | + - (void)setTextAndSelection:(NSInteger)eventCount |
| 111 | + value:(NSString *__nullable)value |
| 112 | + start:(NSInteger)start |
| 113 | +@@ -49,6 +50,19 @@ RCTTextInputHandleCommand(id<RCTTextInputViewProtocol> componentView, const NSSt |
| 114 | + return; |
| 115 | + } |
| 116 | + |
| 117 | ++ if ([commandName isEqualToString:@"clear"]) { |
| 118 | ++#if RCT_DEBUG |
| 119 | ++ if ([args count] != 0) { |
| 120 | ++ RCTLogError( |
| 121 | ++ @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); |
| 122 | ++ return; |
| 123 | ++ } |
| 124 | ++#endif |
| 125 | ++ |
| 126 | ++ [componentView clear]; |
| 127 | ++ return; |
| 128 | ++ } |
| 129 | ++ |
| 130 | + if ([commandName isEqualToString:@"setTextAndSelection"]) { |
| 131 | + #if RCT_DEBUG |
| 132 | + if ([args count] != 4) { |
| 133 | +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextClearEvent.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextClearEvent.java |
| 134 | +new file mode 100644 |
| 135 | +index 0000000..0c142a0 |
| 136 | +--- /dev/null |
| 137 | ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextClearEvent.java |
| 138 | +@@ -0,0 +1,53 @@ |
| 139 | ++/* |
| 140 | ++ * Copyright (c) Meta Platforms, Inc. and affiliates. |
| 141 | ++ * |
| 142 | ++ * This source code is licensed under the MIT license found in the |
| 143 | ++ * LICENSE file in the root directory of this source tree. |
| 144 | ++ */ |
| 145 | ++ |
| 146 | ++package com.facebook.react.views.textinput; |
| 147 | ++ |
| 148 | ++import androidx.annotation.Nullable; |
| 149 | ++ |
| 150 | ++import com.facebook.react.bridge.Arguments; |
| 151 | ++import com.facebook.react.bridge.WritableMap; |
| 152 | ++import com.facebook.react.uimanager.common.ViewUtil; |
| 153 | ++import com.facebook.react.uimanager.events.Event; |
| 154 | ++ |
| 155 | ++/** |
| 156 | ++ * Event emitted by EditText native view when text changes. VisibleForTesting from {@link |
| 157 | ++ * TextInputEventsTestCase}. |
| 158 | ++ */ |
| 159 | ++public class ReactTextClearEvent extends Event<ReactTextClearEvent> { |
| 160 | ++ |
| 161 | ++ public static final String EVENT_NAME = "topClear"; |
| 162 | ++ |
| 163 | ++ private String mText; |
| 164 | ++ private int mEventCount; |
| 165 | ++ |
| 166 | ++ @Deprecated |
| 167 | ++ public ReactTextClearEvent(int viewId, String text, int eventCount) { |
| 168 | ++ this(ViewUtil.NO_SURFACE_ID, viewId, text, eventCount); |
| 169 | ++ } |
| 170 | ++ |
| 171 | ++ public ReactTextClearEvent(int surfaceId, int viewId, String text, int eventCount) { |
| 172 | ++ super(surfaceId, viewId); |
| 173 | ++ mText = text; |
| 174 | ++ mEventCount = eventCount; |
| 175 | ++ } |
| 176 | ++ |
| 177 | ++ @Override |
| 178 | ++ public String getEventName() { |
| 179 | ++ return EVENT_NAME; |
| 180 | ++ } |
| 181 | ++ |
| 182 | ++ @Nullable |
| 183 | ++ @Override |
| 184 | ++ protected WritableMap getEventData() { |
| 185 | ++ WritableMap eventData = Arguments.createMap(); |
| 186 | ++ eventData.putString("text", mText); |
| 187 | ++ eventData.putInt("eventCount", mEventCount); |
| 188 | ++ eventData.putInt("target", getViewTag()); |
| 189 | ++ return eventData; |
| 190 | ++ } |
| 191 | ++} |
| 192 | +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java |
| 193 | +index 8496a7d..53e5c49 100644 |
| 194 | +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java |
| 195 | ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java |
| 196 | +@@ -8,6 +8,7 @@ |
| 197 | + package com.facebook.react.views.textinput; |
| 198 | + |
| 199 | + import static com.facebook.react.uimanager.UIManagerHelper.getReactContext; |
| 200 | ++import static com.facebook.react.uimanager.UIManagerHelper.getSurfaceId; |
| 201 | + |
| 202 | + import android.content.Context; |
| 203 | + import android.content.res.ColorStateList; |
| 204 | +@@ -273,6 +274,9 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout |
| 205 | + .put( |
| 206 | + ScrollEventType.getJSEventName(ScrollEventType.SCROLL), |
| 207 | + MapBuilder.of("registrationName", "onScroll")) |
| 208 | ++ .put( |
| 209 | ++ ReactTextClearEvent.EVENT_NAME, |
| 210 | ++ MapBuilder.of("registrationName", "onClear")) |
| 211 | + .build()); |
| 212 | + return eventTypeConstants; |
| 213 | + } |
| 214 | +@@ -330,6 +334,27 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout |
| 215 | + reactEditText.maybeSetTextFromJS(getReactTextUpdate(text, mostRecentEventCount)); |
| 216 | + } |
| 217 | + reactEditText.maybeSetSelection(mostRecentEventCount, start, end); |
| 218 | ++ break; |
| 219 | ++ case "clear": |
| 220 | ++ // Capture the current text |
| 221 | ++ Editable text = reactEditText.getText(); |
| 222 | ++ |
| 223 | ++ // Reset the edit text |
| 224 | ++ ReactTextUpdate textUpdate = getReactTextUpdate("", reactEditText.incrementAndGetEventCounter()); |
| 225 | ++ reactEditText.maybeSetTextFromJS(textUpdate); |
| 226 | ++ reactEditText.maybeSetSelection(reactEditText.incrementAndGetEventCounter(), 0, 0); |
| 227 | ++ |
| 228 | ++ // Dispatch the clear event |
| 229 | ++ EventDispatcher eventDispatcher = getEventDispatcher(getReactContext(reactEditText), reactEditText); |
| 230 | ++ eventDispatcher.dispatchEvent( |
| 231 | ++ new ReactTextClearEvent( |
| 232 | ++ getSurfaceId(reactEditText), |
| 233 | ++ reactEditText.getId(), |
| 234 | ++ text.toString(), |
| 235 | ++ reactEditText.incrementAndGetEventCounter() |
| 236 | ++ ) |
| 237 | ++ ); |
| 238 | ++ |
| 239 | + break; |
| 240 | + } |
| 241 | + } |
| 242 | +diff --git a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp |
| 243 | +index 497569a..1c10b11 100644 |
| 244 | +--- a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp |
| 245 | ++++ b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.cpp |
| 246 | +@@ -134,6 +134,11 @@ void TextInputEventEmitter::onBlur( |
| 247 | + dispatchTextInputEvent("blur", textInputMetrics); |
| 248 | + } |
| 249 | + |
| 250 | ++void TextInputEventEmitter::onClear( |
| 251 | ++ const TextInputMetrics& textInputMetrics) const { |
| 252 | ++ dispatchTextInputEvent("clear", textInputMetrics); |
| 253 | ++} |
| 254 | ++ |
| 255 | + void TextInputEventEmitter::onChange( |
| 256 | + const TextInputMetrics& textInputMetrics) const { |
| 257 | + dispatchTextInputEvent("change", textInputMetrics); |
| 258 | +diff --git a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h |
| 259 | +index 0ab2b18..bc5e624 100644 |
| 260 | +--- a/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h |
| 261 | ++++ b/node_modules/react-native/ReactCommon/react/renderer/components/textinput/iostextinput/react/renderer/components/iostextinput/TextInputEventEmitter.h |
| 262 | +@@ -38,6 +38,7 @@ class TextInputEventEmitter : public ViewEventEmitter { |
| 263 | + |
| 264 | + void onFocus(const TextInputMetrics& textInputMetrics) const; |
| 265 | + void onBlur(const TextInputMetrics& textInputMetrics) const; |
| 266 | ++ void onClear(const TextInputMetrics& textInputMetrics) const; |
| 267 | + void onChange(const TextInputMetrics& textInputMetrics) const; |
| 268 | + void onChangeSync(const TextInputMetrics& textInputMetrics) const; |
| 269 | + void onContentSizeChange(const TextInputMetrics& textInputMetrics) const; |
0 commit comments