mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add prop to filter drag and drop pasting on Android (#49446)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49446 On Android, by default, every EditText accepts `DragEvent` and will automatically focus themselves to accept these data. In some rare cases, it might not be desirable to allow data from arbitrary drag and drop events to be pasted into a text input. This change adds a new prop `acceptDragAndDropTypes` to do exactly that: reject drag and drop events by telling the system to ignore certain types of drag data and, by proxy, disabling behavior that automatically focuses the text input. The prop accepts a subset of MIME types supported by Android as documented [here](https://developer.android.com/reference/android/content/ClipDescription#MIMETYPE_TEXT_HTML). It's important to note that this is an experimental prop, as is evident by the `experimental_` prefix on the JS side. Its signature could change before the prop has fully matured, use at your own risk Changelog: [Android][Added] - Add new prop for filtering drag and drop targeting to text inputs Reviewed By: javache Differential Revision: D69674225 fbshipit-source-id: 4dbbdd81bb0f394b6206da5a377c75ea71671626
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3b17cdb643
commit
d10dd7130c
+1
@@ -658,6 +658,7 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = {
|
||||
},
|
||||
},
|
||||
validAttributes: {
|
||||
acceptDragAndDropTypes: true,
|
||||
maxFontSizeMultiplier: true,
|
||||
adjustsFontSizeToFit: true,
|
||||
minimumFontScale: true,
|
||||
|
||||
@@ -405,6 +405,19 @@ export type TextInputIOSProps = $ReadOnly<{
|
||||
}>;
|
||||
|
||||
export type TextInputAndroidProps = $ReadOnly<{
|
||||
/**
|
||||
* When provided, the text input will only accept drag and drop events for the specified
|
||||
* mime types. If null or not provided, the text input will accept all types of drag and drop
|
||||
* events.
|
||||
* Defaults to null.
|
||||
*
|
||||
* *NOTE*: This prop is experimental and its API may change in the future. Use at your own risk.
|
||||
*
|
||||
* @platform android
|
||||
* @see https://developer.android.com/reference/android/content/ClipData for more information on MIME types
|
||||
*/
|
||||
experimental_acceptDragAndDropTypes?: ?$ReadOnlyArray<string>,
|
||||
|
||||
/**
|
||||
* When provided it will set the color of the cursor (or "caret") in the component.
|
||||
* Unlike the behavior of `selectionColor` the cursor color will be set independently
|
||||
|
||||
@@ -741,6 +741,7 @@ function InternalTextInput(props: TextInputProps): React.Node {
|
||||
accessibilityState={_accessibilityState}
|
||||
accessibilityLabelledBy={_accessibilityLabelledBy}
|
||||
accessible={accessible}
|
||||
acceptDragAndDropTypes={props.experimental_acceptDragAndDropTypes}
|
||||
autoCapitalize={autoCapitalize}
|
||||
submitBehavior={submitBehavior}
|
||||
caretHidden={caretHidden}
|
||||
|
||||
@@ -2831,6 +2831,7 @@ export type TextInputIOSProps = $ReadOnly<{
|
||||
smartInsertDelete?: ?boolean,
|
||||
}>;
|
||||
export type TextInputAndroidProps = $ReadOnly<{
|
||||
experimental_acceptDragAndDropTypes?: ?$ReadOnlyArray<string>,
|
||||
cursorColor?: ?ColorValue,
|
||||
selectionHandleColor?: ?ColorValue,
|
||||
disableFullscreenUI?: ?boolean,
|
||||
|
||||
@@ -6651,6 +6651,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
|
||||
@@ -6670,6 +6671,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
|
||||
@@ -6695,6 +6697,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
|
||||
@@ -6758,6 +6761,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
|
||||
|
||||
+13
@@ -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<String>? = 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.
|
||||
|
||||
+16
@@ -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<String>()
|
||||
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
|
||||
|
||||
@@ -448,6 +448,27 @@ const examples: Array<RNTesterModuleExample> = [
|
||||
return <ToggleDefaultPaddingExample />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Drag and drop',
|
||||
render: function (): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<ExampleTextInput
|
||||
experimental_acceptDragAndDropTypes={[]}
|
||||
placeholder="Does not accept drag drops"
|
||||
/>
|
||||
<ExampleTextInput
|
||||
experimental_acceptDragAndDropTypes={['text/plain']}
|
||||
placeholder="Only accepts plaintext drag drops"
|
||||
/>
|
||||
<ExampleTextInput
|
||||
experimental_acceptDragAndDropTypes={null}
|
||||
placeholder="Accepts all drag drops"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = ({
|
||||
|
||||
Reference in New Issue
Block a user