react-native-drax 0.10.3 → 0.11.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +2 -73
- package/.prettierrc +16 -0
- package/README.md +81 -1
- package/build/AllHoverViews.d.ts +0 -0
- package/build/AllHoverViews.js +30 -0
- package/build/DraxContext.d.ts +0 -1
- package/build/DraxList.d.ts +3 -3
- package/build/DraxList.js +231 -216
- package/build/DraxListItem.d.ts +7 -0
- package/build/DraxListItem.js +121 -0
- package/build/DraxProvider.d.ts +1 -3
- package/build/DraxProvider.js +322 -259
- package/build/DraxScrollView.d.ts +1 -1
- package/build/DraxScrollView.js +29 -90
- package/build/DraxSubprovider.d.ts +2 -2
- package/build/DraxSubprovider.js +1 -1
- package/build/DraxView.d.ts +7 -2
- package/build/DraxView.js +60 -383
- package/build/HoverView.d.ts +8 -0
- package/build/HoverView.js +40 -0
- package/build/PanGestureDetector.d.ts +3 -0
- package/build/PanGestureDetector.js +49 -0
- package/build/hooks/useContent.d.ts +23 -0
- package/build/hooks/useContent.js +212 -0
- package/build/hooks/useDraxProtocol.d.ts +5 -0
- package/build/hooks/useDraxProtocol.js +32 -0
- package/build/hooks/useDraxRegistry.d.ts +21 -20
- package/build/hooks/useDraxRegistry.js +195 -182
- package/build/hooks/useDraxScrollHandler.d.ts +25 -0
- package/build/hooks/useDraxScrollHandler.js +89 -0
- package/build/hooks/useDraxState.d.ts +1 -1
- package/build/hooks/useDraxState.js +9 -6
- package/build/hooks/useMeasurements.d.ts +9 -0
- package/build/hooks/useMeasurements.js +119 -0
- package/build/hooks/useStatus.d.ts +11 -0
- package/build/hooks/useStatus.js +96 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +4 -1
- package/build/math.d.ts +2 -2
- package/build/math.js +10 -6
- package/build/params.d.ts +9 -0
- package/build/params.js +7 -1
- package/build/transform.d.ts +11 -4
- package/build/transform.js +50 -8
- package/build/types.d.ts +238 -87
- package/build/types.js +10 -7
- package/package.json +43 -45
package/build/DraxProvider.js
CHANGED
|
@@ -22,20 +22,252 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
exports.DraxProvider = void 0;
|
|
30
|
+
const lodash_throttle_1 = __importDefault(require("lodash.throttle"));
|
|
27
31
|
const react_1 = __importStar(require("react"));
|
|
28
32
|
const react_native_1 = require("react-native");
|
|
29
33
|
const react_native_gesture_handler_1 = require("react-native-gesture-handler");
|
|
30
|
-
const
|
|
34
|
+
const react_native_reanimated_1 = require("react-native-reanimated");
|
|
31
35
|
const DraxContext_1 = require("./DraxContext");
|
|
32
|
-
const
|
|
36
|
+
const HoverView_1 = require("./HoverView");
|
|
37
|
+
const hooks_1 = require("./hooks");
|
|
33
38
|
const math_1 = require("./math");
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
const types_1 = require("./types");
|
|
40
|
+
const startPositionInitialValue = {
|
|
41
|
+
parent: { x: 0, y: 0 },
|
|
42
|
+
grab: { x: 0, y: 0 },
|
|
43
|
+
};
|
|
44
|
+
const DraxProvider = ({ debug = false, style = styles.provider, children }) => {
|
|
45
|
+
const { getViewState, getTrackingStatus, getAllViewIds, dispatch } = (0, hooks_1.useDraxState)();
|
|
46
|
+
const { getAbsoluteViewData, getTrackingDragged, getTrackingReceiver, getTrackingMonitorIds, getTrackingMonitors, getDragPositionData, findMonitorsAndReceiver, getHoverItems, registerView, updateViewProtocol, updateViewMeasurements, updateHoverViewMeasurements, resetReceiver, resetDrag, startDrag, updateDragPosition, updateReceiver, setMonitorIds, unregisterView, getReleaseViews, } = (0, hooks_1.useDraxRegistry)(dispatch);
|
|
47
|
+
const rootViewRef = (0, react_1.useRef)(null);
|
|
48
|
+
const dragPositionDataSV = (0, react_native_reanimated_1.useSharedValue)(undefined);
|
|
49
|
+
const startPosition = (0, react_native_reanimated_1.useSharedValue)(startPositionInitialValue);
|
|
50
|
+
const parentPosition = (0, react_native_reanimated_1.useSharedValue)({ x: 0, y: 0 });
|
|
51
|
+
const checkForReceiver = (0, react_1.useCallback)((dragPositionData) => {
|
|
52
|
+
// Find which monitors and receiver this drag is over.
|
|
53
|
+
const dragged = getTrackingDragged();
|
|
54
|
+
if (dragged && dragPositionData) {
|
|
55
|
+
const { dragAbsolutePosition, dragTranslationRatio, dragTranslation } = dragPositionData;
|
|
56
|
+
const { monitors, receiver } = findMonitorsAndReceiver(dragAbsolutePosition, dragged.id);
|
|
57
|
+
// Get the previous receiver, if any.
|
|
58
|
+
const oldReceiver = getTrackingReceiver();
|
|
59
|
+
/*
|
|
60
|
+
* Consider the following cases for new and old receiver ids:
|
|
61
|
+
* Case 1: new exists, old exists, new is the same as old
|
|
62
|
+
* Case 2: new exists, old exists, new is different from old
|
|
63
|
+
* Case 3: new exists, old does not exist
|
|
64
|
+
* Case 4: new does not exist, old exists
|
|
65
|
+
* Case 5: new does not exist, old does not exist
|
|
66
|
+
*/
|
|
67
|
+
const draggedProtocol = dragged.data.protocol;
|
|
68
|
+
// Prepare event data for dragged view.
|
|
69
|
+
const eventDataDragged = {
|
|
70
|
+
dragTranslationRatio,
|
|
71
|
+
id: dragged.id,
|
|
72
|
+
parentId: dragged.data.parentId,
|
|
73
|
+
payload: dragged.data.protocol.dragPayload,
|
|
74
|
+
dragOffset: dragged.tracking.dragOffset,
|
|
75
|
+
grabOffset: dragged.tracking.grabOffset,
|
|
76
|
+
grabOffsetRatio: dragged.tracking.grabOffsetRatio,
|
|
77
|
+
hoverPosition: dragged.tracking.hoverPosition.value,
|
|
78
|
+
data: dragged.data,
|
|
79
|
+
};
|
|
80
|
+
// Prepare base drag event data.
|
|
81
|
+
const dragEventData = {
|
|
82
|
+
dragAbsolutePosition,
|
|
83
|
+
dragTranslation,
|
|
84
|
+
dragged: eventDataDragged,
|
|
85
|
+
};
|
|
86
|
+
// Prepare event data stub for monitor updates later so we can optionally add receiver.
|
|
87
|
+
const monitorEventDataStub = {
|
|
88
|
+
...dragEventData,
|
|
89
|
+
};
|
|
90
|
+
if (receiver) {
|
|
91
|
+
// New receiver exists.
|
|
92
|
+
const receiverProtocol = receiver.data.protocol;
|
|
93
|
+
// Update the receiver.
|
|
94
|
+
const trackingReceiver = updateReceiver(receiver, dragged);
|
|
95
|
+
if (trackingReceiver === undefined) {
|
|
96
|
+
// This should never happen, but just in case.
|
|
97
|
+
// if (debug) {
|
|
98
|
+
// console.log('Failed to update tracking receiver');
|
|
99
|
+
// }
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Prepare event data for receiver view.
|
|
103
|
+
const eventDataReceiver = {
|
|
104
|
+
id: receiver.id,
|
|
105
|
+
parentId: receiver.data.parentId,
|
|
106
|
+
payload: receiver.data.protocol.receiverPayload,
|
|
107
|
+
receiveOffset: trackingReceiver.receiveOffset,
|
|
108
|
+
receiveOffsetRatio: trackingReceiver.receiveOffsetRatio,
|
|
109
|
+
data: receiver.data,
|
|
110
|
+
};
|
|
111
|
+
// Add receiver data to monitor event stub.
|
|
112
|
+
monitorEventDataStub.receiver = eventDataReceiver;
|
|
113
|
+
// Prepare event data for callbacks.
|
|
114
|
+
const eventData = {
|
|
115
|
+
...dragEventData,
|
|
116
|
+
receiver: eventDataReceiver,
|
|
117
|
+
};
|
|
118
|
+
if (oldReceiver) {
|
|
119
|
+
if (receiver.id === oldReceiver.id) {
|
|
120
|
+
// Case 1: new exists, old exists, new is the same as old
|
|
121
|
+
// Call the protocol event callbacks for dragging over the receiver.
|
|
122
|
+
draggedProtocol.onDragOver?.(eventData);
|
|
123
|
+
receiverProtocol.onReceiveDragOver?.(eventData);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Case 2: new exists, old exists, new is different from old
|
|
127
|
+
// Prepare event data with old receiver.
|
|
128
|
+
const eventDataOldReceiver = {
|
|
129
|
+
...dragEventData,
|
|
130
|
+
receiver: {
|
|
131
|
+
id: oldReceiver.id,
|
|
132
|
+
parentId: oldReceiver.data.parentId,
|
|
133
|
+
payload: oldReceiver.data.protocol.receiverPayload,
|
|
134
|
+
receiveOffset: oldReceiver.tracking.receiveOffset,
|
|
135
|
+
receiveOffsetRatio: oldReceiver.tracking.receiveOffsetRatio,
|
|
136
|
+
data: oldReceiver.data,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
// Call the protocol event callbacks for exiting the old receiver...
|
|
140
|
+
draggedProtocol.onDragExit?.(eventDataOldReceiver);
|
|
141
|
+
const endEventDataOldReceiver = {
|
|
142
|
+
...eventDataOldReceiver,
|
|
143
|
+
cancelled: false,
|
|
144
|
+
};
|
|
145
|
+
oldReceiver.data.protocol.onReceiveDragExit?.(endEventDataOldReceiver);
|
|
146
|
+
// ...and entering the new receiver.
|
|
147
|
+
draggedProtocol.onDragEnter?.(eventData);
|
|
148
|
+
receiverProtocol.onReceiveDragEnter?.(eventData);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Case 3: new exists, old does not exist
|
|
153
|
+
// Call the protocol event callbacks for entering the new receiver.
|
|
154
|
+
draggedProtocol.onDragEnter?.(eventData);
|
|
155
|
+
receiverProtocol.onReceiveDragEnter?.(eventData);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else if (oldReceiver) {
|
|
159
|
+
// Case 4: new does not exist, old exists
|
|
160
|
+
// Reset the old receiver.
|
|
161
|
+
resetReceiver();
|
|
162
|
+
// Prepare event data with old receiver.
|
|
163
|
+
const eventData = {
|
|
164
|
+
...dragEventData,
|
|
165
|
+
receiver: {
|
|
166
|
+
id: oldReceiver.id,
|
|
167
|
+
parentId: oldReceiver.data.parentId,
|
|
168
|
+
payload: oldReceiver.data.protocol.receiverPayload,
|
|
169
|
+
receiveOffset: oldReceiver.tracking.receiveOffset,
|
|
170
|
+
receiveOffsetRatio: oldReceiver.tracking.receiveOffsetRatio,
|
|
171
|
+
data: oldReceiver.data,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
// Call the protocol event callbacks for exiting the old receiver.
|
|
175
|
+
draggedProtocol.onDragExit?.(eventData);
|
|
176
|
+
const receiveEventData = {
|
|
177
|
+
...eventData,
|
|
178
|
+
cancelled: false,
|
|
179
|
+
};
|
|
180
|
+
oldReceiver.data.protocol.onReceiveDragExit?.(receiveEventData);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// Case 5: new does not exist, old does not exist
|
|
184
|
+
// Call the protocol event callback for dragging.
|
|
185
|
+
draggedProtocol.onDrag?.(dragEventData);
|
|
186
|
+
}
|
|
187
|
+
// Notify monitors and update monitor tracking, if necessary.
|
|
188
|
+
const prevMonitorIds = getTrackingMonitorIds();
|
|
189
|
+
if (monitors.length > 0 || prevMonitorIds.length > 0) {
|
|
190
|
+
const newMonitorIds = monitors.map(({ id: monitorId, data: monitorData, relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio, }) => {
|
|
191
|
+
const monitorEventData = {
|
|
192
|
+
...monitorEventDataStub,
|
|
193
|
+
monitorOffset,
|
|
194
|
+
monitorOffsetRatio,
|
|
195
|
+
};
|
|
196
|
+
if (prevMonitorIds.includes(monitorId)) {
|
|
197
|
+
// Drag was already over this monitor.
|
|
198
|
+
monitorData.protocol.onMonitorDragOver?.(monitorEventData);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Drag is entering monitor.
|
|
202
|
+
monitorData.protocol.onMonitorDragEnter?.(monitorEventData);
|
|
203
|
+
}
|
|
204
|
+
return monitorId;
|
|
205
|
+
});
|
|
206
|
+
prevMonitorIds
|
|
207
|
+
.filter(monitorId => !newMonitorIds.includes(monitorId))
|
|
208
|
+
.forEach(monitorId => {
|
|
209
|
+
// Drag has exited monitor.
|
|
210
|
+
const monitorData = getAbsoluteViewData(monitorId);
|
|
211
|
+
if (monitorData) {
|
|
212
|
+
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
|
|
213
|
+
monitorData.protocol.onMonitorDragExit?.({
|
|
214
|
+
...monitorEventDataStub,
|
|
215
|
+
monitorOffset,
|
|
216
|
+
monitorOffsetRatio,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
setMonitorIds(newMonitorIds);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}, [
|
|
224
|
+
findMonitorsAndReceiver,
|
|
225
|
+
getAbsoluteViewData,
|
|
226
|
+
getTrackingDragged,
|
|
227
|
+
getTrackingMonitorIds,
|
|
228
|
+
getTrackingReceiver,
|
|
229
|
+
resetReceiver,
|
|
230
|
+
setMonitorIds,
|
|
231
|
+
updateReceiver,
|
|
232
|
+
]);
|
|
233
|
+
const updateDragAbsolutePosition = (0, react_1.useCallback)((position) => {
|
|
234
|
+
const dragged = getTrackingDragged();
|
|
235
|
+
if (dragged && position) {
|
|
236
|
+
// Get the absolute position data for the drag touch.
|
|
237
|
+
const dragPositionData = getDragPositionData({
|
|
238
|
+
parentPosition: position,
|
|
239
|
+
draggedMeasurements: dragged.data.absoluteMeasurements,
|
|
240
|
+
lockXPosition: dragged.data.protocol.lockDragXPosition,
|
|
241
|
+
lockYPosition: dragged.data.protocol.lockDragYPosition,
|
|
242
|
+
});
|
|
243
|
+
if (!dragPositionData) {
|
|
244
|
+
// Failed to get drag position data. This should never happen.
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const { dragAbsolutePosition, dragTranslation, dragTranslationRatio } = dragPositionData;
|
|
248
|
+
dragPositionDataSV.value = {
|
|
249
|
+
dragAbsolutePosition,
|
|
250
|
+
dragTranslation,
|
|
251
|
+
dragTranslationRatio,
|
|
252
|
+
};
|
|
253
|
+
// if (debug) {
|
|
254
|
+
// console.log(`Drag at absolute coordinates (${dragAbsolutePosition.x}, ${dragAbsolutePosition.y})\n`);
|
|
255
|
+
// console.log(`Drag translation (${dragTranslation.x}, ${dragTranslation.y})`);
|
|
256
|
+
// console.log(`Drag translation ratio (${dragTranslationRatio.x}, ${dragTranslationRatio.y})`);
|
|
257
|
+
// }
|
|
258
|
+
// Always update the drag position.
|
|
259
|
+
updateDragPosition(dragAbsolutePosition);
|
|
260
|
+
}
|
|
261
|
+
}, [dragPositionDataSV, getDragPositionData, getTrackingDragged, updateDragPosition]);
|
|
262
|
+
// // Create throttled gesture event handler, tied to this id.
|
|
263
|
+
const throttledHandleGestureEvent = (0, react_1.useMemo)(() => (0, lodash_throttle_1.default)((position) => {
|
|
264
|
+
// Pass the event up to the Drax context.
|
|
265
|
+
updateDragAbsolutePosition(position);
|
|
266
|
+
}, 20), [updateDragAbsolutePosition]);
|
|
267
|
+
(0, react_native_reanimated_1.useAnimatedReaction)(() => dragPositionDataSV.value, position => {
|
|
268
|
+
(0, react_native_reanimated_1.runOnJS)(checkForReceiver)(position);
|
|
269
|
+
});
|
|
270
|
+
const handleGestureStateChange = (0, react_1.useCallback)((id) => (event) => {
|
|
39
271
|
if (debug) {
|
|
40
272
|
console.log(`handleGestureStateChange(${id}, ${JSON.stringify(event, null, 2)})`);
|
|
41
273
|
}
|
|
@@ -75,7 +307,7 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
75
307
|
}
|
|
76
308
|
/*
|
|
77
309
|
* Documentation on gesture handler state flow used in switches below:
|
|
78
|
-
* https://
|
|
310
|
+
* https://docs.swmansion.com/react-native-gesture-handler/docs/under-the-hood/state/
|
|
79
311
|
*/
|
|
80
312
|
const { state: gestureState, // Used in switch logic below; see block comment above.
|
|
81
313
|
x: grabX, // x position of touch relative to dragged view
|
|
@@ -83,6 +315,10 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
83
315
|
absoluteX: parentX, // x position of touch relative to parent of dragged view
|
|
84
316
|
absoluteY: parentY, // y position of touch relative to parent of dragged view
|
|
85
317
|
} = event;
|
|
318
|
+
startPosition.value = {
|
|
319
|
+
parent: { x: parentX, y: parentY },
|
|
320
|
+
grab: { x: grabX, y: grabY },
|
|
321
|
+
};
|
|
86
322
|
/** Position of touch relative to parent of dragged view */
|
|
87
323
|
const dragParentPosition = { x: parentX, y: parentY };
|
|
88
324
|
const { x: absoluteX, // absolute x position of dragged view within DraxProvider
|
|
@@ -154,7 +390,12 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
154
390
|
// Failed to get absolute position of drag. This should never happen.
|
|
155
391
|
return;
|
|
156
392
|
}
|
|
157
|
-
const { dragAbsolutePosition, dragTranslation, dragTranslationRatio
|
|
393
|
+
const { dragAbsolutePosition, dragTranslation, dragTranslationRatio } = dragPositionData;
|
|
394
|
+
dragPositionDataSV.value = {
|
|
395
|
+
dragAbsolutePosition,
|
|
396
|
+
dragTranslation,
|
|
397
|
+
dragTranslationRatio,
|
|
398
|
+
};
|
|
158
399
|
// Prepare event data for dragged view.
|
|
159
400
|
const eventDataDragged = {
|
|
160
401
|
id,
|
|
@@ -164,7 +405,8 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
164
405
|
dragOffset: dragged.tracking.dragOffset,
|
|
165
406
|
grabOffset: dragged.tracking.grabOffset,
|
|
166
407
|
grabOffsetRatio: dragged.tracking.grabOffsetRatio,
|
|
167
|
-
hoverPosition: dragged.tracking.hoverPosition,
|
|
408
|
+
hoverPosition: dragged.tracking.hoverPosition.value,
|
|
409
|
+
data: draggedData,
|
|
168
410
|
};
|
|
169
411
|
// Get data for receiver view (if any) before we reset.
|
|
170
412
|
const receiver = getTrackingReceiver();
|
|
@@ -180,8 +422,8 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
180
422
|
id: receiver.id,
|
|
181
423
|
parentId: receiver.data.parentId,
|
|
182
424
|
payload: receiver.data.protocol.receiverPayload,
|
|
183
|
-
|
|
184
|
-
|
|
425
|
+
...receiver.tracking,
|
|
426
|
+
data: receiver.data,
|
|
185
427
|
};
|
|
186
428
|
const eventData = {
|
|
187
429
|
dragAbsolutePosition,
|
|
@@ -203,12 +445,13 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
203
445
|
if (monitors.length > 0) {
|
|
204
446
|
monitors.forEach(({ data: monitorData }) => {
|
|
205
447
|
if (monitorData) {
|
|
206
|
-
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio
|
|
207
|
-
|
|
448
|
+
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
|
|
449
|
+
const monitorEventData = {
|
|
208
450
|
...eventData,
|
|
209
451
|
monitorOffset,
|
|
210
452
|
monitorOffsetRatio,
|
|
211
|
-
}
|
|
453
|
+
};
|
|
454
|
+
response = monitorData.protocol.onMonitorDragDrop?.(monitorEventData);
|
|
212
455
|
}
|
|
213
456
|
if (!responded && response !== undefined) {
|
|
214
457
|
snapbackTarget = response;
|
|
@@ -240,12 +483,14 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
240
483
|
payload: receiver.data.protocol.receiverPayload,
|
|
241
484
|
receiveOffset: receiver.tracking.receiveOffset,
|
|
242
485
|
receiveOffsetRatio: receiver.tracking.receiveOffsetRatio,
|
|
486
|
+
data: receiver.data,
|
|
243
487
|
};
|
|
244
|
-
|
|
245
|
-
receiver?.data.protocol.onReceiveDragExit?.({
|
|
488
|
+
const receivedDragExitEventData = {
|
|
246
489
|
...eventData,
|
|
247
490
|
receiver: eventReceiverData,
|
|
248
|
-
}
|
|
491
|
+
};
|
|
492
|
+
// If there is a receiver but drag was cancelled, let it know the drag exited it.
|
|
493
|
+
receiver?.data.protocol.onReceiveDragExit?.(receivedDragExitEventData);
|
|
249
494
|
// And let any active monitors know too.
|
|
250
495
|
if (monitors.length > 0) {
|
|
251
496
|
const monitorEventData = {
|
|
@@ -253,7 +498,7 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
253
498
|
receiver: eventReceiverData,
|
|
254
499
|
};
|
|
255
500
|
monitors.forEach(({ data: monitorData }) => {
|
|
256
|
-
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio
|
|
501
|
+
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
|
|
257
502
|
response = monitorData.protocol.onMonitorDragEnd?.({
|
|
258
503
|
...monitorEventData,
|
|
259
504
|
monitorOffset,
|
|
@@ -269,6 +514,10 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
269
514
|
}
|
|
270
515
|
// Reset the drag.
|
|
271
516
|
resetDrag(snapbackTarget);
|
|
517
|
+
if (startPosition.value) {
|
|
518
|
+
startPosition.value = startPositionInitialValue;
|
|
519
|
+
parentPosition.value = { x: 0, y: 0 };
|
|
520
|
+
}
|
|
272
521
|
return;
|
|
273
522
|
}
|
|
274
523
|
// Case 4: We're not already dragging a view.
|
|
@@ -324,13 +573,18 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
324
573
|
x: grabX / width,
|
|
325
574
|
y: grabY / height,
|
|
326
575
|
};
|
|
327
|
-
const { dragOffset, dragTranslation, dragTranslationRatio, hoverPosition
|
|
576
|
+
const { dragOffset, dragTranslation, dragTranslationRatio, hoverPosition } = startDrag({
|
|
328
577
|
grabOffset,
|
|
329
578
|
grabOffsetRatio,
|
|
330
579
|
dragAbsolutePosition,
|
|
331
580
|
dragParentPosition,
|
|
332
581
|
draggedId: id,
|
|
333
582
|
});
|
|
583
|
+
dragPositionDataSV.value = {
|
|
584
|
+
dragAbsolutePosition,
|
|
585
|
+
dragTranslation,
|
|
586
|
+
dragTranslationRatio,
|
|
587
|
+
};
|
|
334
588
|
if (debug) {
|
|
335
589
|
console.log(`Start dragging view id ${id} at absolute position (${dragAbsolutePosition.x}, ${dragAbsolutePosition.y})`);
|
|
336
590
|
}
|
|
@@ -342,10 +596,11 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
342
596
|
dragOffset,
|
|
343
597
|
grabOffset,
|
|
344
598
|
grabOffsetRatio,
|
|
345
|
-
hoverPosition,
|
|
599
|
+
hoverPosition: hoverPosition.value,
|
|
346
600
|
dragTranslationRatio,
|
|
347
601
|
parentId: draggedData.parentId,
|
|
348
602
|
payload: draggedData.protocol.dragPayload,
|
|
603
|
+
data: draggedData,
|
|
349
604
|
},
|
|
350
605
|
};
|
|
351
606
|
draggedData.protocol.onDragStart?.(eventData);
|
|
@@ -366,272 +621,80 @@ const DraxProvider = ({ debug = false, style = styles.provider, children, }) =>
|
|
|
366
621
|
}
|
|
367
622
|
}
|
|
368
623
|
}, [
|
|
624
|
+
debug,
|
|
625
|
+
getTrackingDragged,
|
|
369
626
|
getAbsoluteViewData,
|
|
627
|
+
startPosition,
|
|
370
628
|
getDragPositionData,
|
|
371
|
-
|
|
629
|
+
dragPositionDataSV,
|
|
372
630
|
getTrackingReceiver,
|
|
373
631
|
getTrackingMonitors,
|
|
374
632
|
resetDrag,
|
|
633
|
+
parentPosition,
|
|
375
634
|
startDrag,
|
|
376
635
|
findMonitorsAndReceiver,
|
|
377
636
|
setMonitorIds,
|
|
378
|
-
debug,
|
|
379
637
|
]);
|
|
380
638
|
const handleGestureEvent = (0, react_1.useCallback)((id, event) => {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (dragged === undefined) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
392
|
-
if (dragged.id !== id) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
639
|
+
'worklet';
|
|
640
|
+
// if (debug) {
|
|
641
|
+
// console.log(`handleGestureEvent(${id}, ${JSON.stringify(event, null, 2)})`);
|
|
642
|
+
// }
|
|
643
|
+
// if (dragged === undefined) {
|
|
644
|
+
// // We're not tracking any gesture yet.
|
|
645
|
+
// if (debug) {
|
|
646
|
+
// console.log('Ignoring gesture event because we have not initialized a drag');
|
|
647
|
+
// }
|
|
648
|
+
// return;
|
|
649
|
+
// }
|
|
650
|
+
// if (dragged.id !== id) {
|
|
651
|
+
// // This is not a gesture we're tracking. We don't support multiple simultaneous drags.
|
|
652
|
+
// if (debug) {
|
|
653
|
+
// console.log('Ignoring gesture event because this is not the view being dragged');
|
|
654
|
+
// }
|
|
655
|
+
// return;
|
|
656
|
+
// }
|
|
399
657
|
const { absoluteX: parentX, // x position of touch relative to parent of dragged view
|
|
400
658
|
absoluteY: parentY, // y position of touch relative to parent of dragged view
|
|
401
659
|
} = event;
|
|
402
|
-
if (debug) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
660
|
+
// if (debug) {
|
|
661
|
+
// console.log(`Dragged item absolute coordinates (${dragged.data.absoluteMeasurements.x}, ${dragged.data.absoluteMeasurements.y})`);
|
|
662
|
+
// console.log(`Native event in-view touch coordinates: (${event.x}, ${event.y})`);
|
|
663
|
+
// }
|
|
406
664
|
/** Position of touch relative to parent of dragged view */
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
if (!dragPositionData) {
|
|
416
|
-
// Failed to get drag position data. This should never happen.
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
const { dragAbsolutePosition, dragTranslation, dragTranslationRatio, } = dragPositionData;
|
|
420
|
-
if (debug) {
|
|
421
|
-
console.log(`Drag at absolute coordinates (${dragAbsolutePosition.x}, ${dragAbsolutePosition.y})\n`);
|
|
422
|
-
console.log(`Drag translation (${dragTranslation.x}, ${dragTranslation.y})`);
|
|
423
|
-
console.log(`Drag translation ratio (${dragTranslationRatio.x}, ${dragTranslationRatio.y})`);
|
|
424
|
-
}
|
|
425
|
-
// Find which monitors and receiver this drag is over.
|
|
426
|
-
const { monitors, receiver } = findMonitorsAndReceiver(dragAbsolutePosition, dragged.id);
|
|
427
|
-
// Get the previous receiver, if any.
|
|
428
|
-
const oldReceiver = getTrackingReceiver();
|
|
429
|
-
// Always update the drag position.
|
|
430
|
-
updateDragPosition(dragAbsolutePosition);
|
|
431
|
-
const draggedProtocol = dragged.data.protocol;
|
|
432
|
-
// Prepare event data for dragged view.
|
|
433
|
-
const eventDataDragged = {
|
|
434
|
-
dragTranslationRatio,
|
|
435
|
-
id: dragged.id,
|
|
436
|
-
parentId: dragged.data.parentId,
|
|
437
|
-
payload: dragged.data.protocol.dragPayload,
|
|
438
|
-
dragOffset: dragged.tracking.dragOffset,
|
|
439
|
-
grabOffset: dragged.tracking.grabOffset,
|
|
440
|
-
grabOffsetRatio: dragged.tracking.grabOffsetRatio,
|
|
441
|
-
hoverPosition: dragged.tracking.hoverPosition,
|
|
442
|
-
};
|
|
443
|
-
// Prepare base drag event data.
|
|
444
|
-
const dragEventData = {
|
|
445
|
-
dragAbsolutePosition,
|
|
446
|
-
dragTranslation,
|
|
447
|
-
dragged: eventDataDragged,
|
|
448
|
-
};
|
|
449
|
-
// Prepare event data stub for monitor updates later so we can optionally add receiver.
|
|
450
|
-
const monitorEventDataStub = {
|
|
451
|
-
...dragEventData,
|
|
452
|
-
};
|
|
453
|
-
/*
|
|
454
|
-
* Consider the following cases for new and old receiver ids:
|
|
455
|
-
* Case 1: new exists, old exists, new is the same as old
|
|
456
|
-
* Case 2: new exists, old exists, new is different from old
|
|
457
|
-
* Case 3: new exists, old does not exist
|
|
458
|
-
* Case 4: new does not exist, old exists
|
|
459
|
-
* Case 5: new does not exist, old does not exist
|
|
460
|
-
*/
|
|
461
|
-
if (receiver) {
|
|
462
|
-
// New receiver exists.
|
|
463
|
-
const receiverProtocol = receiver.data.protocol;
|
|
464
|
-
// Update the receiver.
|
|
465
|
-
const trackingReceiver = updateReceiver(receiver, dragged);
|
|
466
|
-
if (trackingReceiver === undefined) {
|
|
467
|
-
// This should never happen, but just in case.
|
|
468
|
-
if (debug) {
|
|
469
|
-
console.log('Failed to update tracking receiver');
|
|
470
|
-
}
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
// Prepare event data for receiver view.
|
|
474
|
-
const eventDataReceiver = {
|
|
475
|
-
id: receiver.id,
|
|
476
|
-
parentId: receiver.data.parentId,
|
|
477
|
-
payload: receiver.data.protocol.receiverPayload,
|
|
478
|
-
receiveOffset: trackingReceiver.receiveOffset,
|
|
479
|
-
receiveOffsetRatio: trackingReceiver.receiveOffsetRatio,
|
|
480
|
-
};
|
|
481
|
-
// Add receiver data to monitor event stub.
|
|
482
|
-
monitorEventDataStub.receiver = eventDataReceiver;
|
|
483
|
-
// Prepare event data for callbacks.
|
|
484
|
-
const eventData = {
|
|
485
|
-
...dragEventData,
|
|
486
|
-
receiver: eventDataReceiver,
|
|
487
|
-
};
|
|
488
|
-
if (oldReceiver) {
|
|
489
|
-
if (receiver.id === oldReceiver.id) {
|
|
490
|
-
// Case 1: new exists, old exists, new is the same as old
|
|
491
|
-
// Call the protocol event callbacks for dragging over the receiver.
|
|
492
|
-
draggedProtocol.onDragOver?.(eventData);
|
|
493
|
-
receiverProtocol.onReceiveDragOver?.(eventData);
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
// Case 2: new exists, old exists, new is different from old
|
|
497
|
-
// Prepare event data with old receiver.
|
|
498
|
-
const eventDataOldReceiver = {
|
|
499
|
-
...dragEventData,
|
|
500
|
-
receiver: {
|
|
501
|
-
id: oldReceiver.id,
|
|
502
|
-
parentId: oldReceiver.data.parentId,
|
|
503
|
-
payload: oldReceiver.data.protocol.receiverPayload,
|
|
504
|
-
receiveOffset: oldReceiver.tracking.receiveOffset,
|
|
505
|
-
receiveOffsetRatio: oldReceiver.tracking.receiveOffsetRatio,
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
// Call the protocol event callbacks for exiting the old receiver...
|
|
509
|
-
draggedProtocol.onDragExit?.(eventDataOldReceiver);
|
|
510
|
-
oldReceiver.data.protocol.onReceiveDragExit?.({
|
|
511
|
-
...eventDataOldReceiver,
|
|
512
|
-
cancelled: false,
|
|
513
|
-
});
|
|
514
|
-
// ...and entering the new receiver.
|
|
515
|
-
draggedProtocol.onDragEnter?.(eventData);
|
|
516
|
-
receiverProtocol.onReceiveDragEnter?.(eventData);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
else {
|
|
520
|
-
// Case 3: new exists, old does not exist
|
|
521
|
-
// Call the protocol event callbacks for entering the new receiver.
|
|
522
|
-
draggedProtocol.onDragEnter?.(eventData);
|
|
523
|
-
receiverProtocol.onReceiveDragEnter?.(eventData);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
else if (oldReceiver) {
|
|
527
|
-
// Case 4: new does not exist, old exists
|
|
528
|
-
// Reset the old receiver.
|
|
529
|
-
resetReceiver();
|
|
530
|
-
// Prepare event data with old receiver.
|
|
531
|
-
const eventData = {
|
|
532
|
-
...dragEventData,
|
|
533
|
-
receiver: {
|
|
534
|
-
id: oldReceiver.id,
|
|
535
|
-
parentId: oldReceiver.data.parentId,
|
|
536
|
-
payload: oldReceiver.data.protocol.receiverPayload,
|
|
537
|
-
receiveOffset: oldReceiver.tracking.receiveOffset,
|
|
538
|
-
receiveOffsetRatio: oldReceiver.tracking.receiveOffsetRatio,
|
|
539
|
-
},
|
|
540
|
-
};
|
|
541
|
-
// Call the protocol event callbacks for exiting the old receiver.
|
|
542
|
-
draggedProtocol.onDragExit?.(eventData);
|
|
543
|
-
oldReceiver.data.protocol.onReceiveDragExit?.({
|
|
544
|
-
...eventData,
|
|
545
|
-
cancelled: false,
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
// Case 5: new does not exist, old does not exist
|
|
550
|
-
// Call the protocol event callback for dragging.
|
|
551
|
-
draggedProtocol.onDrag?.(dragEventData);
|
|
552
|
-
}
|
|
553
|
-
// Notify monitors and update monitor tracking, if necessary.
|
|
554
|
-
const prevMonitorIds = getTrackingMonitorIds();
|
|
555
|
-
if (monitors.length > 0 || prevMonitorIds.length > 0) {
|
|
556
|
-
const newMonitorIds = monitors.map(({ id: monitorId, data: monitorData, relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio, }) => {
|
|
557
|
-
const monitorEventData = {
|
|
558
|
-
...monitorEventDataStub,
|
|
559
|
-
monitorOffset,
|
|
560
|
-
monitorOffsetRatio,
|
|
561
|
-
};
|
|
562
|
-
if (prevMonitorIds.includes(monitorId)) {
|
|
563
|
-
// Drag was already over this monitor.
|
|
564
|
-
monitorData.protocol.onMonitorDragOver?.(monitorEventData);
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
// Drag is entering monitor.
|
|
568
|
-
monitorData.protocol.onMonitorDragEnter?.(monitorEventData);
|
|
569
|
-
}
|
|
570
|
-
return monitorId;
|
|
571
|
-
});
|
|
572
|
-
prevMonitorIds.filter((monitorId) => !newMonitorIds.includes(monitorId))
|
|
573
|
-
.forEach((monitorId) => {
|
|
574
|
-
// Drag has exited monitor.
|
|
575
|
-
const monitorData = getAbsoluteViewData(monitorId);
|
|
576
|
-
if (monitorData) {
|
|
577
|
-
const { relativePosition: monitorOffset, relativePositionRatio: monitorOffsetRatio, } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
|
|
578
|
-
monitorData.protocol.onMonitorDragExit?.({
|
|
579
|
-
...monitorEventDataStub,
|
|
580
|
-
monitorOffset,
|
|
581
|
-
monitorOffsetRatio,
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
setMonitorIds(newMonitorIds);
|
|
586
|
-
}
|
|
587
|
-
}, [
|
|
588
|
-
getAbsoluteViewData,
|
|
589
|
-
getDragPositionData,
|
|
665
|
+
parentPosition.value = { x: parentX, y: parentY };
|
|
666
|
+
(0, react_native_reanimated_1.runOnJS)(throttledHandleGestureEvent)({ x: parentX, y: parentY });
|
|
667
|
+
}, [parentPosition, throttledHandleGestureEvent]);
|
|
668
|
+
const contextValue = {
|
|
669
|
+
getReleaseViews,
|
|
670
|
+
dragPositionDataSV,
|
|
671
|
+
startPosition,
|
|
672
|
+
parentPosition,
|
|
590
673
|
getTrackingDragged,
|
|
591
674
|
getTrackingReceiver,
|
|
592
|
-
getTrackingMonitorIds,
|
|
593
|
-
findMonitorsAndReceiver,
|
|
594
|
-
resetReceiver,
|
|
595
|
-
updateDragPosition,
|
|
596
675
|
updateReceiver,
|
|
676
|
+
resetReceiver,
|
|
677
|
+
getTrackingMonitorIds,
|
|
678
|
+
getAbsoluteViewData,
|
|
597
679
|
setMonitorIds,
|
|
598
|
-
|
|
599
|
-
]);
|
|
600
|
-
const contextValue = {
|
|
680
|
+
findMonitorsAndReceiver,
|
|
601
681
|
getViewState,
|
|
602
682
|
getTrackingStatus,
|
|
603
683
|
registerView,
|
|
604
684
|
unregisterView,
|
|
605
685
|
updateViewProtocol,
|
|
606
686
|
updateViewMeasurements,
|
|
607
|
-
|
|
687
|
+
updateHoverViewMeasurements,
|
|
608
688
|
handleGestureEvent,
|
|
609
|
-
|
|
689
|
+
handleGestureStateChange,
|
|
690
|
+
rootViewRef,
|
|
610
691
|
};
|
|
611
|
-
const
|
|
612
|
-
const
|
|
613
|
-
getHoverItems().forEach(({ id, key, internalRenderHoverView, hoverPosition, dimensions, }) => {
|
|
614
|
-
const viewState = getViewState(id);
|
|
615
|
-
if (viewState) {
|
|
616
|
-
const hoverView = internalRenderHoverView({
|
|
617
|
-
key,
|
|
618
|
-
hoverPosition,
|
|
619
|
-
viewState,
|
|
620
|
-
trackingStatus,
|
|
621
|
-
dimensions,
|
|
622
|
-
});
|
|
623
|
-
if (hoverView) {
|
|
624
|
-
hoverViews.push(hoverView);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
});
|
|
628
|
-
const setRootNodeHandleRef = (0, react_1.useCallback)((ref) => {
|
|
629
|
-
rootNodeHandleRef.current = ref && (0, react_native_1.findNodeHandle)(ref);
|
|
630
|
-
}, []);
|
|
692
|
+
const allViewStates = (0, react_1.useMemo)(() => getAllViewIds(), [getAllViewIds]);
|
|
693
|
+
const hoverViews = (0, react_1.useMemo)(() => getHoverItems(allViewStates).map((viewData, index) => viewData && (react_1.default.createElement(HoverView_1.HoverView, { key: viewData.id || index, ...(viewData?.protocol || {}), id: viewData.id, scrollPosition: viewData?.scrollPosition, scrollPositionOffset: viewData?.scrollPositionOffset }))), [allViewStates, getHoverItems]);
|
|
631
694
|
return (react_1.default.createElement(DraxContext_1.DraxContext.Provider, { value: contextValue },
|
|
632
|
-
react_1.default.createElement(react_native_1.View, { style: style, ref:
|
|
695
|
+
react_1.default.createElement(react_native_1.View, { style: style, ref: rootViewRef },
|
|
633
696
|
children,
|
|
634
|
-
|
|
697
|
+
hoverViews)));
|
|
635
698
|
};
|
|
636
699
|
exports.DraxProvider = DraxProvider;
|
|
637
700
|
const styles = react_native_1.StyleSheet.create({
|