@rootnative/impulse 0.0.0-alpha.0 → 0.0.0-alpha.1

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 (64) hide show
  1. package/CHANGELOG.md +51 -5
  2. package/README.md +206 -11
  3. package/dist/{chunk-5BMRKYVY.js → chunk-2UZTAWUQ.js} +20 -2
  4. package/dist/chunk-BNSFDNLA.js +75 -0
  5. package/dist/chunk-DXXGWG4Q.js +136 -0
  6. package/dist/{chunk-PMR25UCT.js → chunk-HGBCIL6X.js} +1 -1
  7. package/dist/chunk-HI5PHDJY.js +94 -0
  8. package/dist/{chunk-IG5RXCYR.js → chunk-IH7SQ5X6.js} +11 -15
  9. package/dist/chunk-MWCIEVTA.js +199 -0
  10. package/dist/{chunk-F4RHM4ZK.js → chunk-NYDDZD4G.js} +58 -1
  11. package/dist/chunk-PGOQSKEJ.js +144 -0
  12. package/dist/{chunk-FR242SUF.js → chunk-TGOGIZDH.js} +13 -7
  13. package/dist/chunk-VEPUHGPN.js +12 -0
  14. package/dist/chunk-YZHAQ4XK.js +136 -0
  15. package/dist/compose/index.d.ts +1 -1
  16. package/dist/double-tap/index.d.ts +184 -0
  17. package/dist/double-tap/index.js +5 -0
  18. package/dist/drag/index.d.ts +18 -13
  19. package/dist/drag/index.js +3 -3
  20. package/dist/index.d.ts +10 -3
  21. package/dist/index.js +12 -5
  22. package/dist/long-press/index.d.ts +219 -0
  23. package/dist/long-press/index.js +4 -0
  24. package/dist/pan/index.d.ts +221 -0
  25. package/dist/pan/index.js +4 -0
  26. package/dist/pinch/index.d.ts +239 -0
  27. package/dist/pinch/index.js +4 -0
  28. package/dist/raw/index.d.ts +3 -3
  29. package/dist/raw/index.js +2 -2
  30. package/dist/rotate/index.d.ts +263 -0
  31. package/dist/rotate/index.js +4 -0
  32. package/dist/swipe/index.d.ts +254 -0
  33. package/dist/swipe/index.js +4 -0
  34. package/dist/tap/index.d.ts +34 -29
  35. package/dist/tap/index.js +4 -3
  36. package/dist/tapEvent-KSSojt_l.d.ts +28 -0
  37. package/dist/{types-Ch2HM3aP.d.ts → types-ChGKY28a.d.ts} +27 -1
  38. package/dist/{useGestureMemo-Ccv8rB0C.d.ts → useGestureMemo-BRW1EKcJ.d.ts} +1 -1
  39. package/jest-setup.cjs +32 -1
  40. package/llms.txt +155 -0
  41. package/package.json +35 -2
  42. package/src/index.ts +50 -4
  43. package/src/intents/double-tap/index.ts +6 -0
  44. package/src/intents/long-press/index.ts +6 -0
  45. package/src/intents/pan/index.ts +2 -0
  46. package/src/intents/pinch/index.ts +2 -0
  47. package/src/intents/rotate/index.ts +6 -0
  48. package/src/intents/swipe/index.ts +8 -0
  49. package/src/intents/tapEvent.ts +50 -0
  50. package/src/intents/useDoubleTap.ts +321 -0
  51. package/src/intents/useDrag.ts +49 -28
  52. package/src/intents/useLongPress.ts +391 -0
  53. package/src/intents/usePan.ts +444 -0
  54. package/src/intents/usePinch.ts +483 -0
  55. package/src/intents/useRotate.ts +507 -0
  56. package/src/intents/useSwipe.ts +585 -0
  57. package/src/intents/useTap.ts +51 -60
  58. package/src/internal/intentResult.ts +67 -0
  59. package/src/internal/phaseCallbacks.ts +51 -0
  60. package/src/internal/useGestureMemo.ts +32 -4
  61. package/src/internal/useLatestCallback.ts +2 -2
  62. package/src/raw/useRawGesture.ts +1 -1
  63. package/src/relations/index.ts +94 -0
  64. package/src/types.ts +27 -0
