Skip to content

Commit 8a41f83

Browse files
SaadnajmiNick Lefevertido64
authored
feat(fabric): Implement Drag and Drop on View (#2713)
## Summary: Cherry pick more commits from #2117 to implement Drag and Drop Support on View. ## Test Plan: Moved the TextInput example (which doesn't work on Fabric yet) to a new page, and added a View example (which does work on Fabric) https://github.com/user-attachments/assets/b00b25fc-24b9-4587-865f-a05f305d0f40 --------- Co-authored-by: Nick Lefever <[email protected]> Co-authored-by: Tommy Nguyen <[email protected]>
1 parent 9006981 commit 8a41f83

File tree

18 files changed

+701
-219
lines changed

18 files changed

+701
-219
lines changed

packages/react-native/Libraries/Components/Pressable/Pressable.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
BlurEvent,
1313
// [macOS
1414
FocusEvent,
15+
DragEvent,
1516
HandledKeyEvent,
1617
KeyEvent,
1718
GestureResponderEvent,
@@ -198,21 +199,21 @@ type PressableBaseProps = $ReadOnly<{
198199
*
199200
* @platform macos
200201
*/
201-
onDragEnter?: (event: MouseEvent) => void,
202+
onDragEnter?: (event: DragEvent) => void,
202203

203204
/**
204205
* Fired when a file is dragged out of the Pressable via the mouse.
205206
*
206207
* @platform macos
207208
*/
208-
onDragLeave?: (event: MouseEvent) => void,
209+
onDragLeave?: (event: DragEvent) => void,
209210

210211
/**
211212
* Fired when a file is dropped on the Pressable via the mouse.
212213
*
213214
* @platform macos
214215
*/
215-
onDrop?: (event: MouseEvent) => void,
216+
onDrop?: (event: DragEvent) => void,
216217

217218
/**
218219
* The types of dragged files that the Pressable will accept.

packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import type {EdgeInsetsOrSizeProp} from '../../StyleSheet/EdgeInsetsPropType';
1313
import type {
1414
BlurEvent,
1515
FocusEvent,
16-
// [macOS]
17-
MouseEvent,
16+
MouseEvent, // [macOS]
17+
DragEvent, // [macOS]
1818
GestureResponderEvent,
1919
LayoutChangeEvent,
2020
} from '../../Types/CoreEventTypes';
@@ -36,9 +36,9 @@ export type TouchableWithoutFeedbackPropsIOS = {
3636
tooltip?: ?string,
3737
onMouseEnter?: (event: MouseEvent) => void,
3838
onMouseLeave?: (event: MouseEvent) => void,
39-
onDragEnter?: (event: MouseEvent) => void,
40-
onDragLeave?: (event: MouseEvent) => void,
41-
onDrop?: (event: MouseEvent) => void,
39+
onDragEnter?: (event: DragEvent) => void,
40+
onDragLeave?: (event: DragEvent) => void,
41+
onDrop?: (event: DragEvent) => void,
4242
draggedTypes?: ?DraggedTypesType,
4343
// macOS]
4444
};

packages/react-native/Libraries/Components/View/DraggedType.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
'use strict';
1414

15-
export type DraggedType = 'fileUrl';
15+
export type DraggedType = 'fileUrl' | 'image' | 'string';
1616

1717
export type DraggedTypesType = DraggedType | $ReadOnlyArray<DraggedType>;
1818

1919
module.exports = {
20-
DraggedTypes: ['fileUrl'],
20+
DraggedTypes: ['fileUrl', 'image', 'string'],
2121
};

packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {GestureResponderHandlers} from '../../../types/public/ReactNativeRendere
1313
import {StyleProp} from '../../StyleSheet/StyleSheet';
1414
import {ViewStyle} from '../../StyleSheet/StyleSheetTypes';
1515
import {
16+
DragEvent,
1617
HandledKeyEvent,
1718
KeyEvent,
1819
LayoutChangeEvent,
@@ -108,7 +109,7 @@ export interface ViewPropsAndroid {
108109
tabIndex?: 0 | -1 | undefined;
109110
}
110111

111-
export type DraggedType = 'fileUrl';
112+
export type DraggedType = 'fileUrl' | 'image' | 'string';
112113
export type DraggedTypesType = DraggedType | DraggedType[];
113114

114115
export interface ViewPropsMacOS {
@@ -118,9 +119,9 @@ export interface ViewPropsMacOS {
118119
enableFocusRing?: boolean | undefined;
119120
onMouseEnter?: ((event: MouseEvent) => void) | undefined;
120121
onMouseLeave?: ((event: MouseEvent) => void) | undefined;
121-
onDragEnter?: ((event: MouseEvent) => void) | undefined;
122-
onDragLeave?: ((event: MouseEvent) => void) | undefined;
123-
onDrop?: ((event: MouseEvent) => void) | undefined;
122+
onDragEnter?: ((event: DragEvent) => void) | undefined;
123+
onDragLeave?: ((event: DragEvent) => void) | undefined;
124+
onDrop?: ((event: DragEvent) => void) | undefined;
124125
onKeyDown?: ((event: KeyEvent) => void) | undefined;
125126
onKeyUp?: ((event: KeyEvent) => void) | undefined;
126127
keyDownEvents?: HandledKeyEvent[] | undefined;

packages/react-native/Libraries/Components/View/ViewPropTypes.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
BlurEvent,
1717
FocusEvent,
1818
// [macOS]
19+
DragEvent,
1920
HandledKeyEvent,
2021
KeyEvent,
2122
LayoutChangeEvent,
@@ -410,21 +411,21 @@ type MacOSViewProps = $ReadOnly<{|
410411
*
411412
* @platform macos
412413
*/
413-
onDragEnter?: (event: MouseEvent) => void,
414+
onDragEnter?: (event: DragEvent) => void,
414415

415416
/**
416417
* Fired when a file is dragged out of the view via the mouse.
417418
*
418419
* @platform macos
419420
*/
420-
onDragLeave?: (event: MouseEvent) => void,
421+
onDragLeave?: (event: DragEvent) => void,
421422

422423
/**
423424
* Fired when an element is dropped on a valid drop target
424425
*
425426
* @platform macos
426427
*/
427-
onDrop?: (event: MouseEvent) => void,
428+
onDrop?: (event: DragEvent) => void,
428429

429430
/**
430431
* Specifies the Tooltip for the view

packages/react-native/Libraries/Types/CoreEventTypes.d.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,26 @@ export interface NativeBlurEvent extends TargetedEvent {}
305305
export interface FocusEvent extends NativeSyntheticEvent<NativeFocusEvent> {}
306306

307307
export interface BlueEvent extends NativeSyntheticEvent<NativeBlurEvent> {}
308+
309+
// Drag and Drop types
310+
export interface DataTransferItem {
311+
name: string;
312+
kind: string;
313+
type: string;
314+
uri: string;
315+
size?: number | undefined;
316+
width?: number | undefined;
317+
height?: number | undefined;
318+
}
319+
320+
export interface DataTransfer {
321+
files: ReadonlyArray<DataTransferItem>;
322+
types: ReadonlyArray<string>;
323+
}
324+
325+
export interface DragEvent extends MouseEvent {
326+
nativeEvent: NativeMouseEvent & {
327+
dataTransfer?: DataTransfer | undefined;
328+
};
329+
}
308330
// macOS]

packages/react-native/Libraries/Types/CoreEventTypes.js

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,10 @@ export interface NativePointerEvent extends NativeMouseEvent {
221221
export type PointerEvent = NativeSyntheticEvent<NativePointerEvent>;
222222

223223
export type NativeTouchEvent = $ReadOnly<{
224-
altKey?: ?boolean, // [macOS]
225-
button?: ?number, // [macOS]
226224
/**
227225
* Array of all touch events that have changed since the last event
228226
*/
229227
changedTouches: $ReadOnlyArray<NativeTouchEvent>,
230-
ctrlKey?: ?boolean, // [macOS]
231228
/**
232229
* 3D Touch reported force
233230
* @platform ios
@@ -245,7 +242,7 @@ export type NativeTouchEvent = $ReadOnly<{
245242
* The Y position of the touch, relative to the element
246243
*/
247244
locationY: number,
248-
metaKey?: ?boolean, // [macOS]
245+
249246
/**
250247
* The X position of the touch, relative to the screen
251248
*/
@@ -254,7 +251,6 @@ export type NativeTouchEvent = $ReadOnly<{
254251
* The Y position of the touch, relative to the screen
255252
*/
256253
pageY: number,
257-
shiftKey?: ?boolean, // [macOS]
258254
/**
259255
* The node id of the element receiving the touch event
260256
*/
@@ -267,6 +263,13 @@ export type NativeTouchEvent = $ReadOnly<{
267263
* Array of all current touches on the screen
268264
*/
269265
touches: $ReadOnlyArray<NativeTouchEvent>,
266+
// [macOS
267+
ctrlKey?: ?boolean,
268+
altKey?: ?boolean,
269+
shiftKey?: ?boolean,
270+
metaKey?: ?boolean,
271+
button?: ?number,
272+
// macOS]
270273
}>;
271274

272275
export type GestureResponderEvent = ResponderSyntheticEvent<NativeTouchEvent>;
@@ -283,48 +286,6 @@ export type NativeScrollPoint = $ReadOnly<{
283286
x: number,
284287
}>;
285288

286-
// [macOS
287-
export type KeyEvent = NativeSyntheticEvent<
288-
$ReadOnly<{|
289-
// Modifier keys
290-
capsLockKey: boolean,
291-
shiftKey: boolean,
292-
ctrlKey: boolean,
293-
altKey: boolean,
294-
metaKey: boolean,
295-
numericPadKey: boolean,
296-
helpKey: boolean,
297-
functionKey: boolean,
298-
// Key options
299-
ArrowLeft: boolean,
300-
ArrowRight: boolean,
301-
ArrowUp: boolean,
302-
ArrowDown: boolean,
303-
key: string,
304-
|}>,
305-
>;
306-
307-
/**
308-
* Represents a key that could be passed to `KeyDownEvents` and `KeyUpEvents`.
309-
*
310-
* `key` is the actual key, such as "a", or one of the special values:
311-
* "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
312-
* "Backspace", "Delete", "Home", "End", "PageUp", "PageDown".
313-
*
314-
* The rest are modifiers that when absent mean false.
315-
*
316-
* @platform macos
317-
*/
318-
export type HandledKeyEvent = $ReadOnly<{|
319-
altKey?: ?boolean,
320-
ctrlKey?: ?boolean,
321-
metaKey?: ?boolean,
322-
shiftKey?: ?boolean,
323-
key: string,
324-
|}>;
325-
326-
// macOS]
327-
328289
export type NativeScrollVelocity = $ReadOnly<{
329290
y: number,
330291
x: number,
@@ -370,3 +331,70 @@ export type MouseEvent = NativeSyntheticEvent<
370331
timestamp: number,
371332
}>,
372333
>;
334+
335+
// [macOS
336+
export type DataTransferItem = $ReadOnly<{
337+
name: string,
338+
kind: string,
339+
type: string,
340+
uri: string,
341+
size?: number,
342+
width?: number,
343+
height?: number,
344+
}>;
345+
346+
export type DataTransfer = $ReadOnly<{
347+
files: $ReadOnlyArray<DataTransferItem>,
348+
types: $ReadOnlyArray<string>,
349+
}>;
350+
351+
export type DragEvent = NativeSyntheticEvent<
352+
$ReadOnly<{
353+
clientX: number,
354+
clientY: number,
355+
pageX: number,
356+
pageY: number,
357+
timestamp: number,
358+
dataTransfer?: DataTransfer,
359+
}>,
360+
>;
361+
362+
export type KeyEvent = NativeSyntheticEvent<
363+
$ReadOnly<{|
364+
// Modifier keys
365+
capsLockKey: boolean,
366+
shiftKey: boolean,
367+
ctrlKey: boolean,
368+
altKey: boolean,
369+
metaKey: boolean,
370+
numericPadKey: boolean,
371+
helpKey: boolean,
372+
functionKey: boolean,
373+
// Key options
374+
ArrowLeft: boolean,
375+
ArrowRight: boolean,
376+
ArrowUp: boolean,
377+
ArrowDown: boolean,
378+
key: string,
379+
|}>,
380+
>;
381+
382+
/**
383+
* Represents a key that could be passed to `KeyDownEvents` and `KeyUpEvents`.
384+
*
385+
* `key` is the actual key, such as "a", or one of the special values:
386+
* "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
387+
* "Backspace", "Delete", "Home", "End", "PageUp", "PageDown".
388+
*
389+
* The rest are modifiers that when absent mean false.
390+
*
391+
* @platform macos
392+
*/
393+
export type HandledKeyEvent = $ReadOnly<{|
394+
ctrlKey?: ?boolean,
395+
altKey?: ?boolean,
396+
shiftKey?: ?boolean,
397+
metaKey?: ?boolean,
398+
key: string,
399+
|}>;
400+
// macOS]

0 commit comments

Comments
 (0)