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
@@ -2,16 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useDraxRegistry = void 0;
4
4
  const react_1 = require("react");
5
- const react_native_1 = require("react-native");
6
- const useDraxState_1 = require("./useDraxState");
7
- const types_1 = require("../types");
5
+ const react_native_reanimated_1 = require("react-native-reanimated");
8
6
  const math_1 = require("../math");
9
7
  const params_1 = require("../params");
8
+ const types_1 = require("../types");
9
+ const useDraxState_1 = require("./useDraxState");
10
10
  /*
11
11
  * The registry functions mutate their registry parameter, so let's
12
12
  * disable the "no parameter reassignment" rule for the entire file:
13
13
  */
14
- /* eslint-disable no-param-reassign */
15
14
  /** Create an initial empty Drax registry. */
16
15
  const createInitialRegistry = (stateDispatch) => ({
17
16
  stateDispatch,
@@ -26,9 +25,10 @@ const createInitialProtocol = () => ({
26
25
  draggable: false,
27
26
  receptive: false,
28
27
  monitoring: false,
28
+ hoverPosition: params_1.INITIAL_REANIMATED_POSITION,
29
29
  });
30
30
  /** Get data for a registered view by its id. */
31
- const getViewDataFromRegistry = (registry, id) => ((id && registry.viewIds.includes(id)) ? registry.viewDataById[id] : undefined);
31
+ const getViewDataFromRegistry = (registry, id) => id && registry.viewIds.includes(id) ? registry.viewDataById[id] : undefined;
32
32
  /** Get absolute measurements for a registered view, incorporating parents and clipping. */
33
33
  const getAbsoluteMeasurementsForViewFromRegistry = (registry, { measurements, parentId }, clipped = false) => {
34
34
  if (!measurements) {
@@ -48,9 +48,12 @@ const getAbsoluteMeasurementsForViewFromRegistry = (registry, { measurements, pa
48
48
  // console.log(`Failed to get absolute measurements for view: no absolute measurements for parent id ${parentId}`);
49
49
  return undefined;
50
50
  }
51
- const { x, y, width, height, } = measurements;
52
- const { x: parentX, y: parentY, } = parentMeasurements;
53
- const { x: offsetX, y: offsetY } = parentViewData.scrollPositionRef?.current || { x: 0, y: 0 };
51
+ const { x, y, width, height } = measurements;
52
+ const { x: parentX, y: parentY } = parentMeasurements;
53
+ const { x: offsetX, y: offsetY } = parentViewData.protocol.scrollPositionValue || {
54
+ x: 0,
55
+ y: 0,
56
+ };
54
57
  const abs = {
55
58
  width,
56
59
  height,
@@ -73,7 +76,7 @@ const getAbsoluteViewDataFromRegistry = (registry, id) => {
73
76
  }
74
77
  return {
75
78
  ...viewData,
76
- measurements: viewData.measurements,
79
+ measurements: viewData.measurements, // It must exist, since absoluteMeasurements is defined.
77
80
  absoluteMeasurements,
78
81
  };
79
82
  };
@@ -92,8 +95,9 @@ const getAbsoluteViewEntryFromRegistry = (registry, id) => {
92
95
  const findMonitorsAndReceiverInRegistry = (registry, absolutePosition, excludeViewId) => {
93
96
  const monitors = [];
94
97
  let receiver;
98
+ const excludedView = getViewDataFromRegistry(registry, excludeViewId);
95
99
  // console.log(`find monitors and receiver for absolute position (${absolutePosition.x}, ${absolutePosition.y})`);
96
- registry.viewIds.forEach((targetId) => {
100
+ registry.viewIds.forEach(targetId => {
97
101
  // console.log(`checking target id ${targetId}`);
98
102
  if (targetId === excludeViewId) {
99
103
  // Don't consider the excluded view.
@@ -125,7 +129,7 @@ const findMonitorsAndReceiverInRegistry = (registry, absolutePosition, excludeVi
125
129
  id: targetId,
126
130
  data: {
127
131
  ...target,
128
- measurements: target.measurements,
132
+ measurements: target.measurements, // It must exist, since absoluteMeasurements is defined.
129
133
  absoluteMeasurements,
130
134
  },
131
135
  ...(0, math_1.getRelativePosition)(absolutePosition, absoluteMeasurements),
@@ -135,7 +139,18 @@ const findMonitorsAndReceiverInRegistry = (registry, absolutePosition, excludeVi
135
139
  monitors.push(foundView);
136
140
  // console.log('it\'s a monitor');
137
141
  }
138
- if (receptive) {
142
+ const excludedAbsoluteViewData = excludedView && getAbsoluteMeasurementsForViewFromRegistry(registry, excludedView, true);
143
+ const targetDynamicReceptiveCondition = !target.protocol?.dynamicReceptiveCallback ||
144
+ (excludedAbsoluteViewData &&
145
+ target.protocol?.dynamicReceptiveCallback({
146
+ foundView,
147
+ excludedView: {
148
+ ...excludedView,
149
+ measurements: excludedView.measurements, // It must exist, since excludedAbsoluteViewData is defined.
150
+ absoluteMeasurements: excludedAbsoluteViewData,
151
+ },
152
+ }));
153
+ if (receptive && targetDynamicReceptiveCondition) {
139
154
  // It's the latest receiver found.
140
155
  receiver = foundView;
141
156
  // console.log('it\'s a receiver');
@@ -176,56 +191,33 @@ const getTrackingReceiverFromRegistry = (registry) => {
176
191
  return undefined;
177
192
  };
178
193
  /** Get ids for all currently monitoring views. */
179
- const getTrackingMonitorIdsFromRegistry = (registry) => (registry.drag?.monitorIds || []);
194
+ const getTrackingMonitorIdsFromRegistry = (registry) => registry.drag?.monitorIds || [];
180
195
  /** Get id and data for all currently monitoring views. */
181
- const getTrackingMonitorsFromRegistry = (registry) => (registry.drag?.monitorIds
182
- .map((id) => getAbsoluteViewEntryFromRegistry(registry, id))
183
- .filter((value) => !!value)
184
- || []);
196
+ const getTrackingMonitorsFromRegistry = (registry) => registry.drag?.monitorIds
197
+ .map(id => getAbsoluteViewEntryFromRegistry(registry, id))
198
+ .filter((value) => !!value) || [];
185
199
  /** Get the array of hover items for dragged and released views */
186
- const getHoverItemsFromRegistry = (registry) => {
187
- const hoverItems = [];
188
- // Find all released view hover items, in order from oldest to newest.
189
- registry.releaseIds.forEach((releaseId) => {
190
- const release = registry.releaseById[releaseId];
191
- if (release) {
192
- const { viewId, hoverPosition } = release;
193
- const releasedData = getAbsoluteViewDataFromRegistry(registry, viewId);
194
- if (releasedData) {
195
- const { protocol: { internalRenderHoverView }, measurements } = releasedData;
196
- if (internalRenderHoverView) {
197
- hoverItems.push({
198
- hoverPosition,
199
- internalRenderHoverView,
200
- key: releaseId,
201
- id: viewId,
202
- dimensions: (0, math_1.extractDimensions)(measurements),
203
- });
204
- }
205
- }
200
+ const getHoverItemsFromRegistry = (registry, viewIds) => {
201
+ return viewIds.map(viewId => {
202
+ const releaseData = Object.values(registry.releaseById).find(release => release.viewId === viewId);
203
+ const scrollPosition = releaseData?.scrollPosition;
204
+ const scrollPositionOffset = releaseData?.scrollPositionOffset;
205
+ const viewData = getViewDataFromRegistry(registry, viewId);
206
+ if (viewData) {
207
+ return {
208
+ id: viewId,
209
+ ...viewData,
210
+ scrollPosition,
211
+ scrollPositionOffset,
212
+ };
206
213
  }
207
214
  });
208
- // Find the currently dragged hover item.
209
- const { id: draggedId, data: draggedData } = getTrackingDraggedFromRegistry(registry) ?? {};
210
- if (draggedData) {
211
- const { protocol: { internalRenderHoverView }, measurements } = draggedData;
212
- if (draggedId && internalRenderHoverView) {
213
- hoverItems.push({
214
- internalRenderHoverView,
215
- key: `dragged-hover-${draggedId}`,
216
- id: draggedId,
217
- hoverPosition: registry.drag.hoverPosition,
218
- dimensions: (0, math_1.extractDimensions)(measurements),
219
- });
220
- }
221
- }
222
- return hoverItems;
223
215
  };
224
216
  /**
225
217
  * Get the absolute position of a drag already in progress from touch
226
218
  * coordinates within the immediate parent view of the dragged view.
227
219
  */
228
- const getDragPositionDataFromRegistry = (registry, { parentPosition, draggedMeasurements, lockXPosition = false, lockYPosition = false, }) => {
220
+ const getDragPositionDataFromRegistry = (registry, { parentPosition, draggedMeasurements, lockXPosition = false, lockYPosition = false }) => {
229
221
  if (!registry.drag) {
230
222
  return undefined;
231
223
  }
@@ -234,10 +226,10 @@ const getDragPositionDataFromRegistry = (registry, { parentPosition, draggedMeas
234
226
  * absolute coordinates of drag start
235
227
  * + translation offset of drag
236
228
  */
237
- const { absoluteStartPosition, parentStartPosition, } = registry.drag;
229
+ const { absoluteStartPosition, parentStartPosition } = registry.drag;
238
230
  const dragTranslation = {
239
- x: lockXPosition ? 0 : (parentPosition.x - parentStartPosition.x),
240
- y: lockYPosition ? 0 : (parentPosition.y - parentStartPosition.y),
231
+ x: lockXPosition ? 0 : parentPosition.x - parentStartPosition.x,
232
+ y: lockYPosition ? 0 : parentPosition.y - parentStartPosition.y,
241
233
  };
242
234
  const dragTranslationRatio = {
243
235
  x: dragTranslation.x / draggedMeasurements.width,
@@ -254,7 +246,7 @@ const getDragPositionDataFromRegistry = (registry, { parentPosition, draggedMeas
254
246
  };
255
247
  };
256
248
  /** Register a Drax view. */
257
- const registerViewInRegistry = (registry, { id, parentId, scrollPositionRef }) => {
249
+ const registerViewInRegistry = (registry, { id, parentId, scrollPosition }) => {
258
250
  const { viewIds, viewDataById, stateDispatch } = registry;
259
251
  // Make sure not to duplicate registered view id.
260
252
  if (viewIds.indexOf(id) < 0) {
@@ -265,7 +257,7 @@ const registerViewInRegistry = (registry, { id, parentId, scrollPositionRef }) =
265
257
  // console.log(`Register view ${id} with parent ${parentId}`);
266
258
  viewDataById[id] = {
267
259
  parentId,
268
- scrollPositionRef,
260
+ scrollPosition,
269
261
  protocol: existingData?.protocol ?? createInitialProtocol(),
270
262
  measurements: existingData?.measurements, // Starts undefined.
271
263
  };
@@ -286,8 +278,16 @@ const updateViewMeasurementsInRegistry = (registry, { id, measurements }) => {
286
278
  registry.viewDataById[id].measurements = measurements;
287
279
  }
288
280
  };
281
+ /** Update a view's measurements. */
282
+ const updateHoverViewMeasurementsInRegistry = (registry, { id, measurements }) => {
283
+ const existingData = getViewDataFromRegistry(registry, id);
284
+ if (existingData) {
285
+ // console.log(`Update ${id} measurements: @(${measurements?.x}, ${measurements?.y}) ${measurements?.width}x${measurements?.height}`);
286
+ registry.viewDataById[id].hoverMeasurements = measurements;
287
+ }
288
+ };
289
289
  /** Reset the receiver in drag tracking, if any. */
290
- const resetReceiverInRegistry = ({ drag, stateDispatch }) => {
290
+ const resetReceiverInRegistry = ({ drag }) => {
291
291
  if (!drag) {
292
292
  return;
293
293
  }
@@ -298,109 +298,156 @@ const resetReceiverInRegistry = ({ drag, stateDispatch }) => {
298
298
  }
299
299
  // console.log('clearing receiver');
300
300
  drag.receiver = undefined;
301
- stateDispatch(useDraxState_1.actions.updateTrackingStatus({ receiving: false }));
302
- stateDispatch(useDraxState_1.actions.updateViewState({
303
- id: draggedId,
304
- viewStateUpdate: {
305
- draggingOverReceiver: undefined,
306
- },
307
- }));
308
- stateDispatch(useDraxState_1.actions.updateViewState({
309
- id: receiver.receiverId,
310
- viewStateUpdate: {
311
- receiveStatus: types_1.DraxViewReceiveStatus.Inactive,
312
- receiveOffset: undefined,
313
- receiveOffsetRatio: undefined,
314
- receivingDrag: undefined,
315
- },
316
- }));
301
+ // stateDispatch(actions.updateTrackingStatus({ receiving: false }));
302
+ // stateDispatch(actions.updateViewState({
303
+ // id: draggedId,
304
+ // viewStateUpdate: {
305
+ // draggingOverReceiver: undefined,
306
+ // },
307
+ // }));
308
+ // stateDispatch(actions.updateViewState({
309
+ // id: receiver.receiverId,
310
+ // viewStateUpdate: {
311
+ // receiveStatus: DraxViewReceiveStatus.Inactive,
312
+ // receiveOffset: undefined,
313
+ // receiveOffsetRatio: undefined,
314
+ // receivingDrag: undefined,
315
+ // },
316
+ // }));
317
317
  };
318
318
  /** Track a new release, returning its unique identifier. */
319
319
  const createReleaseInRegistry = (registry, release) => {
320
320
  const releaseId = (0, math_1.generateRandomId)();
321
321
  registry.releaseIds.push(releaseId);
322
322
  registry.releaseById[releaseId] = release;
323
+ /**
324
+ * @todo remove BUG workaround
325
+ * @summary Force HoverView state to get the latest scrollPosition
326
+ */
327
+ registerViewInRegistry(registry, { id: 'fakefakefake' });
328
+ unregisterViewInRegistry(registry, { id: 'fakefakefake' });
323
329
  return releaseId;
324
330
  };
325
331
  /** Stop tracking a release, given its unique identifier. */
326
332
  const deleteReleaseInRegistry = (registry, releaseId) => {
327
- registry.releaseIds = registry.releaseIds.filter((id) => id !== releaseId);
333
+ registry.releaseIds = registry.releaseIds.filter(id => id !== releaseId);
328
334
  delete registry.releaseById[releaseId];
329
335
  };
336
+ /** Get the array of hover items for dragged and released views */
337
+ const getReleasesFromRegistry = (registry) => {
338
+ // Find all released view hover items, in order from oldest to newest.
339
+ return registry.releaseIds.map(releaseId => {
340
+ const release = registry.releaseById[releaseId];
341
+ const { viewId } = release;
342
+ return viewId;
343
+ });
344
+ };
330
345
  /** Reset drag tracking, if any. */
331
- const resetDragInRegistry = (registry, snapbackTarget = types_1.DraxSnapbackTargetPreset.Default) => {
332
- const { drag, stateDispatch } = registry;
346
+ const resetDragInRegistry = (registry, snapTarget = types_1.DraxSnapbackTargetPreset.Default) => {
347
+ const { drag } = registry;
333
348
  if (!drag) {
334
349
  return;
335
350
  }
351
+ const { draggedId, hoverPosition, receiver } = drag;
352
+ const receiverData = getAbsoluteViewDataFromRegistry(registry, receiver?.receiverId);
353
+ const receiverParentData = getAbsoluteViewDataFromRegistry(registry, receiverData?.parentId);
336
354
  resetReceiverInRegistry(registry);
337
- const { draggedId, hoverPosition } = drag;
338
355
  const draggedData = getAbsoluteViewDataFromRegistry(registry, draggedId);
339
356
  // Clear the drag.
340
- // console.log('clearing drag');
341
357
  registry.drag = undefined;
342
358
  // Determine if/where/how to snapback.
343
359
  let snapping = false;
344
- if (snapbackTarget !== types_1.DraxSnapbackTargetPreset.None && draggedData) {
345
- const { internalRenderHoverView, onSnapbackEnd, snapbackAnimator, animateSnapback = true, snapbackDelay = params_1.defaultSnapbackDelay, snapbackDuration = params_1.defaultSnapbackDuration, } = draggedData.protocol;
346
- if (internalRenderHoverView && animateSnapback) {
360
+ if (snapTarget !== types_1.DraxSnapbackTargetPreset.None && draggedData) {
361
+ const { onSnapEnd, snapAnimator, animateSnap = true, snapDelay = params_1.defaultSnapbackDelay, snapDuration = params_1.defaultSnapbackDuration, } = draggedData.protocol;
362
+ const parentData = getAbsoluteViewDataFromRegistry(registry, draggedData?.parentId);
363
+ const scrollPosition = (receiverData ? receiverParentData?.scrollPosition : parentData?.scrollPosition) ||
364
+ params_1.INITIAL_REANIMATED_POSITION;
365
+ if (animateSnap) {
347
366
  let toValue;
348
- if ((0, types_1.isPosition)(snapbackTarget)) {
367
+ if ((0, types_1.isPosition)(snapTarget)) {
349
368
  // Snapback to specified target.
350
- toValue = snapbackTarget;
369
+ toValue = snapTarget;
370
+ }
371
+ else if (receiverData) {
372
+ // Snap forward to the center of the receiver
373
+ toValue = {
374
+ x: receiverData.absoluteMeasurements.x +
375
+ receiverData.absoluteMeasurements.width / 2 -
376
+ draggedData.absoluteMeasurements.width / 2,
377
+ y: receiverData.absoluteMeasurements.y +
378
+ receiverData.absoluteMeasurements.height / 2 -
379
+ draggedData.absoluteMeasurements.height / 2,
380
+ };
351
381
  }
352
382
  else {
353
383
  // Snapback to default position (where original view is).
384
+ // console.log(
385
+ // " Snapback to default position (where original view is).",
386
+ // );
354
387
  toValue = {
355
388
  x: draggedData.absoluteMeasurements.x,
356
389
  y: draggedData.absoluteMeasurements.y,
357
390
  };
358
391
  }
359
- if (toValue && snapbackDuration > 0) {
392
+ if (toValue && snapDuration > 0) {
360
393
  snapping = true;
361
394
  // Add a release to tracking.
362
- const releaseId = createReleaseInRegistry(registry, { hoverPosition, viewId: draggedId });
395
+ const releaseId = createReleaseInRegistry(registry, {
396
+ hoverPosition,
397
+ viewId: draggedId,
398
+ scrollPosition,
399
+ scrollPositionOffset: {
400
+ x: scrollPosition.value.x,
401
+ y: scrollPosition.value.y,
402
+ },
403
+ });
404
+ const onSnapAnimationEnd = (_finished) => {
405
+ const snapPayload = {
406
+ dragged: { data: draggedData, ...drag },
407
+ receiver: receiver &&
408
+ receiverData && {
409
+ data: receiverData,
410
+ ...receiver,
411
+ },
412
+ };
413
+ delete snapPayload.dragged.receiver;
414
+ // // Call the snap end handlers, regardless of whether animation of finished.
415
+ onSnapEnd?.(snapPayload);
416
+ receiverData?.protocol?.onReceiveSnapEnd?.(snapPayload);
417
+ // Remove the release from tracking, regardless of whether animation finished.
418
+ deleteReleaseInRegistry(registry, releaseId);
419
+ // Resetting the hover position updates the view state for the released view to be inactive.
420
+ hoverPosition.value = { x: 0, y: 0 };
421
+ };
422
+ const finishedCallback = finished => {
423
+ 'worklet';
424
+ (0, react_native_reanimated_1.runOnJS)(onSnapAnimationEnd)(finished);
425
+ };
363
426
  // Animate the released hover snapback.
364
- let animation;
365
- if (snapbackAnimator) {
366
- animation = snapbackAnimator({
427
+ if (snapAnimator) {
428
+ snapAnimator({
367
429
  hoverPosition,
368
430
  toValue,
369
- delay: snapbackDelay,
370
- duration: snapbackDuration,
431
+ delay: snapDelay,
432
+ duration: snapDuration,
433
+ scrollPosition,
434
+ finishedCallback,
371
435
  });
372
436
  }
373
437
  else {
374
- animation = react_native_1.Animated.timing(hoverPosition, {
375
- toValue,
376
- delay: snapbackDelay,
377
- duration: snapbackDuration,
378
- useNativeDriver: true,
379
- });
438
+ hoverPosition.value = (0, react_native_reanimated_1.withDelay)(snapDelay, (0, react_native_reanimated_1.withTiming)(toValue, {
439
+ duration: snapDuration,
440
+ reduceMotion: react_native_reanimated_1.ReduceMotion.System,
441
+ }, finishedCallback), react_native_reanimated_1.ReduceMotion.System);
380
442
  }
381
- animation.start(({ finished }) => {
382
- // Remove the release from tracking, regardless of whether animation finished.
383
- deleteReleaseInRegistry(registry, releaseId);
384
- // Call the snapback end handler, regardless of whether animation of finished.
385
- onSnapbackEnd?.();
386
- // If the animation finished, update the view state for the released view to be inactive.
387
- if (finished) {
388
- stateDispatch(useDraxState_1.actions.updateViewState({
389
- id: draggedId,
390
- viewStateUpdate: {
391
- dragStatus: types_1.DraxViewDragStatus.Inactive,
392
- hoverPosition: undefined,
393
- grabOffset: undefined,
394
- grabOffsetRatio: undefined,
395
- },
396
- }));
397
- }
398
- });
399
443
  }
400
444
  }
401
445
  }
402
- // Update the drag tracking status.
403
- stateDispatch(useDraxState_1.actions.updateTrackingStatus({ dragging: false }));
446
+ else {
447
+ // Update the drag tracking status.
448
+ // Resetting the hover position updates the view state for the released view to be inactive.
449
+ hoverPosition.value = { x: 0, y: 0 };
450
+ }
404
451
  // Update the view state, data dependent on whether snapping back.
405
452
  const viewStateUpdate = {
406
453
  dragAbsolutePosition: undefined,
@@ -413,26 +460,23 @@ const resetDragInRegistry = (registry, snapbackTarget = types_1.DraxSnapbackTarg
413
460
  }
414
461
  else {
415
462
  viewStateUpdate.dragStatus = types_1.DraxViewDragStatus.Inactive;
416
- viewStateUpdate.hoverPosition = undefined;
417
463
  viewStateUpdate.grabOffset = undefined;
418
464
  viewStateUpdate.grabOffsetRatio = undefined;
465
+ hoverPosition.value = { x: 0, y: 0 };
419
466
  }
420
- stateDispatch(useDraxState_1.actions.updateViewState({
421
- viewStateUpdate,
422
- id: draggedId,
423
- }));
467
+ // stateDispatch(actions.updateViewState({
468
+ // viewStateUpdate,
469
+ // id: draggedId,
470
+ // }));
424
471
  };
425
472
  /** Start tracking a drag. */
426
- const startDragInRegistry = (registry, { dragAbsolutePosition, dragParentPosition, draggedId, grabOffset, grabOffsetRatio, }) => {
427
- const { stateDispatch } = registry;
473
+ const startDragInRegistry = (registry, { dragAbsolutePosition, dragParentPosition, draggedId, grabOffset, grabOffsetRatio }) => {
428
474
  resetDragInRegistry(registry);
429
475
  const dragTranslation = { x: 0, y: 0 };
430
476
  const dragTranslationRatio = { x: 0, y: 0 };
431
477
  const dragOffset = grabOffset;
432
- const hoverPosition = new react_native_1.Animated.ValueXY({
433
- x: dragAbsolutePosition.x - grabOffset.x,
434
- y: dragAbsolutePosition.y - grabOffset.y,
435
- });
478
+ const draggedData = getViewDataFromRegistry(registry, draggedId);
479
+ const hoverPosition = draggedData?.protocol.hoverPosition || params_1.INITIAL_REANIMATED_POSITION;
436
480
  registry.drag = {
437
481
  absoluteStartPosition: dragAbsolutePosition,
438
482
  parentStartPosition: dragParentPosition,
@@ -447,20 +491,6 @@ const startDragInRegistry = (registry, { dragAbsolutePosition, dragParentPositio
447
491
  receiver: undefined,
448
492
  monitorIds: [],
449
493
  };
450
- stateDispatch(useDraxState_1.actions.updateTrackingStatus({ dragging: true }));
451
- stateDispatch(useDraxState_1.actions.updateViewState({
452
- id: draggedId,
453
- viewStateUpdate: {
454
- dragAbsolutePosition,
455
- dragTranslation,
456
- dragTranslationRatio,
457
- dragOffset,
458
- grabOffset,
459
- grabOffsetRatio,
460
- hoverPosition,
461
- dragStatus: types_1.DraxViewDragStatus.Dragging,
462
- },
463
- }));
464
494
  return {
465
495
  dragAbsolutePosition,
466
496
  dragTranslation,
@@ -471,7 +501,7 @@ const startDragInRegistry = (registry, { dragAbsolutePosition, dragParentPositio
471
501
  };
472
502
  /** Update drag position. */
473
503
  const updateDragPositionInRegistry = (registry, dragAbsolutePosition) => {
474
- const { drag, stateDispatch } = registry;
504
+ const { drag } = registry;
475
505
  if (!drag) {
476
506
  return;
477
507
  }
@@ -480,7 +510,7 @@ const updateDragPositionInRegistry = (registry, dragAbsolutePosition) => {
480
510
  return;
481
511
  }
482
512
  const { absoluteMeasurements } = dragged.data;
483
- const { draggedId, grabOffset, hoverPosition } = drag;
513
+ const { grabOffset, hoverPosition } = drag;
484
514
  const dragTranslation = {
485
515
  x: dragAbsolutePosition.x - drag.absoluteStartPosition.x,
486
516
  y: dragAbsolutePosition.y - drag.absoluteStartPosition.y,
@@ -497,29 +527,19 @@ const updateDragPositionInRegistry = (registry, dragAbsolutePosition) => {
497
527
  drag.dragTranslation = dragTranslation;
498
528
  drag.dragTranslationRatio = dragTranslationRatio;
499
529
  drag.dragOffset = dragOffset;
500
- hoverPosition.setValue({
530
+ hoverPosition.value = {
501
531
  x: dragAbsolutePosition.x - grabOffset.x,
502
532
  y: dragAbsolutePosition.y - grabOffset.y,
503
- });
504
- stateDispatch(useDraxState_1.actions.updateViewState({
505
- id: draggedId,
506
- viewStateUpdate: {
507
- dragAbsolutePosition,
508
- dragTranslation,
509
- dragTranslationRatio,
510
- dragOffset,
511
- },
512
- }));
533
+ };
513
534
  };
514
535
  /** Update receiver for a drag. */
515
536
  const updateReceiverInRegistry = (registry, receiver, dragged) => {
516
- const { drag, stateDispatch } = registry;
537
+ const { drag } = registry;
517
538
  if (!drag) {
518
539
  return undefined;
519
540
  }
520
- const { relativePosition, relativePositionRatio, id: receiverId, data: receiverData, } = receiver;
521
- const { parentId: receiverParentId, protocol: { receiverPayload }, } = receiverData;
522
- const { id: draggedId, data: draggedData, } = dragged;
541
+ const { relativePosition, relativePositionRatio, id: receiverId } = receiver;
542
+ const { id: draggedId, data: draggedData } = dragged;
523
543
  const { parentId: draggedParentId, protocol: { dragPayload }, } = draggedData;
524
544
  const oldReceiver = drag.receiver;
525
545
  const receiveOffset = relativePosition;
@@ -529,6 +549,7 @@ const updateReceiverInRegistry = (registry, receiver, dragged) => {
529
549
  id: draggedId,
530
550
  parentId: draggedParentId,
531
551
  payload: dragPayload,
552
+ data: draggedData,
532
553
  },
533
554
  receiveOffset,
534
555
  receiveOffsetRatio,
@@ -542,7 +563,7 @@ const updateReceiverInRegistry = (registry, receiver, dragged) => {
542
563
  // New receiver.
543
564
  if (oldReceiver) {
544
565
  // Clear the old receiver.
545
- resetReceiverInRegistry(registry);
566
+ (0, react_native_reanimated_1.runOnJS)(resetReceiverInRegistry)(registry);
546
567
  }
547
568
  drag.receiver = {
548
569
  receiverId,
@@ -550,22 +571,7 @@ const updateReceiverInRegistry = (registry, receiver, dragged) => {
550
571
  receiveOffsetRatio,
551
572
  };
552
573
  receiverUpdate.receiveStatus = types_1.DraxViewReceiveStatus.Receiving;
553
- stateDispatch(useDraxState_1.actions.updateTrackingStatus({ receiving: true }));
554
574
  }
555
- stateDispatch(useDraxState_1.actions.updateViewState({
556
- id: receiverId,
557
- viewStateUpdate: receiverUpdate,
558
- }));
559
- stateDispatch(useDraxState_1.actions.updateViewState({
560
- id: draggedId,
561
- viewStateUpdate: {
562
- draggingOverReceiver: {
563
- id: receiverId,
564
- parentId: receiverParentId,
565
- payload: receiverPayload,
566
- },
567
- },
568
- }));
569
575
  return drag.receiver;
570
576
  };
571
577
  /** Set the monitors for a drag. */
@@ -577,7 +583,7 @@ const setMonitorIdsInRegistry = ({ drag }, monitorIds) => {
577
583
  /** Unregister a Drax view. */
578
584
  const unregisterViewInRegistry = (registry, { id }) => {
579
585
  const { [id]: removed, ...viewDataById } = registry.viewDataById;
580
- registry.viewIds = registry.viewIds.filter((thisId) => thisId !== id);
586
+ registry.viewIds = registry.viewIds.filter(thisId => thisId !== id);
581
587
  registry.viewDataById = viewDataById;
582
588
  if (registry.drag?.draggedId === id) {
583
589
  resetDragInRegistry(registry);
@@ -616,14 +622,14 @@ const useDraxRegistry = (stateDispatch) => {
616
622
  * Get the absolute position of a drag already in progress from touch
617
623
  * coordinates within the immediate parent view of the dragged view.
618
624
  */
619
- const getDragPositionData = (0, react_1.useCallback)((params) => (getDragPositionDataFromRegistry(registryRef.current, params)), []);
625
+ const getDragPositionData = (0, react_1.useCallback)((params) => getDragPositionDataFromRegistry(registryRef.current, params), []);
620
626
  /**
621
627
  * Find all monitoring views and the latest receptive view that
622
628
  * contain the touch coordinates, excluding the specified view.
623
629
  */
624
- const findMonitorsAndReceiver = (0, react_1.useCallback)((absolutePosition, excludeViewId) => (findMonitorsAndReceiverInRegistry(registryRef.current, absolutePosition, excludeViewId)), []);
630
+ const findMonitorsAndReceiver = (0, react_1.useCallback)((absolutePosition, excludeViewId) => findMonitorsAndReceiverInRegistry(registryRef.current, absolutePosition, excludeViewId), []);
625
631
  /** Get the array of hover items for dragged and released views */
626
- const getHoverItems = (0, react_1.useCallback)(() => getHoverItemsFromRegistry(registryRef.current), []);
632
+ const getHoverItems = (0, react_1.useCallback)((viewIds) => getHoverItemsFromRegistry(registryRef.current, viewIds), []);
627
633
  /**
628
634
  *
629
635
  * Imperative methods without state reactions (data management only).
@@ -633,6 +639,8 @@ const useDraxRegistry = (stateDispatch) => {
633
639
  const updateViewProtocol = (0, react_1.useCallback)((payload) => updateViewProtocolInRegistry(registryRef.current, payload), []);
634
640
  /** Update a view's measurements. */
635
641
  const updateViewMeasurements = (0, react_1.useCallback)((payload) => updateViewMeasurementsInRegistry(registryRef.current, payload), []);
642
+ /** Update a hover view's measurements. */
643
+ const updateHoverViewMeasurements = (0, react_1.useCallback)((payload) => updateHoverViewMeasurementsInRegistry(registryRef.current, payload), []);
636
644
  /**
637
645
  *
638
646
  * Imperative methods with potential state reactions.
@@ -647,15 +655,18 @@ const useDraxRegistry = (stateDispatch) => {
647
655
  /** Start tracking a drag. */
648
656
  const startDrag = (0, react_1.useCallback)((payload) => startDragInRegistry(registryRef.current, payload), []);
649
657
  /** Update drag position. */
650
- const updateDragPosition = (0, react_1.useCallback)((dragAbsolutePosition) => (updateDragPositionInRegistry(registryRef.current, dragAbsolutePosition)), []);
658
+ const updateDragPosition = (0, react_1.useCallback)((dragAbsolutePosition) => updateDragPositionInRegistry(registryRef.current, dragAbsolutePosition), []);
651
659
  /** Update the receiver for a drag. */
652
- const updateReceiver = (0, react_1.useCallback)((receiver, dragged) => (updateReceiverInRegistry(registryRef.current, receiver, dragged)), []);
660
+ const updateReceiver = (0, react_1.useCallback)((receiver, dragged) => updateReceiverInRegistry(registryRef.current, receiver, dragged), []);
653
661
  /** Set the monitors for a drag. */
654
662
  const setMonitorIds = (0, react_1.useCallback)((monitorIds) => setMonitorIdsInRegistry(registryRef.current, monitorIds), []);
655
663
  /** Unregister a Drax view. */
656
664
  const unregisterView = (0, react_1.useCallback)((payload) => unregisterViewInRegistry(registryRef.current, payload), []);
665
+ const getReleaseViews = (0, react_1.useCallback)(() => getReleasesFromRegistry(registryRef.current), []);
657
666
  /** Create the Drax registry object for return, only replacing reference when necessary. */
658
667
  const draxRegistry = (0, react_1.useMemo)(() => ({
668
+ registryRef,
669
+ getReleaseViews,
659
670
  getViewData,
660
671
  getAbsoluteViewData,
661
672
  getTrackingDragged,
@@ -668,6 +679,7 @@ const useDraxRegistry = (stateDispatch) => {
668
679
  registerView,
669
680
  updateViewProtocol,
670
681
  updateViewMeasurements,
682
+ updateHoverViewMeasurements,
671
683
  resetReceiver,
672
684
  resetDrag,
673
685
  startDrag,
@@ -688,6 +700,7 @@ const useDraxRegistry = (stateDispatch) => {
688
700
  registerView,
689
701
  updateViewProtocol,
690
702
  updateViewMeasurements,
703
+ updateHoverViewMeasurements,
691
704
  resetReceiver,
692
705
  resetDrag,
693
706
  startDrag,