@@ -1,4 +1,4 @@
1
- import { useGestureMemo } from './chunk-F4RHM4ZK.js';
1
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
2
2
 
3
3
  // src/raw/useRawGesture.ts
4
4
  function useRawGesture(build, deps, options) {
@@ -0,0 +1,94 @@
1
+ import { useStableRecord, useLatestCallback, buildIntentResult } from './chunk-2UZTAWUQ.js';
2
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
3
+ import { useMemo } from 'react';
4
+ import { Gesture } from 'react-native-gesture-handler';
5
+ import { useSharedValue } from 'react-native-reanimated';
6
+ import { scheduleOnRN } from 'react-native-worklets';
7
+
8
+ var DEFAULT_MIN_DURATION = 500;
9
+ var DEFAULT_MAX_DISTANCE = 10;
10
+ function toLongPressEvent(event) {
11
+ "worklet";
12
+ return {
13
+ x: event.x,
14
+ y: event.y,
15
+ absolute: { x: event.absoluteX, y: event.absoluteY },
16
+ duration: event.duration,
17
+ pointers: event.numberOfPointers
18
+ };
19
+ }
20
+ function useLongPress(options = {}) {
21
+ const {
22
+ minDuration = DEFAULT_MIN_DURATION,
23
+ maxDistance = DEFAULT_MAX_DISTANCE,
24
+ pointers,
25
+ enabled,
26
+ onLongPress,
27
+ onLongPressEnd,
28
+ onBegin,
29
+ onFinalize
30
+ } = options;
31
+ const isActive = useSharedValue(false);
32
+ const hitSlop = useStableRecord(options.hitSlop);
33
+ const handleLongPress = useLatestCallback(onLongPress);
34
+ const handleLongPressEnd = useLatestCallback(onLongPressEnd);
35
+ const hasLongPress = onLongPress !== void 0;
36
+ const hasLongPressEnd = onLongPressEnd !== void 0;
37
+ const built = useGestureMemo(
38
+ "useLongPress",
39
+ () => {
40
+ const press = Gesture.LongPress().minDuration(minDuration).maxDistance(maxDistance).onBegin((event) => {
41
+ "worklet";
42
+ onBegin?.(toLongPressEvent(event));
43
+ }).onStart((event) => {
44
+ "worklet";
45
+ isActive.value = true;
46
+ if (hasLongPress) {
47
+ scheduleOnRN(handleLongPress, toLongPressEvent(event));
48
+ }
49
+ }).onEnd((event, success) => {
50
+ "worklet";
51
+ if (hasLongPressEnd) {
52
+ scheduleOnRN(handleLongPressEnd, toLongPressEvent(event), {
53
+ cancelled: !success
54
+ });
55
+ }
56
+ }).onFinalize((event, success) => {
57
+ "worklet";
58
+ isActive.value = false;
59
+ onFinalize?.(toLongPressEvent(event), success);
60
+ });
61
+ if (pointers !== void 0) {
62
+ press.numberOfPointers(pointers);
63
+ }
64
+ if (hitSlop !== void 0) {
65
+ press.hitSlop(hitSlop);
66
+ }
67
+ if (enabled !== void 0) {
68
+ press.enabled(enabled);
69
+ }
70
+ return press;
71
+ },
72
+ [
73
+ minDuration,
74
+ maxDistance,
75
+ pointers,
76
+ hitSlop,
77
+ enabled,
78
+ hasLongPress,
79
+ hasLongPressEnd,
80
+ handleLongPress,
81
+ handleLongPressEnd,
82
+ isActive,
83
+ onBegin,
84
+ onFinalize
85
+ ],
86
+ options
87
+ );
88
+ return useMemo(
89
+ () => buildIntentResult(built, { isActive }),
90
+ [built, isActive]
91
+ );
92
+ }
93
+
94
+ export { useLongPress };
@@ -1,20 +1,13 @@
1
- import { useStableRecord, useLatestCallback } from './chunk-5BMRKYVY.js';
2
- import { useGestureMemo } from './chunk-F4RHM4ZK.js';
1
+ import { toTapEvent } from './chunk-VEPUHGPN.js';
2
+ import { useStableRecord, useLatestCallback, buildIntentResult } from './chunk-2UZTAWUQ.js';
3
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
3
4
  import { useMemo } from 'react';
4
5
  import { Gesture } from 'react-native-gesture-handler';
5
- import { useSharedValue, runOnJS } from 'react-native-reanimated';
6
+ import { useSharedValue } from 'react-native-reanimated';
7
+ import { scheduleOnRN } from 'react-native-worklets';
6
8
 
7
9
  var DEFAULT_MAX_DURATION = 500;
8
10
  var DEFAULT_MAX_DISTANCE = 10;
9
- function toTapEvent(event) {
10
- "worklet";
11
- return {
12
- x: event.x,
13
- y: event.y,
14
- absolute: { x: event.absoluteX, y: event.absoluteY },
15
- pointers: event.numberOfPointers
16
- };
17
- }
18
11
  function useTap(options = {}) {
19
12
  const {
20
13
  pointers = 1,
@@ -38,8 +31,8 @@ function useTap(options = {}) {
38
31
  onBegin?.(toTapEvent(event));
39
32
  }).onEnd((event, success) => {
40
33
  "worklet";
41
- if (success && hasTapHandler) {
42
- runOnJS(handleTap)(toTapEvent(event));
34
+ if (hasTapHandler) {
35
+ scheduleOnRN(handleTap, toTapEvent(event), { cancelled: !success });
43
36
  }
44
37
  }).onFinalize((event, success) => {
45
38
  "worklet";
@@ -68,7 +61,10 @@ function useTap(options = {}) {
68
61
  ],
69
62
  options
70
63
  );
71
- return useMemo(() => ({ ...built, isActive }), [built, isActive]);
64
+ return useMemo(
65
+ () => buildIntentResult(built, { isActive }),
66
+ [built, isActive]
67
+ );
72
68
  }
73
69
 
74
70
  export { useTap };
@@ -0,0 +1,199 @@
1
+ import { useStableRecord, useLatestCallback, buildIntentResult } from './chunk-2UZTAWUQ.js';
2
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
3
+ import { useStableList } from './chunk-ZX7WNICB.js';
4
+ import { useMemo } from 'react';
5
+ import { Gesture } from 'react-native-gesture-handler';
6
+ import { useSharedValue } from 'react-native-reanimated';
7
+ import { scheduleOnRN } from 'react-native-worklets';
8
+
9
+ var DEFAULT_THRESHOLD = 10;
10
+ var DEFAULT_COMMIT_DISTANCE = 80;
11
+ var DEFAULT_COMMIT_SPEED = 800;
12
+ var ALL_DIRECTIONS = [
13
+ "left",
14
+ "right",
15
+ "up",
16
+ "down"
17
+ ];
18
+ function pickDirection(translationX, translationY, velocityX, velocityY, commitDistance, commitSpeed, allowLeft, allowRight, allowUp, allowDown) {
19
+ "worklet";
20
+ const distanceX = Math.abs(translationX);
21
+ const distanceY = Math.abs(translationY);
22
+ if (distanceX >= distanceY) {
23
+ if (distanceX < commitDistance && Math.abs(velocityX) < commitSpeed) {
24
+ return null;
25
+ }
26
+ if (translationX < 0) {
27
+ return allowLeft ? "left" : null;
28
+ }
29
+ if (translationX > 0) {
30
+ return allowRight ? "right" : null;
31
+ }
32
+ return null;
33
+ }
34
+ if (distanceY < commitDistance && Math.abs(velocityY) < commitSpeed) {
35
+ return null;
36
+ }
37
+ if (translationY < 0) {
38
+ return allowUp ? "up" : null;
39
+ }
40
+ if (translationY > 0) {
41
+ return allowDown ? "down" : null;
42
+ }
43
+ return null;
44
+ }
45
+ function useSwipe(options = {}) {
46
+ const {
47
+ threshold = DEFAULT_THRESHOLD,
48
+ commitDistance = DEFAULT_COMMIT_DISTANCE,
49
+ commitSpeed = DEFAULT_COMMIT_SPEED,
50
+ failOffset,
51
+ pointers,
52
+ enabled,
53
+ onSwipe,
54
+ onSwipeEnd,
55
+ onBegin,
56
+ onUpdate,
57
+ onFinalize
58
+ } = options;
59
+ const x = useSharedValue(0);
60
+ const y = useSharedValue(0);
61
+ const isActive = useSharedValue(false);
62
+ const originX = useSharedValue(0);
63
+ const originY = useSharedValue(0);
64
+ const hitSlop = useStableRecord(options.hitSlop);
65
+ const directions = useStableList(options.directions ?? ALL_DIRECTIONS);
66
+ const allowLeft = directions.includes("left");
67
+ const allowRight = directions.includes("right");
68
+ const allowUp = directions.includes("up");
69
+ const allowDown = directions.includes("down");
70
+ const hasHorizontal = allowLeft || allowRight;
71
+ const hasVertical = allowUp || allowDown;
72
+ const axis = hasHorizontal && !hasVertical ? "x" : hasVertical && !hasHorizontal ? "y" : null;
73
+ const handleSwipe = useLatestCallback(onSwipe);
74
+ const handleSwipeEnd = useLatestCallback(onSwipeEnd);
75
+ const hasSwipe = onSwipe !== void 0;
76
+ const hasSwipeEnd = onSwipeEnd !== void 0;
77
+ const built = useGestureMemo(
78
+ "useSwipe",
79
+ () => {
80
+ const toSwipeEvent = (event, direction) => {
81
+ "worklet";
82
+ const translationX = x.value;
83
+ const translationY = y.value;
84
+ const horizontal = Math.abs(translationX) >= Math.abs(translationY);
85
+ return {
86
+ direction,
87
+ distance: Math.abs(horizontal ? translationX : translationY),
88
+ speed: Math.abs(horizontal ? event.velocityX : event.velocityY),
89
+ translation: { x: translationX, y: translationY },
90
+ velocity: { x: event.velocityX, y: event.velocityY },
91
+ absolute: { x: event.absoluteX, y: event.absoluteY },
92
+ pointers: event.numberOfPointers
93
+ };
94
+ };
95
+ const pan = Gesture.Pan().onBegin((event) => {
96
+ "worklet";
97
+ onBegin?.(toSwipeEvent(event, null));
98
+ }).onStart((event) => {
99
+ "worklet";
100
+ originX.value = event.translationX;
101
+ originY.value = event.translationY;
102
+ x.value = 0;
103
+ y.value = 0;
104
+ isActive.value = true;
105
+ }).onUpdate((event) => {
106
+ "worklet";
107
+ x.value = event.translationX - originX.value;
108
+ y.value = event.translationY - originY.value;
109
+ onUpdate?.(toSwipeEvent(event, null));
110
+ }).onEnd((event, success) => {
111
+ "worklet";
112
+ const direction = success ? pickDirection(
113
+ x.value,
114
+ y.value,
115
+ event.velocityX,
116
+ event.velocityY,
117
+ commitDistance,
118
+ commitSpeed,
119
+ allowLeft,
120
+ allowRight,
121
+ allowUp,
122
+ allowDown
123
+ ) : null;
124
+ if (direction !== null && hasSwipe) {
125
+ scheduleOnRN(
126
+ handleSwipe,
127
+ toSwipeEvent(event, direction)
128
+ );
129
+ }
130
+ if (hasSwipeEnd) {
131
+ scheduleOnRN(handleSwipeEnd, toSwipeEvent(event, direction), {
132
+ cancelled: !success
133
+ });
134
+ }
135
+ }).onFinalize((event, success) => {
136
+ "worklet";
137
+ isActive.value = false;
138
+ onFinalize?.(toSwipeEvent(event, null), success);
139
+ });
140
+ if (axis === "x") {
141
+ pan.activeOffsetX([-threshold, threshold]);
142
+ } else if (axis === "y") {
143
+ pan.activeOffsetY([-threshold, threshold]);
144
+ } else {
145
+ pan.minDistance(threshold);
146
+ }
147
+ if (failOffset !== void 0) {
148
+ if (axis === "x") {
149
+ pan.failOffsetY([-failOffset, failOffset]);
150
+ } else if (axis === "y") {
151
+ pan.failOffsetX([-failOffset, failOffset]);
152
+ }
153
+ }
154
+ if (pointers !== void 0) {
155
+ pan.minPointers(pointers).maxPointers(pointers);
156
+ }
157
+ if (hitSlop !== void 0) {
158
+ pan.hitSlop(hitSlop);
159
+ }
160
+ if (enabled !== void 0) {
161
+ pan.enabled(enabled);
162
+ }
163
+ return pan;
164
+ },
165
+ [
166
+ axis,
167
+ threshold,
168
+ commitDistance,
169
+ commitSpeed,
170
+ failOffset,
171
+ pointers,
172
+ hitSlop,
173
+ enabled,
174
+ allowLeft,
175
+ allowRight,
176
+ allowUp,
177
+ allowDown,
178
+ hasSwipe,
179
+ hasSwipeEnd,
180
+ handleSwipe,
181
+ handleSwipeEnd,
182
+ x,
183
+ y,
184
+ originX,
185
+ originY,
186
+ isActive,
187
+ onBegin,
188
+ onUpdate,
189
+ onFinalize
190
+ ],
191
+ options
192
+ );
193
+ return useMemo(
194
+ () => buildIntentResult(built, { x, y, isActive }),
195
+ [built, x, y, isActive]
196
+ );
197
+ }
198
+
199
+ export { useSwipe };
@@ -1,5 +1,6 @@
1
1
  import { useStableList, isDevBuild, warnOnce } from './chunk-ZX7WNICB.js';
2
- import { useRef, useMemo } from 'react';
2
+ import { useRef, useMemo, useEffect } from 'react';
3
+ import { isWorkletFunction } from 'react-native-worklets';
3
4
 
4
5
  // src/relations/index.ts
5
6
  var RELATIONS = [
@@ -16,6 +17,37 @@ function applyRelations(gesture, relations, hookName) {
16
17
  }
17
18
  }
18
19
  }
20
+ function hasHandlerTag(candidate) {
21
+ const tag = candidate.handlerTag;
22
+ return typeof tag === "number" && tag > 0;
23
+ }
24
+ function isUnresolvable(reference) {
25
+ if (typeof reference !== "object" || reference === null) {
26
+ return false;
27
+ }
28
+ if (!("current" in reference)) {
29
+ return false;
30
+ }
31
+ const current = reference.current;
32
+ if (current === null || current === void 0) {
33
+ return false;
34
+ }
35
+ return !hasHandlerTag(current);
36
+ }
37
+ function warnOnUnresolvableReferences(relations, hookName) {
38
+ if (!isDevBuild()) {
39
+ return;
40
+ }
41
+ for (const [option] of RELATIONS) {
42
+ if (!relations[option].some(isUnresolvable)) {
43
+ continue;
44
+ }
45
+ warnOnce(
46
+ `relations:untagged:${hookName}:${option}`,
47
+ `${hookName} received a \`${option}\` reference to a component that owns no gesture, so gesture-handler dropped the relation. The gesture still works and the two still conflict \u2014 nothing reports it at runtime. React Native's own \`ScrollView\` and \`FlatList\` are the usual cause: they carry no handler tag. Import \`ScrollView\` or \`FlatList\` from \`@rootnative/impulse/gesture-handler\` and put the ref on that component instead.`
48
+ );
49
+ }
50
+ }
19
51
  function warnOnConflictingRelations(relations, hookName) {
20
52
  if (!isDevBuild()) {
21
53
  return;
@@ -41,6 +73,22 @@ function warnOnConflictingRelations(relations, hookName) {
41
73
  }
42
74
  }
43
75
  }
76
+ var PHASE_CALLBACKS = ["onBegin", "onUpdate", "onFinalize"];
77
+ function warnOnPlainPhaseCallbacks(callbacks, hookName) {
78
+ if (!isDevBuild() || typeof isWorkletFunction !== "function") {
79
+ return;
80
+ }
81
+ for (const name of PHASE_CALLBACKS) {
82
+ const callback = callbacks[name];
83
+ if (typeof callback !== "function" || isWorkletFunction(callback)) {
84
+ continue;
85
+ }
86
+ warnOnce(
87
+ `worklets:plain:${hookName}:${name}`,
88
+ `${hookName} received an \`${name}\` that is not a worklet, and \`${name}\` runs on the UI thread. Add the 'worklet' directive as the first statement of the function. Without it, iOS and Android throw "Tried to synchronously call a Remote Function" when the gesture reaches that phase. For code that must run on the JS thread, such as a React state update, use the hook's intent callback instead.`
89
+ );
90
+ }
91
+ }
44
92
 
45
93
  // src/internal/useGestureMemo.ts
46
94
  function useGestureMemo(hookName, build, deps, options) {
@@ -48,6 +96,9 @@ function useGestureMemo(hookName, build, deps, options) {
48
96
  const blocks = useStableList(options?.blocks);
49
97
  const deferTo = useStableList(options?.deferTo);
50
98
  const testId = options?.testId;
99
+ const onBegin = options?.onBegin;
100
+ const onUpdate = options?.onUpdate;
101
+ const onFinalize = options?.onFinalize;
51
102
  const ref = useRef(void 0);
52
103
  const gesture = useMemo(
53
104
  () => {
@@ -71,6 +122,12 @@ function useGestureMemo(hookName, build, deps, options) {
71
122
  // eslint-disable-next-line react-hooks/exhaustive-deps
72
123
  [...deps, alongside, blocks, deferTo, testId, hookName]
73
124
  );
125
+ useEffect(() => {
126
+ warnOnUnresolvableReferences({ alongside, blocks, deferTo }, hookName);
127
+ }, [alongside, blocks, deferTo, hookName]);
128
+ useEffect(() => {
129
+ warnOnPlainPhaseCallbacks({ onBegin, onUpdate, onFinalize }, hookName);
130
+ }, [onBegin, onUpdate, onFinalize, hookName]);
74
131
  return useMemo(() => ({ gesture, ref }), [gesture]);
75
132
  }
76
133
 
@@ -0,0 +1,144 @@
1
+ import { useStableRecord, useLatestCallback, buildIntentResult } from './chunk-2UZTAWUQ.js';
2
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
3
+ import { useMemo } from 'react';
4
+ import { Gesture } from 'react-native-gesture-handler';
5
+ import { useSharedValue } from 'react-native-reanimated';
6
+ import { scheduleOnRN } from 'react-native-worklets';
7
+
8
+ var DEFAULT_THRESHOLD = 10;
9
+ function usePan(options = {}) {
10
+ const {
11
+ axis = "both",
12
+ threshold = DEFAULT_THRESHOLD,
13
+ failOffset,
14
+ pointers,
15
+ enabled,
16
+ onPanStart,
17
+ onPanEnd,
18
+ onBegin,
19
+ onUpdate,
20
+ onFinalize
21
+ } = options;
22
+ const x = useSharedValue(0);
23
+ const y = useSharedValue(0);
24
+ const isActive = useSharedValue(false);
25
+ const originX = useSharedValue(0);
26
+ const originY = useSharedValue(0);
27
+ const lastX = useSharedValue(0);
28
+ const lastY = useSharedValue(0);
29
+ const hitSlop = useStableRecord(options.hitSlop);
30
+ const movesX = axis !== "y";
31
+ const movesY = axis !== "x";
32
+ const handlePanStart = useLatestCallback(onPanStart);
33
+ const handlePanEnd = useLatestCallback(onPanEnd);
34
+ const hasPanStart = onPanStart !== void 0;
35
+ const hasPanEnd = onPanEnd !== void 0;
36
+ const built = useGestureMemo(
37
+ "usePan",
38
+ () => {
39
+ const toPanEvent = (event, changeX, changeY) => {
40
+ "worklet";
41
+ return {
42
+ translation: { x: x.value, y: y.value },
43
+ change: { x: changeX, y: changeY },
44
+ velocity: { x: event.velocityX, y: event.velocityY },
45
+ absolute: { x: event.absoluteX, y: event.absoluteY },
46
+ pointers: event.numberOfPointers
47
+ };
48
+ };
49
+ const pan = Gesture.Pan().onBegin((event) => {
50
+ "worklet";
51
+ onBegin?.(toPanEvent(event, 0, 0));
52
+ }).onStart((event) => {
53
+ "worklet";
54
+ originX.value = event.translationX;
55
+ originY.value = event.translationY;
56
+ lastX.value = 0;
57
+ lastY.value = 0;
58
+ x.value = 0;
59
+ y.value = 0;
60
+ isActive.value = true;
61
+ if (hasPanStart) {
62
+ scheduleOnRN(handlePanStart, toPanEvent(event, 0, 0));
63
+ }
64
+ }).onUpdate((event) => {
65
+ "worklet";
66
+ const nextX = movesX ? event.translationX - originX.value : 0;
67
+ const nextY = movesY ? event.translationY - originY.value : 0;
68
+ const changeX = nextX - lastX.value;
69
+ const changeY = nextY - lastY.value;
70
+ lastX.value = nextX;
71
+ lastY.value = nextY;
72
+ x.value = nextX;
73
+ y.value = nextY;
74
+ onUpdate?.(toPanEvent(event, changeX, changeY));
75
+ }).onEnd((event, success) => {
76
+ "worklet";
77
+ if (hasPanEnd) {
78
+ scheduleOnRN(handlePanEnd, toPanEvent(event, 0, 0), {
79
+ cancelled: !success
80
+ });
81
+ }
82
+ }).onFinalize((event, success) => {
83
+ "worklet";
84
+ isActive.value = false;
85
+ onFinalize?.(toPanEvent(event, 0, 0), success);
86
+ });
87
+ if (axis === "x") {
88
+ pan.activeOffsetX([-threshold, threshold]);
89
+ } else if (axis === "y") {
90
+ pan.activeOffsetY([-threshold, threshold]);
91
+ } else {
92
+ pan.minDistance(threshold);
93
+ }
94
+ if (failOffset !== void 0) {
95
+ if (axis === "x") {
96
+ pan.failOffsetY([-failOffset, failOffset]);
97
+ } else if (axis === "y") {
98
+ pan.failOffsetX([-failOffset, failOffset]);
99
+ }
100
+ }
101
+ if (pointers !== void 0) {
102
+ pan.minPointers(pointers).maxPointers(pointers);
103
+ }
104
+ if (hitSlop !== void 0) {
105
+ pan.hitSlop(hitSlop);
106
+ }
107
+ if (enabled !== void 0) {
108
+ pan.enabled(enabled);
109
+ }
110
+ return pan;
111
+ },
112
+ [
113
+ axis,
114
+ threshold,
115
+ failOffset,
116
+ pointers,
117
+ hitSlop,
118
+ enabled,
119
+ movesX,
120
+ movesY,
121
+ hasPanStart,
122
+ hasPanEnd,
123
+ handlePanStart,
124
+ handlePanEnd,
125
+ x,
126
+ y,
127
+ originX,
128
+ originY,
129
+ lastX,
130
+ lastY,
131
+ isActive,
132
+ onBegin,
133
+ onUpdate,
134
+ onFinalize
135
+ ],
136
+ options
137
+ );
138
+ return useMemo(
139
+ () => buildIntentResult(built, { x, y, isActive }),
140
+ [built, x, y, isActive]
141
+ );
142
+ }
143
+
144
+ export { usePan };
@@ -1,8 +1,9 @@
1
- import { useStableRecord, useLatestCallback } from './chunk-5BMRKYVY.js';
2
- import { useGestureMemo } from './chunk-F4RHM4ZK.js';
1
+ import { useStableRecord, useLatestCallback, buildIntentResult } from './chunk-2UZTAWUQ.js';
2
+ import { useGestureMemo } from './chunk-NYDDZD4G.js';
3
3
  import { useMemo } from 'react';
4
4
  import { Gesture } from 'react-native-gesture-handler';
5
- import { useSharedValue, runOnJS } from 'react-native-reanimated';
5
+ import { useSharedValue } from 'react-native-reanimated';
6
+ import { scheduleOnRN } from 'react-native-worklets';
6
7
 
7
8
  var DEFAULT_THRESHOLD = 10;
8
9
  function resist(value, min, max, elastic) {
@@ -83,7 +84,7 @@ function useDrag(options = {}) {
83
84
  startY.value = y.value - event.translationY;
84
85
  isActive.value = true;
85
86
  if (hasDragStart) {
86
- runOnJS(handleDragStart)(toDragEvent(event));
87
+ scheduleOnRN(handleDragStart, toDragEvent(event));
87
88
  }
88
89
  }).onUpdate((event) => {
89
90
  "worklet";
@@ -106,8 +107,10 @@ function useDrag(options = {}) {
106
107
  onUpdate?.(toDragEvent(event));
107
108
  }).onEnd((event, success) => {
108
109
  "worklet";
109
- if (success && hasDragEnd) {
110
- runOnJS(handleDragEnd)(toDragEvent(event));
110
+ if (hasDragEnd) {
111
+ scheduleOnRN(handleDragEnd, toDragEvent(event), {
112
+ cancelled: !success
113
+ });
111
114
  }
112
115
  }).onFinalize((event, success) => {
113
116
  "worklet";
@@ -168,7 +171,10 @@ function useDrag(options = {}) {
168
171
  ],
169
172
  options
170
173
  );
171
- return useMemo(() => ({ ...built, x, y, isActive }), [built, x, y, isActive]);
174
+ return useMemo(
175
+ () => buildIntentResult(built, { x, y, isActive }),
176
+ [built, x, y, isActive]
177
+ );
172
178
  }
173
179
 
174
180
  export { useDrag };
@@ -0,0 +1,12 @@
1
+ // src/intents/tapEvent.ts
2
+ function toTapEvent(event) {
3
+ "worklet";
4
+ return {
5
+ x: event.x,
6
+ y: event.y,
7
+ absolute: { x: event.absoluteX, y: event.absoluteY },
8
+ pointers: event.numberOfPointers
9
+ };
10
+ }
11
+
12
+ export { toTapEvent };