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.
Files changed (47) hide show
  1. package/.eslintrc.js +2 -73
  2. package/.prettierrc +16 -0
  3. package/README.md +81 -1
  4. package/build/AllHoverViews.d.ts +0 -0
  5. package/build/AllHoverViews.js +30 -0
  6. package/build/DraxContext.d.ts +0 -1
  7. package/build/DraxList.d.ts +3 -3
  8. package/build/DraxList.js +231 -216
  9. package/build/DraxListItem.d.ts +7 -0
  10. package/build/DraxListItem.js +121 -0
  11. package/build/DraxProvider.d.ts +1 -3
  12. package/build/DraxProvider.js +322 -259
  13. package/build/DraxScrollView.d.ts +1 -1
  14. package/build/DraxScrollView.js +29 -90
  15. package/build/DraxSubprovider.d.ts +2 -2
  16. package/build/DraxSubprovider.js +1 -1
  17. package/build/DraxView.d.ts +7 -2
  18. package/build/DraxView.js +60 -383
  19. package/build/HoverView.d.ts +8 -0
  20. package/build/HoverView.js +40 -0
  21. package/build/PanGestureDetector.d.ts +3 -0
  22. package/build/PanGestureDetector.js +49 -0
  23. package/build/hooks/useContent.d.ts +23 -0
  24. package/build/hooks/useContent.js +212 -0
  25. package/build/hooks/useDraxProtocol.d.ts +5 -0
  26. package/build/hooks/useDraxProtocol.js +32 -0
  27. package/build/hooks/useDraxRegistry.d.ts +21 -20
  28. package/build/hooks/useDraxRegistry.js +195 -182
  29. package/build/hooks/useDraxScrollHandler.d.ts +25 -0
  30. package/build/hooks/useDraxScrollHandler.js +89 -0
  31. package/build/hooks/useDraxState.d.ts +1 -1
  32. package/build/hooks/useDraxState.js +9 -6
  33. package/build/hooks/useMeasurements.d.ts +9 -0
  34. package/build/hooks/useMeasurements.js +119 -0
  35. package/build/hooks/useStatus.d.ts +11 -0
  36. package/build/hooks/useStatus.js +96 -0
  37. package/build/index.d.ts +2 -0
  38. package/build/index.js +4 -1
  39. package/build/math.d.ts +2 -2
  40. package/build/math.js +10 -6
  41. package/build/params.d.ts +9 -0
  42. package/build/params.js +7 -1
  43. package/build/transform.d.ts +11 -4
  44. package/build/transform.js +50 -8
  45. package/build/types.d.ts +238 -87
  46. package/build/types.js +10 -7
  47. package/package.json +43 -45
@@ -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 hooks_1 = require("./hooks");
34
+ const react_native_reanimated_1 = require("react-native-reanimated");
31
35
  const DraxContext_1 = require("./DraxContext");
32
- const types_1 = require("./types");
36
+ const HoverView_1 = require("./HoverView");
37
+ const hooks_1 = require("./hooks");
33
38
  const math_1 = require("./math");
34
- const DraxProvider = ({ debug = false, style = styles.provider, children, }) => {
35
- const { getViewState, getTrackingStatus, dispatch, } = (0, hooks_1.useDraxState)();
36
- const { getAbsoluteViewData, getTrackingDragged, getTrackingReceiver, getTrackingMonitorIds, getTrackingMonitors, getDragPositionData, findMonitorsAndReceiver, getHoverItems, registerView, updateViewProtocol, updateViewMeasurements, resetReceiver, resetDrag, startDrag, updateDragPosition, updateReceiver, setMonitorIds, unregisterView, } = (0, hooks_1.useDraxRegistry)(dispatch);
37
- const rootNodeHandleRef = (0, react_1.useRef)(null);
38
- const handleGestureStateChange = (0, react_1.useCallback)((id, event) => {
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://github.com/kmagiera/react-native-gesture-handler/blob/master/docs/state.md
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, } = dragPositionData;
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
- receiveOffset: receiver.tracking.receiveOffset,
184
- receiveOffsetRatio: receiver.tracking.receiveOffsetRatio,
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, } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
207
- response = monitorData.protocol.onMonitorDragDrop?.({
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
- // If there is a receiver but drag was cancelled, let it know the drag exited it.
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, } = (0, math_1.getRelativePosition)(dragAbsolutePosition, monitorData.absoluteMeasurements);
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, } = startDrag({
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
- getTrackingDragged,
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
- if (debug) {
382
- console.log(`handleGestureEvent(${id}, ${JSON.stringify(event, null, 2)})`);
383
- }
384
- const dragged = getTrackingDragged();
385
- if (dragged === undefined) {
386
- // We're not tracking any gesture yet.
387
- if (debug) {
388
- console.log('Ignoring gesture event because we have not initialized a drag');
389
- }
390
- return;
391
- }
392
- if (dragged.id !== id) {
393
- // This is not a gesture we're tracking. We don't support multiple simultaneous drags.
394
- if (debug) {
395
- console.log('Ignoring gesture event because this is not the view being dragged');
396
- }
397
- return;
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
- console.log(`Dragged item absolute coordinates (${dragged.data.absoluteMeasurements.x}, ${dragged.data.absoluteMeasurements.y})`);
404
- console.log(`Native event in-view touch coordinates: (${event.x}, ${event.y})`);
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
- const parentPosition = { x: parentX, y: parentY };
408
- // Get the absolute position data for the drag touch.
409
- const dragPositionData = getDragPositionData({
410
- parentPosition,
411
- draggedMeasurements: dragged.data.absoluteMeasurements,
412
- lockXPosition: dragged.data.protocol.lockDragXPosition,
413
- lockYPosition: dragged.data.protocol.lockDragYPosition,
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
- debug,
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
- handleGestureStateChange,
687
+ updateHoverViewMeasurements,
608
688
  handleGestureEvent,
609
- rootNodeHandleRef,
689
+ handleGestureStateChange,
690
+ rootViewRef,
610
691
  };
611
- const hoverViews = [];
612
- const trackingStatus = getTrackingStatus();
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: setRootNodeHandleRef },
695
+ react_1.default.createElement(react_native_1.View, { style: style, ref: rootViewRef },
633
696
  children,
634
- react_1.default.createElement(react_native_1.View, { style: react_native_1.StyleSheet.absoluteFill, pointerEvents: "none" }, hoverViews))));
697
+ hoverViews)));
635
698
  };
636
699
  exports.DraxProvider = DraxProvider;
637
700
  const styles = react_native_1.StyleSheet.create({