diff --git a/packages/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js b/packages/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js index 734b37d3dc3644..ef6296d1c81006 100644 --- a/packages/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +++ b/packages/react-native/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js @@ -658,6 +658,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { }, }, validAttributes: { + acceptDragAndDropTypes: true, maxFontSizeMultiplier: true, adjustsFontSizeToFit: true, minimumFontScale: true, diff --git a/packages/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js b/packages/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js index 00b31ddbb8bb26..7573b681622d14 100644 --- a/packages/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js +++ b/packages/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js @@ -90,6 +90,7 @@ const RCTTextInputViewConfig = { }, }, validAttributes: { + acceptDragAndDropTypes: true, dynamicTypeRamp: true, fontSize: true, fontWeight: true, diff --git a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js index b273341b328ee2..3db6ec5692e138 100644 --- a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js +++ b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js @@ -514,6 +514,26 @@ export type TextInputAndroidProps = $ReadOnly<{ }>; type TextInputBaseProps = $ReadOnly<{ + /** + * When provided, the text input will only accept drag and drop events for the specified + * types. If null or not provided, the text input will accept all types of drag and drop events. + * An empty array will accept no drag and drop events. + * Defaults to null. + * + * On Android, types must correspond to MIME types from ClipData: + * https://developer.android.com/reference/android/content/ClipData + * (e.g. "text/plain" or "image/*") + * + * On iOS, types must correspond to UTIs: + * https://developer.apple.com/documentation/uniformtypeidentifiers + * (e.g. "public.plain-text" or "public.image") + * + * *NOTE*: This prop is experimental and its API may change in the future. Use at your own risk. + * + * @see https://developer.android.com/reference/android/content/ClipData for more information on MIME types + */ + experimental_acceptDragAndDropTypes?: ?$ReadOnlyArray, + /** * Can tell `TextInput` to automatically capitalize certain characters. * diff --git a/packages/react-native/Libraries/Components/TextInput/TextInput.js b/packages/react-native/Libraries/Components/TextInput/TextInput.js index b56c388d88c9b4..9cf46b2f6985ff 100644 --- a/packages/react-native/Libraries/Components/TextInput/TextInput.js +++ b/packages/react-native/Libraries/Components/TextInput/TextInput.js @@ -675,6 +675,7 @@ function InternalTextInput(props: TextInputProps): React.Node { ref={(ref: $FlowFixMe)} {...otherProps} {...eventHandlers} + acceptDragAndDropTypes={props.experimental_acceptDragAndDropTypes} accessibilityState={_accessibilityState} accessible={accessible} submitBehavior={submitBehavior} @@ -741,6 +742,7 @@ function InternalTextInput(props: TextInputProps): React.Node { accessibilityState={_accessibilityState} accessibilityLabelledBy={_accessibilityLabelledBy} accessible={accessible} + acceptDragAndDropTypes={props.experimental_acceptDragAndDropTypes} autoCapitalize={autoCapitalize} submitBehavior={submitBehavior} caretHidden={caretHidden} diff --git a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm index 565b0f6afb607e..6e9c3841cee196 100644 --- a/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm +++ b/packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm @@ -20,6 +20,7 @@ @implementation RCTUITextView { NSDictionary *_defaultTextAttributes; NSArray *_initialValueLeadingBarButtonGroups; NSArray *_initialValueTrailingBarButtonGroups; + NSArray *_acceptDragAndDropTypes; } static UIFont *defaultPlaceholderFont(void) @@ -102,6 +103,16 @@ - (NSString *)accessibilityLabel #pragma mark - Properties +- (void)setAcceptDragAndDropTypes:(NSArray *)acceptDragAndDropTypes +{ + _acceptDragAndDropTypes = acceptDragAndDropTypes; +} + +- (nullable NSArray *)acceptDragAndDropTypes +{ + return _acceptDragAndDropTypes; +} + - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm index ac8e464fc2dce8..82d9a79af7345f 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm +++ b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.mm @@ -11,7 +11,7 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingContext; -@interface RCTBackedTextFieldDelegateAdapter () +@interface RCTBackedTextFieldDelegateAdapter () @end @implementation RCTBackedTextFieldDelegateAdapter { @@ -25,6 +25,7 @@ - (instancetype)initWithTextField:(UITextField * if (self = [super init]) { _backedTextInputView = backedTextInputView; backedTextInputView.delegate = self; + backedTextInputView.textDropDelegate = self; [_backedTextInputView addTarget:self action:@selector(textFieldDidChange) @@ -159,11 +160,47 @@ - (void)textFieldProbablyDidChangeSelection [_backedTextInputView.textInputDelegate textInputDidChangeSelection]; } +#pragma mark - UITextDropDelegate + +- (UITextDropEditability)textDroppableView:(UIView *)textDroppableView + willBecomeEditableForDrop:(id)drop +{ + if (!_backedTextInputView.enabled) { + return UITextDropEditabilityNo; + } + if ([self _shouldAcceptDrop:drop]) { + return UITextDropEditabilityYes; + } else { + return UITextDropEditabilityNo; + } +} + +- (UITextDropProposal *)textDroppableView:(UIView *)textDroppableView + proposalForDrop:(id)drop +{ + if ([self _shouldAcceptDrop:drop]) { + return drop.suggestedProposal; + } else { + return [[UITextDropProposal alloc] initWithDropOperation:UIDropOperationCancel]; + } +} + +- (bool)_shouldAcceptDrop:(id)drop +{ + if (_backedTextInputView.acceptDragAndDropTypes) { + // If we have accepted types, we should only accept drops that match one of them + return [drop.dropSession hasItemsConformingToTypeIdentifiers:_backedTextInputView.acceptDragAndDropTypes]; + } else { + // If we don't have any accepted types, we should accept any drop + return true; + } +} + @end #pragma mark - RCTBackedTextViewDelegateAdapter (for UITextView) -@interface RCTBackedTextViewDelegateAdapter () +@interface RCTBackedTextViewDelegateAdapter () @end @implementation RCTBackedTextViewDelegateAdapter { @@ -179,6 +216,7 @@ - (instancetype)initWithTextView:(UITextView *)b if (self = [super init]) { _backedTextInputView = backedTextInputView; backedTextInputView.delegate = self; + backedTextInputView.textDropDelegate = self; } return self; @@ -304,4 +342,40 @@ - (void)textViewProbablyDidChangeSelection [_backedTextInputView.textInputDelegate textInputDidChangeSelection]; } +#pragma mark - UITextDropDelegate + +- (UITextDropEditability)textDroppableView:(UIView *)textDroppableView + willBecomeEditableForDrop:(id)drop +{ + if (!_backedTextInputView.isEditable) { + return UITextDropEditabilityNo; + } + if ([self _shouldAcceptDrop:drop]) { + return UITextDropEditabilityYes; + } else { + return UITextDropEditabilityNo; + } +} + +- (UITextDropProposal *)textDroppableView:(UIView *)textDroppableView + proposalForDrop:(id)drop +{ + if ([self _shouldAcceptDrop:drop]) { + return drop.suggestedProposal; + } else { + return [[UITextDropProposal alloc] initWithDropOperation:UIDropOperationCancel]; + } +} + +- (bool)_shouldAcceptDrop:(id)drop +{ + if (_backedTextInputView.acceptDragAndDropTypes) { + // If we have accepted types, we should only accept drops that match one of them + return [drop.dropSession hasItemsConformingToTypeIdentifiers:(_backedTextInputView.acceptDragAndDropTypes)]; + } else { + // If we don't have any accepted types, we should accept any drop + return true; + } +} + @end diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index d2cec7f1bfbdcb..b67beb956481ab 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -38,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, readonly) CGPoint contentOffset; @property (nonatomic, assign, readonly) UIEdgeInsets contentInset; @property (nullable, nonatomic, copy) NSDictionary *typingAttributes; +@property (nonatomic, strong, nullable) NSArray *acceptDragAndDropTypes; // This protocol disallows direct access to `selectedTextRange` property because // unwise usage of it can break the `delegate` behavior. So, we always have to diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm index dd3969933904eb..47adc535400fad 100644 --- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm +++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.mm @@ -48,6 +48,7 @@ @implementation RCTBaseTextInputViewManager { RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL) RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) RCT_REMAP_VIEW_PROPERTY(smartInsertDelete, backedTextInputView.smartInsertDeleteType, UITextSmartInsertDeleteType) + RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(submitBehavior, NSString) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) @@ -60,6 +61,9 @@ @implementation RCTBaseTextInputViewManager { RCT_EXPORT_VIEW_PROPERTY(inputAccessoryViewButtonLabel, NSString) RCT_EXPORT_VIEW_PROPERTY(textContentType, NSString) RCT_EXPORT_VIEW_PROPERTY(passwordRules, NSString) +RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) +RCT_EXPORT_VIEW_PROPERTY(disableKeyboardShortcuts, BOOL) +RCT_EXPORT_VIEW_PROPERTY(acceptDragAndDropTypes, NSArray) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onKeyPressSync, RCTDirectEventBlock) @@ -67,10 +71,6 @@ @implementation RCTBaseTextInputViewManager { RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) - -RCT_EXPORT_VIEW_PROPERTY(disableKeyboardShortcuts, BOOL) - RCT_EXPORT_SHADOW_PROPERTY(text, NSString) RCT_EXPORT_SHADOW_PROPERTY(placeholder, NSString) RCT_EXPORT_SHADOW_PROPERTY(onContentSizeChange, RCTDirectEventBlock) diff --git a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm index d1bcd88a988759..377f41e41828ec 100644 --- a/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm +++ b/packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.mm @@ -17,6 +17,7 @@ @implementation RCTUITextField { NSDictionary *_defaultTextAttributes; NSArray *_initialValueLeadingBarButtonGroups; NSArray *_initialValueTrailingBarButtonGroups; + NSArray *_acceptDragAndDropTypes; } // This should not be needed but internal build were failing without it. @@ -57,6 +58,16 @@ - (void)setIsAccessibilityElement:(BOOL)isAccessibilityElement #pragma mark - Properties +- (void)setAcceptDragAndDropTypes:(NSArray *)acceptDragAndDropTypes +{ + _acceptDragAndDropTypes = acceptDragAndDropTypes; +} + +- (nullable NSArray *)acceptDragAndDropTypes +{ + return _acceptDragAndDropTypes; +} + - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset { _textContainerInset = textContainerInset; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index d64601d1560022..9d91aebc889d81 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -2851,6 +2851,7 @@ export type TextInputAndroidProps = $ReadOnly<{ underlineColorAndroid?: ?ColorValue, }>; type TextInputBaseProps = $ReadOnly<{ + experimental_acceptDragAndDropTypes?: ?$ReadOnlyArray, autoCapitalize?: ?AutoCapitalize, autoComplete?: ?( | \\"additional-name\\" diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 1de73336ff6df0..b5d724226fbe93 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -29,7 +29,10 @@ using namespace facebook::react; -@interface RCTTextInputComponentView () +@interface RCTTextInputComponentView () < + RCTBackedTextInputDelegate, + RCTTextInputViewProtocol, + UIDropInteractionDelegate> @end static NSSet *returnKeyTypesSet; @@ -307,6 +310,19 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & _backedTextInputView.disableKeyboardShortcuts = newTextInputProps.disableKeyboardShortcuts; } + if (newTextInputProps.acceptDragAndDropTypes != oldTextInputProps.acceptDragAndDropTypes) { + if (!newTextInputProps.acceptDragAndDropTypes.has_value()) { + _backedTextInputView.acceptDragAndDropTypes = nil; + } else { + auto &vector = newTextInputProps.acceptDragAndDropTypes.value(); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:vector.size()]; + for (const std::string &str : vector) { + [array addObject:[NSString stringWithUTF8String:str.c_str()]]; + } + _backedTextInputView.acceptDragAndDropTypes = array; + } + } + [super updateProps:props oldProps:oldProps]; [self setDefaultInputAccessoryView]; diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm index fb7d5ca1c17cb8..92467e2953f0cb 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm @@ -46,6 +46,7 @@ void RCTCopyBackedTextInput( toTextInput.smartInsertDeleteType = fromTextInput.smartInsertDeleteType; toTextInput.passwordRules = fromTextInput.passwordRules; toTextInput.disableKeyboardShortcuts = fromTextInput.disableKeyboardShortcuts; + toTextInput.acceptDragAndDropTypes = fromTextInput.acceptDragAndDropTypes; [toTextInput setSelectedTextRange:fromTextInput.selectedTextRange notifyDelegate:NO]; } diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 67a6a658e336ed..dd7804c781f99d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6650,6 +6650,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp public final fun getBorderColor (I)I protected final fun getContainsImages ()Z public final fun getDisableFullscreenUI ()Z + public final fun getDragAndDropFilter ()Ljava/util/List; protected final fun getNativeEventCount ()I public final fun getReturnKeyType ()Ljava/lang/String; public final fun getStagedInputType ()I @@ -6669,6 +6670,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp public fun onConfigurationChanged (Landroid/content/res/Configuration;)V public fun onCreateInputConnection (Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection; public fun onDetachedFromWindow ()V + public fun onDragEvent (Landroid/view/DragEvent;)Z public fun onDraw (Landroid/graphics/Canvas;)V public fun onFinishTemporaryDetach ()V protected fun onFocusChanged (ZILandroid/graphics/Rect;)V @@ -6694,6 +6696,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp public final fun setContentSizeWatcher (Lcom/facebook/react/views/textinput/ContentSizeWatcher;)V public final fun setContextMenuHidden (Z)V public final fun setDisableFullscreenUI (Z)V + public final fun setDragAndDropFilter (Ljava/util/List;)V public final fun setEventDispatcher (Lcom/facebook/react/uimanager/events/EventDispatcher;)V public final fun setFontFamily (Ljava/lang/String;)V public fun setFontFeatureSettings (Ljava/lang/String;)V @@ -6757,6 +6760,7 @@ public class com/facebook/react/views/textinput/ReactTextInputManager : com/face public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun receiveCommand (Lcom/facebook/react/views/textinput/ReactEditText;ILcom/facebook/react/bridge/ReadableArray;)V public fun receiveCommand (Lcom/facebook/react/views/textinput/ReactEditText;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V + public final fun setAcceptDragAndDropTypes (Lcom/facebook/react/views/textinput/ReactEditText;Lcom/facebook/react/bridge/ReadableArray;)V public final fun setAllowFontScaling (Lcom/facebook/react/views/textinput/ReactEditText;Z)V public final fun setAutoCapitalize (Lcom/facebook/react/views/textinput/ReactEditText;Lcom/facebook/react/bridge/Dynamic;)V public final fun setAutoCorrect (Lcom/facebook/react/views/textinput/ReactEditText;Ljava/lang/Boolean;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt index 3c9e4cbba28dc1..2936dd005c8c2a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt @@ -28,6 +28,7 @@ import android.text.method.KeyListener import android.text.method.QwertyKeyListener import android.util.TypedValue import android.view.ActionMode +import android.view.DragEvent import android.view.Gravity import android.view.KeyEvent import android.view.Menu @@ -121,6 +122,7 @@ public open class ReactEditText public constructor(context: Context) : AppCompat public var stagedInputType: Int protected var containsImages: Boolean = false public var submitBehavior: String? = null + public var dragAndDropFilter: List? = null private var disableFullscreen: Boolean private var selectionWatcher: SelectionWatcher? = null @@ -1192,6 +1194,17 @@ public open class ReactEditText public constructor(context: Context) : AppCompat super.onDraw(canvas) } + public override fun onDragEvent(event: DragEvent): Boolean { + val dragFilter = dragAndDropFilter + if (dragFilter != null && event.action == DragEvent.ACTION_DRAG_STARTED) { + val shouldHandle = dragFilter.any { filter -> event.clipDescription.hasMimeType(filter) } + if (!shouldHandle) { + return false + } + } + return super.onDragEvent(event) + } + /** * This class will redirect *TextChanged calls to the listeners only in the case where the text is * changed by the user, and not explicitly set by JS. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt index cc0a42197f1b21..373f6c673512fa 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.kt @@ -770,6 +770,22 @@ public open class ReactTextInputManager public constructor() : view.returnKeyType = returnKeyType } + @ReactProp(name = "acceptDragAndDropTypes") + public fun setAcceptDragAndDropTypes( + view: ReactEditText, + acceptDragAndDropTypes: ReadableArray? + ) { + if (acceptDragAndDropTypes == null) { + view.dragAndDropFilter = null + } else { + val acceptedTypes = mutableListOf() + for (i in 0 until acceptDragAndDropTypes.size()) { + acceptDragAndDropTypes.getString(i)?.also(acceptedTypes::add) + } + view.dragAndDropFilter = acceptedTypes + } + } + @ReactProp(name = "disableFullscreenUI", defaultBoolean = false) public fun setDisableFullscreenUI(view: ReactEditText, disableFullscreenUI: Boolean) { view.disableFullscreenUI = disableFullscreenUI diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp index 47787a57a7e9ec..bae2c65ca6edfd 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp @@ -132,7 +132,13 @@ BaseTextInputProps::BaseTextInputProps( rawProps, "disableKeyboardShortcuts", sourceProps.disableKeyboardShortcuts, - {false})) {} + {false})), + acceptDragAndDropTypes(convertRawProp( + context, + rawProps, + "acceptDragAndDropTypes", + sourceProps.acceptDragAndDropTypes, + {})) {} void BaseTextInputProps::setProp( const PropsParserContext& context, @@ -215,6 +221,7 @@ void BaseTextInputProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(submitBehavior); RAW_SET_PROP_SWITCH_CASE_BASIC(multiline); RAW_SET_PROP_SWITCH_CASE_BASIC(disableKeyboardShortcuts); + RAW_SET_PROP_SWITCH_CASE_BASIC(acceptDragAndDropTypes); } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h index 3e934024e05ee3..150f3e5fd55072 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h @@ -80,6 +80,8 @@ class BaseTextInputProps : public ViewProps, public BaseTextProps { bool multiline{false}; bool disableKeyboardShortcuts{false}; + + std::optional> acceptDragAndDropTypes{}; }; } // namespace facebook::react diff --git a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js index 50090c56476e49..b60105e4716140 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js @@ -1253,4 +1253,38 @@ module.exports = ([ ); }, }, + { + title: 'Drag and drop', + render: function (): React.Node { + return ( + + + + + + + ); + }, + }, ]: Array);