@tamagui/react-native-use-responder-events 1.2.8 → 1.2.10

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.
@@ -0,0 +1,365 @@
1
+ import createResponderEvent from "./createResponderEvent";
2
+ import { ResponderTouchHistoryStore } from "./ResponderTouchHistoryStore";
3
+ import {
4
+ isCancelish,
5
+ isEndish,
6
+ isMoveish,
7
+ isScroll,
8
+ isSelectionChange,
9
+ isStartish
10
+ } from "./types";
11
+ import { canUseDOM } from "./utils";
12
+ import {
13
+ getLowestCommonAncestor,
14
+ getResponderPaths,
15
+ hasTargetTouches,
16
+ hasValidSelection,
17
+ isPrimaryPointerDown,
18
+ setResponderId
19
+ } from "./utils";
20
+ const emptyObject = {};
21
+ const startRegistration = [
22
+ "onStartShouldSetResponderCapture",
23
+ "onStartShouldSetResponder",
24
+ { bubbles: true }
25
+ ];
26
+ const moveRegistration = [
27
+ "onMoveShouldSetResponderCapture",
28
+ "onMoveShouldSetResponder",
29
+ { bubbles: true }
30
+ ];
31
+ const scrollRegistration = [
32
+ "onScrollShouldSetResponderCapture",
33
+ "onScrollShouldSetResponder",
34
+ { bubbles: false }
35
+ ];
36
+ const shouldSetResponderEvents = {
37
+ touchstart: startRegistration,
38
+ mousedown: startRegistration,
39
+ touchmove: moveRegistration,
40
+ mousemove: moveRegistration,
41
+ scroll: scrollRegistration
42
+ };
43
+ const emptyResponder = { id: null, idPath: null, node: null };
44
+ const responderListenersMap = /* @__PURE__ */ new Map();
45
+ let isEmulatingMouseEvents = false;
46
+ let trackedTouchCount = 0;
47
+ let currentResponder = {
48
+ id: null,
49
+ node: null,
50
+ idPath: null
51
+ };
52
+ const responderTouchHistoryStore = new ResponderTouchHistoryStore();
53
+ function changeCurrentResponder(responder) {
54
+ currentResponder = responder;
55
+ }
56
+ function getResponderConfig(id) {
57
+ const config = responderListenersMap.get(id);
58
+ return config != null ? config : emptyObject;
59
+ }
60
+ function eventListener(domEvent) {
61
+ const eventType = domEvent.type;
62
+ const eventTarget = domEvent.target;
63
+ if (eventType === "touchstart") {
64
+ isEmulatingMouseEvents = true;
65
+ }
66
+ if (eventType === "touchmove" || trackedTouchCount > 1) {
67
+ isEmulatingMouseEvents = false;
68
+ }
69
+ if (
70
+ // Ignore browser emulated mouse events
71
+ eventType === "mousedown" && isEmulatingMouseEvents || eventType === "mousemove" && isEmulatingMouseEvents || // Ignore mousemove if a mousedown didn't occur first
72
+ eventType === "mousemove" && trackedTouchCount < 1
73
+ ) {
74
+ return;
75
+ }
76
+ if (isEmulatingMouseEvents && eventType === "mouseup") {
77
+ if (trackedTouchCount === 0) {
78
+ isEmulatingMouseEvents = false;
79
+ }
80
+ return;
81
+ }
82
+ const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent);
83
+ const isMoveEvent = isMoveish(eventType);
84
+ const isEndEvent = isEndish(eventType);
85
+ const isScrollEvent = isScroll(eventType);
86
+ const isSelectionChangeEvent = isSelectionChange(eventType);
87
+ const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore);
88
+ if (isStartEvent || isMoveEvent || isEndEvent) {
89
+ if (domEvent.touches) {
90
+ trackedTouchCount = domEvent.touches.length;
91
+ } else {
92
+ if (isStartEvent) {
93
+ trackedTouchCount = 1;
94
+ } else if (isEndEvent) {
95
+ trackedTouchCount = 0;
96
+ }
97
+ }
98
+ responderTouchHistoryStore.recordTouchTrack(
99
+ eventType,
100
+ responderEvent.nativeEvent
101
+ );
102
+ }
103
+ let eventPaths = getResponderPaths(domEvent);
104
+ let wasNegotiated = false;
105
+ let wantsResponder;
106
+ if (isStartEvent || isMoveEvent || isScrollEvent && trackedTouchCount > 0) {
107
+ const currentResponderIdPath = currentResponder.idPath;
108
+ const eventIdPath = eventPaths.idPath;
109
+ if (currentResponderIdPath != null && eventIdPath != null) {
110
+ const lowestCommonAncestor = getLowestCommonAncestor(
111
+ currentResponderIdPath,
112
+ eventIdPath
113
+ );
114
+ if (lowestCommonAncestor != null) {
115
+ const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor);
116
+ const index = indexOfLowestCommonAncestor + (lowestCommonAncestor === currentResponder.id ? 1 : 0);
117
+ eventPaths = {
118
+ idPath: eventIdPath.slice(index),
119
+ nodePath: eventPaths.nodePath.slice(index)
120
+ };
121
+ } else {
122
+ eventPaths = null;
123
+ }
124
+ }
125
+ if (eventPaths != null) {
126
+ wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent);
127
+ if (wantsResponder != null) {
128
+ attemptTransfer(responderEvent, wantsResponder);
129
+ wasNegotiated = true;
130
+ }
131
+ }
132
+ }
133
+ if (currentResponder.id != null && currentResponder.node != null) {
134
+ const { id, node } = currentResponder;
135
+ const {
136
+ onResponderStart,
137
+ onResponderMove,
138
+ onResponderEnd,
139
+ onResponderRelease,
140
+ onResponderTerminate,
141
+ onResponderTerminationRequest
142
+ } = getResponderConfig(id);
143
+ responderEvent.bubbles = false;
144
+ responderEvent.cancelable = false;
145
+ responderEvent.currentTarget = node;
146
+ if (isStartEvent) {
147
+ if (onResponderStart != null) {
148
+ responderEvent.dispatchConfig.registrationName = "onResponderStart";
149
+ onResponderStart(responderEvent);
150
+ }
151
+ } else if (isMoveEvent) {
152
+ if (onResponderMove != null) {
153
+ responderEvent.dispatchConfig.registrationName = "onResponderMove";
154
+ onResponderMove(responderEvent);
155
+ }
156
+ } else {
157
+ const isTerminateEvent = isCancelish(eventType) || // native context menu
158
+ eventType === "contextmenu" || // window blur
159
+ eventType === "blur" && eventTarget === window || // responder (or ancestors) blur
160
+ eventType === "blur" && eventTarget.contains(node) && domEvent.relatedTarget !== node || // native scroll without using a pointer
161
+ isScrollEvent && trackedTouchCount === 0 || // native scroll on node that is parent of the responder (allow siblings to scroll)
162
+ isScrollEvent && eventTarget.contains(node) && eventTarget !== node || // native select/selectionchange on node
163
+ isSelectionChangeEvent && hasValidSelection(domEvent);
164
+ const isReleaseEvent = isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches);
165
+ if (isEndEvent) {
166
+ if (onResponderEnd != null) {
167
+ responderEvent.dispatchConfig.registrationName = "onResponderEnd";
168
+ onResponderEnd(responderEvent);
169
+ }
170
+ }
171
+ if (isReleaseEvent) {
172
+ if (onResponderRelease != null) {
173
+ responderEvent.dispatchConfig.registrationName = "onResponderRelease";
174
+ onResponderRelease(responderEvent);
175
+ }
176
+ changeCurrentResponder(emptyResponder);
177
+ }
178
+ if (isTerminateEvent) {
179
+ let shouldTerminate = true;
180
+ if (eventType === "contextmenu" || eventType === "scroll" || eventType === "selectionchange") {
181
+ if (wasNegotiated) {
182
+ shouldTerminate = false;
183
+ } else if (onResponderTerminationRequest != null) {
184
+ responderEvent.dispatchConfig.registrationName = "onResponderTerminationRequest";
185
+ if (onResponderTerminationRequest(responderEvent) === false) {
186
+ shouldTerminate = false;
187
+ }
188
+ }
189
+ }
190
+ if (shouldTerminate) {
191
+ if (onResponderTerminate != null) {
192
+ responderEvent.dispatchConfig.registrationName = "onResponderTerminate";
193
+ onResponderTerminate(responderEvent);
194
+ }
195
+ changeCurrentResponder(emptyResponder);
196
+ isEmulatingMouseEvents = false;
197
+ trackedTouchCount = 0;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ function findWantsResponder(eventPaths, domEvent, responderEvent) {
204
+ const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type];
205
+ if (shouldSetCallbacks != null) {
206
+ const { idPath, nodePath } = eventPaths;
207
+ const shouldSetCallbackCaptureName = shouldSetCallbacks[0];
208
+ const shouldSetCallbackBubbleName = shouldSetCallbacks[1];
209
+ const { bubbles } = shouldSetCallbacks[2];
210
+ const check = function(id, node, callbackName) {
211
+ const config = getResponderConfig(id);
212
+ const shouldSetCallback = config[callbackName];
213
+ if (shouldSetCallback != null) {
214
+ responderEvent.currentTarget = node;
215
+ if (shouldSetCallback(responderEvent) === true) {
216
+ const prunedIdPath = idPath.slice(idPath.indexOf(id));
217
+ return { id, node, idPath: prunedIdPath };
218
+ }
219
+ }
220
+ };
221
+ for (let i = idPath.length - 1; i >= 0; i--) {
222
+ const id = idPath[i];
223
+ const node = nodePath[i];
224
+ const result = check(id, node, shouldSetCallbackCaptureName);
225
+ if (result != null) {
226
+ return result;
227
+ }
228
+ if (responderEvent.isPropagationStopped() === true) {
229
+ return;
230
+ }
231
+ }
232
+ if (bubbles) {
233
+ for (let i = 0; i < idPath.length; i++) {
234
+ const id = idPath[i];
235
+ const node = nodePath[i];
236
+ const result = check(id, node, shouldSetCallbackBubbleName);
237
+ if (result != null) {
238
+ return result;
239
+ }
240
+ if (responderEvent.isPropagationStopped() === true) {
241
+ return;
242
+ }
243
+ }
244
+ } else {
245
+ const id = idPath[0];
246
+ const node = nodePath[0];
247
+ const target = domEvent.target;
248
+ if (target === node) {
249
+ return check(id, node, shouldSetCallbackBubbleName);
250
+ }
251
+ }
252
+ }
253
+ }
254
+ function attemptTransfer(responderEvent, wantsResponder) {
255
+ const { id: currentId, node: currentNode } = currentResponder;
256
+ const { id, node } = wantsResponder;
257
+ const { onResponderGrant, onResponderReject } = getResponderConfig(id);
258
+ responderEvent.bubbles = false;
259
+ responderEvent.cancelable = false;
260
+ responderEvent.currentTarget = node;
261
+ if (currentId == null) {
262
+ if (onResponderGrant != null) {
263
+ responderEvent.currentTarget = node;
264
+ responderEvent.dispatchConfig.registrationName = "onResponderGrant";
265
+ onResponderGrant(responderEvent);
266
+ }
267
+ changeCurrentResponder(wantsResponder);
268
+ } else {
269
+ const { onResponderTerminate, onResponderTerminationRequest } = getResponderConfig(currentId);
270
+ let allowTransfer = true;
271
+ if (onResponderTerminationRequest != null) {
272
+ responderEvent.currentTarget = currentNode;
273
+ responderEvent.dispatchConfig.registrationName = "onResponderTerminationRequest";
274
+ if (onResponderTerminationRequest(responderEvent) === false) {
275
+ allowTransfer = false;
276
+ }
277
+ }
278
+ if (allowTransfer) {
279
+ if (onResponderTerminate != null) {
280
+ responderEvent.currentTarget = currentNode;
281
+ responderEvent.dispatchConfig.registrationName = "onResponderTerminate";
282
+ onResponderTerminate(responderEvent);
283
+ }
284
+ if (onResponderGrant != null) {
285
+ responderEvent.currentTarget = node;
286
+ responderEvent.dispatchConfig.registrationName = "onResponderGrant";
287
+ onResponderGrant(responderEvent);
288
+ }
289
+ changeCurrentResponder(wantsResponder);
290
+ } else {
291
+ if (onResponderReject != null) {
292
+ responderEvent.currentTarget = node;
293
+ responderEvent.dispatchConfig.registrationName = "onResponderReject";
294
+ onResponderReject(responderEvent);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ const documentEventsCapturePhase = ["blur", "scroll"];
300
+ const documentEventsBubblePhase = [
301
+ // mouse
302
+ "mousedown",
303
+ "mousemove",
304
+ "mouseup",
305
+ "dragstart",
306
+ // touch
307
+ "touchstart",
308
+ "touchmove",
309
+ "touchend",
310
+ "touchcancel",
311
+ // other
312
+ "contextmenu",
313
+ "select",
314
+ "selectionchange"
315
+ ];
316
+ const isTamaguiResponderActive = Symbol();
317
+ function attachListeners() {
318
+ if (canUseDOM && !window[isTamaguiResponderActive]) {
319
+ window.addEventListener("blur", eventListener);
320
+ documentEventsBubblePhase.forEach((eventType) => {
321
+ document.addEventListener(eventType, eventListener);
322
+ });
323
+ documentEventsCapturePhase.forEach((eventType) => {
324
+ document.addEventListener(eventType, eventListener, true);
325
+ });
326
+ window[isTamaguiResponderActive] = true;
327
+ }
328
+ }
329
+ function addNode(id, node, config) {
330
+ setResponderId(node, id);
331
+ responderListenersMap.set(id, config);
332
+ }
333
+ function removeNode(id) {
334
+ if (currentResponder.id === id) {
335
+ terminateResponder();
336
+ }
337
+ if (responderListenersMap.has(id)) {
338
+ responderListenersMap.delete(id);
339
+ }
340
+ }
341
+ function terminateResponder() {
342
+ const { id, node } = currentResponder;
343
+ if (id != null && node != null) {
344
+ const { onResponderTerminate } = getResponderConfig(id);
345
+ if (onResponderTerminate != null) {
346
+ const event = createResponderEvent({}, responderTouchHistoryStore);
347
+ event.currentTarget = node;
348
+ onResponderTerminate(event);
349
+ }
350
+ changeCurrentResponder(emptyResponder);
351
+ }
352
+ isEmulatingMouseEvents = false;
353
+ trackedTouchCount = 0;
354
+ }
355
+ function getResponderNode() {
356
+ return currentResponder.node;
357
+ }
358
+ export {
359
+ addNode,
360
+ attachListeners,
361
+ getResponderNode,
362
+ removeNode,
363
+ terminateResponder
364
+ };
365
+ //# sourceMappingURL=ResponderSystem.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ResponderSystem.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ResponderEvent } from './createResponderEvent'\nimport createResponderEvent from './createResponderEvent'\nimport { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore'\nimport {\n isCancelish,\n isEndish,\n isMoveish,\n isScroll,\n isSelectionChange,\n isStartish,\n} from './types'\nimport { canUseDOM } from './utils'\nimport {\n getLowestCommonAncestor,\n getResponderPaths,\n hasTargetTouches,\n hasValidSelection,\n isPrimaryPointerDown,\n setResponderId,\n} from './utils'\n\n/* ------------ TYPES ------------ */\n\ntype ResponderId = string\n\ntype ActiveResponderInstance = {\n id: ResponderId\n idPath: Array<number>\n node: any\n}\n\ntype EmptyResponderInstance = {\n id: null\n idPath: null\n node: null\n}\n\ntype ResponderInstance = ActiveResponderInstance | EmptyResponderInstance\n\nexport type ResponderConfig = {\n // Direct responder events dispatched directly to responder. Do not bubble.\n onResponderEnd?: ((e: ResponderEvent) => void) | null\n onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null\n onResponderMove?: ((e: ResponderEvent) => void) | null\n onResponderRelease?: ((e: ResponderEvent) => void) | null\n onResponderReject?: ((e: ResponderEvent) => void) | null\n onResponderStart?: ((e: ResponderEvent) => void) | null\n onResponderTerminate?: ((e: ResponderEvent) => void) | null\n onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null\n // On pointer down, should this element become the responder?\n onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On pointer move, should this element become the responder?\n onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On scroll, should this element become the responder? Do no bubble\n onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On text selection change, should this element become the responder?\n onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onSelectionChangeShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n}\n\nconst emptyObject = {}\n\n/* ------------ IMPLEMENTATION ------------ */\n\nconst startRegistration = [\n 'onStartShouldSetResponderCapture',\n 'onStartShouldSetResponder',\n { bubbles: true },\n]\nconst moveRegistration = [\n 'onMoveShouldSetResponderCapture',\n 'onMoveShouldSetResponder',\n { bubbles: true },\n]\nconst scrollRegistration = [\n 'onScrollShouldSetResponderCapture',\n 'onScrollShouldSetResponder',\n { bubbles: false },\n]\nconst shouldSetResponderEvents = {\n touchstart: startRegistration,\n mousedown: startRegistration,\n touchmove: moveRegistration,\n mousemove: moveRegistration,\n scroll: scrollRegistration,\n}\n\nconst emptyResponder = { id: null, idPath: null, node: null }\nconst responderListenersMap = new Map()\n\nlet isEmulatingMouseEvents = false\nlet trackedTouchCount = 0\nlet currentResponder: ResponderInstance = {\n id: null,\n node: null,\n idPath: null,\n}\nconst responderTouchHistoryStore = new ResponderTouchHistoryStore()\n\nfunction changeCurrentResponder(responder: ResponderInstance) {\n currentResponder = responder\n}\n\nfunction getResponderConfig(id: ResponderId): ResponderConfig | any {\n const config = responderListenersMap.get(id)\n return config != null ? config : emptyObject\n}\n\n/**\n * Process native events\n *\n * A single event listener is used to manage the responder system.\n * All pointers are tracked in the ResponderTouchHistoryStore. Native events\n * are interpreted in terms of the Responder System and checked to see if\n * the responder should be transferred. Each host node that is attached to\n * the Responder System has an ID, which is used to look up its associated\n * callbacks.\n */\nfunction eventListener(domEvent: any) {\n const eventType = domEvent.type\n const eventTarget = domEvent.target\n\n /**\n * Manage emulated events and early bailout.\n * Since PointerEvent is not used yet (lack of support in older Safari), it's\n * necessary to manually manage the mess of browser touch/mouse events.\n * And bailout early for termination events when there is no active responder.\n */\n\n // Flag when browser may produce emulated events\n if (eventType === 'touchstart') {\n isEmulatingMouseEvents = true\n }\n // Remove flag when browser will not produce emulated events\n if (eventType === 'touchmove' || trackedTouchCount > 1) {\n isEmulatingMouseEvents = false\n }\n // Ignore various events in particular circumstances\n if (\n // Ignore browser emulated mouse events\n (eventType === 'mousedown' && isEmulatingMouseEvents) ||\n (eventType === 'mousemove' && isEmulatingMouseEvents) ||\n // Ignore mousemove if a mousedown didn't occur first\n (eventType === 'mousemove' && trackedTouchCount < 1)\n ) {\n return\n }\n // Remove flag after emulated events are finished\n if (isEmulatingMouseEvents && eventType === 'mouseup') {\n if (trackedTouchCount === 0) {\n isEmulatingMouseEvents = false\n }\n return\n }\n\n const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent)\n const isMoveEvent = isMoveish(eventType)\n const isEndEvent = isEndish(eventType)\n const isScrollEvent = isScroll(eventType)\n const isSelectionChangeEvent = isSelectionChange(eventType)\n const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore)\n\n /**\n * Record the state of active pointers\n */\n\n if (isStartEvent || isMoveEvent || isEndEvent) {\n if (domEvent.touches) {\n trackedTouchCount = domEvent.touches.length\n } else {\n if (isStartEvent) {\n trackedTouchCount = 1\n } else if (isEndEvent) {\n trackedTouchCount = 0\n }\n }\n responderTouchHistoryStore.recordTouchTrack(\n eventType,\n responderEvent.nativeEvent as any\n )\n }\n\n /**\n * Responder System logic\n */\n\n let eventPaths: any = getResponderPaths(domEvent)\n let wasNegotiated = false\n let wantsResponder\n\n // If an event occured that might change the current responder...\n if (isStartEvent || isMoveEvent || (isScrollEvent && trackedTouchCount > 0)) {\n // If there is already a responder, prune the event paths to the lowest common ancestor\n // of the existing responder and deepest target of the event.\n const currentResponderIdPath = currentResponder.idPath\n const eventIdPath = eventPaths.idPath\n\n if (currentResponderIdPath != null && eventIdPath != null) {\n const lowestCommonAncestor = getLowestCommonAncestor(\n currentResponderIdPath,\n eventIdPath\n )\n if (lowestCommonAncestor != null) {\n const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)\n // Skip the current responder so it doesn't receive unexpected \"shouldSet\" events.\n const index =\n indexOfLowestCommonAncestor +\n (lowestCommonAncestor === currentResponder.id ? 1 : 0)\n eventPaths = {\n idPath: eventIdPath.slice(index),\n nodePath: eventPaths.nodePath.slice(index),\n }\n } else {\n eventPaths = null\n }\n }\n\n if (eventPaths != null) {\n // If a node wants to become the responder, attempt to transfer.\n wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent)\n if (wantsResponder != null) {\n // Sets responder if none exists, or negotates with existing responder.\n attemptTransfer(responderEvent, wantsResponder)\n wasNegotiated = true\n }\n }\n }\n\n // If there is now a responder, invoke its callbacks for the lifecycle of the gesture.\n if (currentResponder.id != null && currentResponder.node != null) {\n const { id, node } = currentResponder\n const {\n onResponderStart,\n onResponderMove,\n onResponderEnd,\n onResponderRelease,\n onResponderTerminate,\n onResponderTerminationRequest,\n } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Start\n if (isStartEvent) {\n if (onResponderStart != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderStart'\n onResponderStart(responderEvent)\n }\n }\n // Move\n else if (isMoveEvent) {\n if (onResponderMove != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderMove'\n onResponderMove(responderEvent)\n }\n } else {\n const isTerminateEvent =\n isCancelish(eventType) ||\n // native context menu\n eventType === 'contextmenu' ||\n // window blur\n (eventType === 'blur' && eventTarget === window) ||\n // responder (or ancestors) blur\n (eventType === 'blur' &&\n eventTarget.contains(node) &&\n domEvent.relatedTarget !== node) ||\n // native scroll without using a pointer\n (isScrollEvent && trackedTouchCount === 0) ||\n // native scroll on node that is parent of the responder (allow siblings to scroll)\n (isScrollEvent && eventTarget.contains(node) && eventTarget !== node) ||\n // native select/selectionchange on node\n (isSelectionChangeEvent && hasValidSelection(domEvent))\n\n const isReleaseEvent =\n isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches)\n\n // End\n if (isEndEvent) {\n if (onResponderEnd != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderEnd'\n onResponderEnd(responderEvent)\n }\n }\n // Release\n if (isReleaseEvent) {\n if (onResponderRelease != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderRelease'\n onResponderRelease(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n }\n // Terminate\n if (isTerminateEvent) {\n let shouldTerminate = true\n\n // Responders can still avoid termination but only for these events.\n if (\n eventType === 'contextmenu' ||\n eventType === 'scroll' ||\n eventType === 'selectionchange'\n ) {\n // Only call this function is it wasn't already called during negotiation.\n if (wasNegotiated) {\n shouldTerminate = false\n } else if (onResponderTerminationRequest != null) {\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n shouldTerminate = false\n }\n }\n }\n\n if (shouldTerminate) {\n if (onResponderTerminate != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n }\n }\n }\n }\n}\n\n/**\n * Walk the event path to/from the target node. At each node, stop and call the\n * relevant \"shouldSet\" functions for the given event type. If any of those functions\n * call \"stopPropagation\" on the event, stop searching for a responder.\n */\nfunction findWantsResponder(eventPaths, domEvent, responderEvent) {\n const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type as any] // for Flow\n\n if (shouldSetCallbacks != null) {\n const { idPath, nodePath } = eventPaths\n\n const shouldSetCallbackCaptureName = shouldSetCallbacks[0]\n const shouldSetCallbackBubbleName = shouldSetCallbacks[1]\n const { bubbles } = shouldSetCallbacks[2]\n\n const check = function (id, node, callbackName) {\n const config = getResponderConfig(id)\n const shouldSetCallback = config[callbackName]\n if (shouldSetCallback != null) {\n responderEvent.currentTarget = node\n if (shouldSetCallback(responderEvent) === true) {\n // Start the path from the potential responder\n const prunedIdPath = idPath.slice(idPath.indexOf(id))\n return { id, node, idPath: prunedIdPath }\n }\n }\n }\n\n // capture\n for (let i = idPath.length - 1; i >= 0; i--) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackCaptureName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n\n // bubble\n if (bubbles) {\n for (let i = 0; i < idPath.length; i++) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackBubbleName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n } else {\n const id = idPath[0]\n const node = nodePath[0]\n const target = domEvent.target\n if (target === node) {\n return check(id, node, shouldSetCallbackBubbleName)\n }\n }\n }\n}\n\n/**\n * Attempt to transfer the responder.\n */\nfunction attemptTransfer(\n responderEvent: ResponderEvent,\n wantsResponder: ActiveResponderInstance\n) {\n const { id: currentId, node: currentNode } = currentResponder\n const { id, node } = wantsResponder\n\n const { onResponderGrant, onResponderReject } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Set responder\n if (currentId == null) {\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n }\n // Negotiate with current responder\n else {\n const { onResponderTerminate, onResponderTerminationRequest } =\n getResponderConfig(currentId)\n\n let allowTransfer = true\n if (onResponderTerminationRequest != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n allowTransfer = false\n }\n }\n\n if (allowTransfer) {\n // Terminate existing responder\n if (onResponderTerminate != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n // Grant next responder\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n } else {\n // Reject responder request\n if (onResponderReject != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderReject'\n onResponderReject(responderEvent)\n }\n }\n }\n}\n\n/* ------------ PUBLIC API ------------ */\n\n/**\n * Attach Listeners\n *\n * Use native events as ReactDOM doesn't have a non-plugin API to implement\n * this system.\n */\nconst documentEventsCapturePhase = ['blur', 'scroll']\nconst documentEventsBubblePhase = [\n // mouse\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'dragstart',\n // touch\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n // other\n 'contextmenu',\n 'select',\n 'selectionchange',\n]\n\nconst isTamaguiResponderActive = Symbol()\n\nexport function attachListeners() {\n if (canUseDOM && !window[isTamaguiResponderActive]) {\n window.addEventListener('blur', eventListener)\n documentEventsBubblePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener)\n })\n documentEventsCapturePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener, true)\n })\n window[isTamaguiResponderActive] = true\n }\n}\n\n/**\n * Register a node with the ResponderSystem.\n */\nexport function addNode(id: ResponderId, node: any, config: ResponderConfig) {\n setResponderId(node, id)\n responderListenersMap.set(id, config)\n}\n\n/**\n * Unregister a node with the ResponderSystem.\n */\nexport function removeNode(id: ResponderId) {\n if (currentResponder.id === id) {\n terminateResponder()\n }\n if (responderListenersMap.has(id)) {\n responderListenersMap.delete(id)\n }\n}\n\n/**\n * Allow the current responder to be terminated from within components to support\n * more complex requirements, such as use with other React libraries for working\n * with scroll views, input views, etc.\n */\nexport function terminateResponder() {\n const { id, node } = currentResponder\n if (id != null && node != null) {\n const { onResponderTerminate } = getResponderConfig(id)\n if (onResponderTerminate != null) {\n const event = createResponderEvent({}, responderTouchHistoryStore)\n event.currentTarget = node\n onResponderTerminate(event)\n }\n changeCurrentResponder(emptyResponder)\n }\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n}\n\n/**\n * Allow unit tests to inspect the current responder in the system.\n * FOR TESTING ONLY.\n */\nexport function getResponderNode(): any {\n return currentResponder.node\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,170 @@
1
+ import { isEndish, isMoveish, isStartish } from "./types";
2
+ const MAX_TOUCH_BANK = 20;
3
+ function timestampForTouch(touch) {
4
+ return touch["timeStamp"] || touch.timestamp;
5
+ }
6
+ function createTouchRecord(touch) {
7
+ return {
8
+ touchActive: true,
9
+ startPageX: touch.pageX,
10
+ startPageY: touch.pageY,
11
+ startTimeStamp: timestampForTouch(touch),
12
+ currentPageX: touch.pageX,
13
+ currentPageY: touch.pageY,
14
+ currentTimeStamp: timestampForTouch(touch),
15
+ previousPageX: touch.pageX,
16
+ previousPageY: touch.pageY,
17
+ previousTimeStamp: timestampForTouch(touch)
18
+ };
19
+ }
20
+ function resetTouchRecord(touchRecord, touch) {
21
+ touchRecord.touchActive = true;
22
+ touchRecord.startPageX = touch.pageX;
23
+ touchRecord.startPageY = touch.pageY;
24
+ touchRecord.startTimeStamp = timestampForTouch(touch);
25
+ touchRecord.currentPageX = touch.pageX;
26
+ touchRecord.currentPageY = touch.pageY;
27
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
28
+ touchRecord.previousPageX = touch.pageX;
29
+ touchRecord.previousPageY = touch.pageY;
30
+ touchRecord.previousTimeStamp = timestampForTouch(touch);
31
+ }
32
+ function getTouchIdentifier({ identifier }) {
33
+ if (identifier == null) {
34
+ console.error("Touch object is missing identifier.");
35
+ }
36
+ if (process.env.NODE_ENV === "development") {
37
+ if (identifier > MAX_TOUCH_BANK) {
38
+ console.error(
39
+ "Touch identifier %s is greater than maximum supported %s which causes performance issues backfilling array locations for all of the indices.",
40
+ identifier,
41
+ MAX_TOUCH_BANK
42
+ );
43
+ }
44
+ }
45
+ return identifier;
46
+ }
47
+ function recordTouchStart(touch, touchHistory) {
48
+ const identifier = getTouchIdentifier(touch);
49
+ const touchRecord = touchHistory.touchBank[identifier];
50
+ if (touchRecord) {
51
+ resetTouchRecord(touchRecord, touch);
52
+ } else {
53
+ touchHistory.touchBank[identifier] = createTouchRecord(touch);
54
+ }
55
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
56
+ }
57
+ function recordTouchMove(touch, touchHistory) {
58
+ const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
59
+ if (touchRecord) {
60
+ touchRecord.touchActive = true;
61
+ touchRecord.previousPageX = touchRecord.currentPageX;
62
+ touchRecord.previousPageY = touchRecord.currentPageY;
63
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
64
+ touchRecord.currentPageX = touch.pageX;
65
+ touchRecord.currentPageY = touch.pageY;
66
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
67
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
68
+ } else {
69
+ console.warn(
70
+ "Cannot record touch move without a touch start.\n",
71
+ `Touch Move: ${printTouch(touch)}
72
+ `,
73
+ `Touch Bank: ${printTouchBank(touchHistory)}`
74
+ );
75
+ }
76
+ }
77
+ function recordTouchEnd(touch, touchHistory) {
78
+ const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
79
+ if (touchRecord) {
80
+ touchRecord.touchActive = false;
81
+ touchRecord.previousPageX = touchRecord.currentPageX;
82
+ touchRecord.previousPageY = touchRecord.currentPageY;
83
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
84
+ touchRecord.currentPageX = touch.pageX;
85
+ touchRecord.currentPageY = touch.pageY;
86
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
87
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
88
+ } else {
89
+ console.warn(
90
+ "Cannot record touch end without a touch start.\n",
91
+ `Touch End: ${printTouch(touch)}
92
+ `,
93
+ `Touch Bank: ${printTouchBank(touchHistory)}`
94
+ );
95
+ }
96
+ }
97
+ function printTouch(touch) {
98
+ return JSON.stringify({
99
+ identifier: touch.identifier,
100
+ pageX: touch.pageX,
101
+ pageY: touch.pageY,
102
+ timestamp: timestampForTouch(touch)
103
+ });
104
+ }
105
+ function printTouchBank(touchHistory) {
106
+ const { touchBank } = touchHistory;
107
+ let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
108
+ if (touchBank.length > MAX_TOUCH_BANK) {
109
+ printed += ` (original size: ${touchBank.length})`;
110
+ }
111
+ return printed;
112
+ }
113
+ class ResponderTouchHistoryStore {
114
+ constructor() {
115
+ this._touchHistory = {
116
+ touchBank: [],
117
+ //Array<TouchRecord>
118
+ numberActiveTouches: 0,
119
+ // If there is only one active touch, we remember its location. This prevents
120
+ // us having to loop through all of the touches all the time in the most
121
+ // common case.
122
+ indexOfSingleActiveTouch: -1,
123
+ mostRecentTimeStamp: 0
124
+ };
125
+ }
126
+ recordTouchTrack(topLevelType, nativeEvent) {
127
+ const touchHistory = this._touchHistory;
128
+ if (isMoveish(topLevelType)) {
129
+ nativeEvent.changedTouches.forEach(
130
+ (touch) => recordTouchMove(touch, touchHistory)
131
+ );
132
+ } else if (isStartish(topLevelType)) {
133
+ nativeEvent.changedTouches.forEach(
134
+ (touch) => recordTouchStart(touch, touchHistory)
135
+ );
136
+ touchHistory.numberActiveTouches = nativeEvent.touches.length;
137
+ if (touchHistory.numberActiveTouches === 1) {
138
+ touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier;
139
+ }
140
+ } else if (isEndish(topLevelType)) {
141
+ nativeEvent.changedTouches.forEach(
142
+ (touch) => recordTouchEnd(touch, touchHistory)
143
+ );
144
+ touchHistory.numberActiveTouches = nativeEvent.touches.length;
145
+ if (touchHistory.numberActiveTouches === 1) {
146
+ const { touchBank } = touchHistory;
147
+ for (let i = 0; i < touchBank.length; i++) {
148
+ const touchTrackToCheck = touchBank[i];
149
+ if (touchTrackToCheck == null ? void 0 : touchTrackToCheck.touchActive) {
150
+ touchHistory.indexOfSingleActiveTouch = i;
151
+ break;
152
+ }
153
+ }
154
+ if (process.env.NODE_ENV === "development") {
155
+ const activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch];
156
+ if (!(activeRecord == null ? void 0 : activeRecord.touchActive)) {
157
+ console.error("Cannot find single active touch.");
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ get touchHistory() {
164
+ return this._touchHistory;
165
+ }
166
+ }
167
+ export {
168
+ ResponderTouchHistoryStore
169
+ };
170
+ //# sourceMappingURL=ResponderTouchHistoryStore.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ResponderTouchHistoryStore.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { Touch, TouchEvent } from './types'\nimport { isEndish, isMoveish, isStartish } from './types'\n\ntype TouchRecord = {\n currentPageX: number\n currentPageY: number\n currentTimeStamp: number\n previousPageX: number\n previousPageY: number\n previousTimeStamp: number\n startPageX: number\n startPageY: number\n startTimeStamp: number\n touchActive: boolean\n}\n\nexport type TouchHistory = {\n indexOfSingleActiveTouch: number\n mostRecentTimeStamp: number\n numberActiveTouches: number\n touchBank: Array<TouchRecord>\n}\n\n/**\n * Tracks the position and time of each active touch by `touch.identifier`. We\n * should typically only see IDs in the range of 1-20 because IDs get recycled\n * when touches end and start again.\n */\n\nconst MAX_TOUCH_BANK = 20\n\nfunction timestampForTouch(touch: Touch): number {\n // The legacy internal implementation provides \"timeStamp\", which has been\n // renamed to \"timestamp\".\n return touch['timeStamp'] || touch.timestamp\n}\n\n/**\n * TODO: Instead of making gestures recompute filtered velocity, we could\n * include a built in velocity computation that can be reused globally.\n */\nfunction createTouchRecord(touch: Touch): TouchRecord {\n return {\n touchActive: true,\n startPageX: touch.pageX,\n startPageY: touch.pageY,\n startTimeStamp: timestampForTouch(touch),\n currentPageX: touch.pageX,\n currentPageY: touch.pageY,\n currentTimeStamp: timestampForTouch(touch),\n previousPageX: touch.pageX,\n previousPageY: touch.pageY,\n previousTimeStamp: timestampForTouch(touch),\n }\n}\n\nfunction resetTouchRecord(touchRecord: TouchRecord, touch: Touch): void {\n touchRecord.touchActive = true\n touchRecord.startPageX = touch.pageX\n touchRecord.startPageY = touch.pageY\n touchRecord.startTimeStamp = timestampForTouch(touch)\n touchRecord.currentPageX = touch.pageX\n touchRecord.currentPageY = touch.pageY\n touchRecord.currentTimeStamp = timestampForTouch(touch)\n touchRecord.previousPageX = touch.pageX\n touchRecord.previousPageY = touch.pageY\n touchRecord.previousTimeStamp = timestampForTouch(touch)\n}\n\nfunction getTouchIdentifier({ identifier }: Touch): number {\n if (identifier == null) {\n // eslint-disable-next-line no-console\n console.error('Touch object is missing identifier.')\n }\n if (process.env.NODE_ENV === 'development') {\n if (identifier > MAX_TOUCH_BANK) {\n // eslint-disable-next-line no-console\n console.error(\n 'Touch identifier %s is greater than maximum supported %s which causes ' +\n 'performance issues backfilling array locations for all of the indices.',\n identifier,\n MAX_TOUCH_BANK,\n )\n }\n }\n return identifier\n}\n\nfunction recordTouchStart(touch: Touch, touchHistory): void {\n const identifier = getTouchIdentifier(touch)\n const touchRecord = touchHistory.touchBank[identifier]\n if (touchRecord) {\n resetTouchRecord(touchRecord, touch)\n } else {\n touchHistory.touchBank[identifier] = createTouchRecord(touch)\n }\n touchHistory.mostRecentTimeStamp = timestampForTouch(touch)\n}\n\nfunction recordTouchMove(touch: Touch, touchHistory): void {\n const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)]\n if (touchRecord) {\n touchRecord.touchActive = true\n touchRecord.previousPageX = touchRecord.currentPageX\n touchRecord.previousPageY = touchRecord.currentPageY\n touchRecord.previousTimeStamp = touchRecord.currentTimeStamp\n touchRecord.currentPageX = touch.pageX\n touchRecord.currentPageY = touch.pageY\n touchRecord.currentTimeStamp = timestampForTouch(touch)\n touchHistory.mostRecentTimeStamp = timestampForTouch(touch)\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n 'Cannot record touch move without a touch start.\\n',\n `Touch Move: ${printTouch(touch)}\\n`,\n `Touch Bank: ${printTouchBank(touchHistory)}`,\n )\n }\n}\n\nfunction recordTouchEnd(touch: Touch, touchHistory): void {\n const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)]\n if (touchRecord) {\n touchRecord.touchActive = false\n touchRecord.previousPageX = touchRecord.currentPageX\n touchRecord.previousPageY = touchRecord.currentPageY\n touchRecord.previousTimeStamp = touchRecord.currentTimeStamp\n touchRecord.currentPageX = touch.pageX\n touchRecord.currentPageY = touch.pageY\n touchRecord.currentTimeStamp = timestampForTouch(touch)\n touchHistory.mostRecentTimeStamp = timestampForTouch(touch)\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n 'Cannot record touch end without a touch start.\\n',\n `Touch End: ${printTouch(touch)}\\n`,\n `Touch Bank: ${printTouchBank(touchHistory)}`,\n )\n }\n}\n\nfunction printTouch(touch: Touch): string {\n return JSON.stringify({\n identifier: touch.identifier,\n pageX: touch.pageX,\n pageY: touch.pageY,\n timestamp: timestampForTouch(touch),\n })\n}\n\nfunction printTouchBank(touchHistory): string {\n const { touchBank } = touchHistory\n let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK))\n if (touchBank.length > MAX_TOUCH_BANK) {\n printed += ` (original size: ${touchBank.length})`\n }\n return printed\n}\n\nexport class ResponderTouchHistoryStore {\n _touchHistory = {\n touchBank: [], //Array<TouchRecord>\n numberActiveTouches: 0,\n // If there is only one active touch, we remember its location. This prevents\n // us having to loop through all of the touches all the time in the most\n // common case.\n indexOfSingleActiveTouch: -1,\n mostRecentTimeStamp: 0,\n }\n\n recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void {\n const touchHistory = this._touchHistory\n if (isMoveish(topLevelType)) {\n nativeEvent.changedTouches.forEach((touch) =>\n recordTouchMove(touch, touchHistory),\n )\n } else if (isStartish(topLevelType)) {\n nativeEvent.changedTouches.forEach((touch) =>\n recordTouchStart(touch, touchHistory),\n )\n touchHistory.numberActiveTouches = nativeEvent.touches.length\n if (touchHistory.numberActiveTouches === 1) {\n touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier\n }\n } else if (isEndish(topLevelType)) {\n nativeEvent.changedTouches.forEach((touch) =>\n recordTouchEnd(touch, touchHistory),\n )\n touchHistory.numberActiveTouches = nativeEvent.touches.length\n if (touchHistory.numberActiveTouches === 1) {\n const { touchBank } = touchHistory\n for (let i = 0; i < touchBank.length; i++) {\n const touchTrackToCheck = touchBank[i]\n // @ts-ignore\n if (touchTrackToCheck?.touchActive) {\n touchHistory.indexOfSingleActiveTouch = i\n break\n }\n }\n if (process.env.NODE_ENV === 'development') {\n const activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]\n // @ts-ignore\n if (!activeRecord?.touchActive) {\n // eslint-disable-next-line no-console\n console.error('Cannot find single active touch.')\n }\n }\n }\n }\n }\n\n get touchHistory(): TouchHistory {\n return this._touchHistory\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,129 @@
1
+ import { getBoundingClientRect } from "./utils";
2
+ const emptyFunction = () => {
3
+ };
4
+ const emptyObject = {};
5
+ const emptyArray = [];
6
+ function normalizeIdentifier(identifier) {
7
+ return identifier > 20 ? identifier % 20 : identifier;
8
+ }
9
+ function createResponderEvent(domEvent, responderTouchHistoryStore) {
10
+ let rect;
11
+ let propagationWasStopped = false;
12
+ let changedTouches;
13
+ let touches;
14
+ const domEventChangedTouches = domEvent.changedTouches;
15
+ const domEventType = domEvent.type;
16
+ const metaKey = domEvent.metaKey === true;
17
+ const shiftKey = domEvent.shiftKey === true;
18
+ const force = (domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].force) || 0;
19
+ const identifier = normalizeIdentifier((domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].identifier) || 0);
20
+ const clientX = (domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].clientX) || domEvent.clientX;
21
+ const clientY = (domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].clientY) || domEvent.clientY;
22
+ const pageX = (domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].pageX) || domEvent.pageX;
23
+ const pageY = (domEventChangedTouches == null ? void 0 : domEventChangedTouches[0].pageY) || domEvent.pageY;
24
+ const preventDefault = typeof domEvent.preventDefault === "function" ? domEvent.preventDefault.bind(domEvent) : emptyFunction;
25
+ const timestamp = domEvent.timeStamp;
26
+ function normalizeTouches(touches2) {
27
+ return Array.prototype.slice.call(touches2).map((touch) => {
28
+ return {
29
+ force: touch.force,
30
+ identifier: normalizeIdentifier(touch.identifier),
31
+ get locationX() {
32
+ return locationX(touch.clientX);
33
+ },
34
+ get locationY() {
35
+ return locationY(touch.clientY);
36
+ },
37
+ pageX: touch.pageX,
38
+ pageY: touch.pageY,
39
+ target: touch.target,
40
+ timestamp
41
+ };
42
+ });
43
+ }
44
+ if (domEventChangedTouches != null) {
45
+ changedTouches = normalizeTouches(domEventChangedTouches);
46
+ touches = normalizeTouches(domEvent.touches);
47
+ } else {
48
+ const emulatedTouches = [
49
+ {
50
+ force,
51
+ identifier,
52
+ get locationX() {
53
+ return locationX(clientX);
54
+ },
55
+ get locationY() {
56
+ return locationY(clientY);
57
+ },
58
+ pageX,
59
+ pageY,
60
+ target: domEvent.target,
61
+ timestamp
62
+ }
63
+ ];
64
+ changedTouches = emulatedTouches;
65
+ touches = domEventType === "mouseup" || domEventType === "dragstart" ? emptyArray : emulatedTouches;
66
+ }
67
+ const responderEvent = {
68
+ bubbles: true,
69
+ cancelable: true,
70
+ // `currentTarget` is set before dispatch
71
+ currentTarget: null,
72
+ defaultPrevented: domEvent.defaultPrevented,
73
+ dispatchConfig: emptyObject,
74
+ eventPhase: domEvent.eventPhase,
75
+ isDefaultPrevented() {
76
+ return domEvent.defaultPrevented;
77
+ },
78
+ isPropagationStopped() {
79
+ return propagationWasStopped;
80
+ },
81
+ isTrusted: domEvent.isTrusted,
82
+ nativeEvent: {
83
+ altKey: false,
84
+ ctrlKey: false,
85
+ metaKey,
86
+ shiftKey,
87
+ changedTouches,
88
+ force,
89
+ identifier,
90
+ get locationX() {
91
+ return locationX(clientX);
92
+ },
93
+ get locationY() {
94
+ return locationY(clientY);
95
+ },
96
+ pageX,
97
+ pageY,
98
+ target: domEvent.target,
99
+ timestamp,
100
+ touches,
101
+ type: domEventType
102
+ },
103
+ persist: emptyFunction,
104
+ preventDefault,
105
+ stopPropagation() {
106
+ propagationWasStopped = true;
107
+ },
108
+ target: domEvent.target,
109
+ timeStamp: timestamp,
110
+ touchHistory: responderTouchHistoryStore.touchHistory
111
+ };
112
+ function locationX(x) {
113
+ rect = rect || getBoundingClientRect(responderEvent.currentTarget);
114
+ if (rect) {
115
+ return x - rect.left;
116
+ }
117
+ }
118
+ function locationY(y) {
119
+ rect = rect || getBoundingClientRect(responderEvent.currentTarget);
120
+ if (rect) {
121
+ return y - rect.top;
122
+ }
123
+ }
124
+ return responderEvent;
125
+ }
126
+ export {
127
+ createResponderEvent as default
128
+ };
129
+ //# sourceMappingURL=createResponderEvent.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/createResponderEvent.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport {\n ResponderTouchHistoryStore,\n TouchHistory,\n} from './ResponderTouchHistoryStore'\nimport { getBoundingClientRect } from './utils'\n\nexport type ResponderEvent = {\n bubbles: boolean\n cancelable: boolean\n currentTarget: any\n defaultPrevented: boolean | null\n dispatchConfig: {\n registrationName?: string\n phasedRegistrationNames?: {\n bubbled: string\n captured: string\n }\n }\n eventPhase: number | null\n isDefaultPrevented: () => boolean\n isPropagationStopped: () => boolean\n isTrusted: boolean | null\n preventDefault: () => void\n stopPropagation: () => void\n nativeEvent: TouchEvent\n persist: () => void\n target: any | null\n timeStamp: number\n touchHistory: TouchHistory\n}\n\nconst emptyFunction = () => {}\nconst emptyObject = {}\nconst emptyArray = []\n\n/**\n * Safari produces very large identifiers that would cause the `touchBank` array\n * length to be so large as to crash the browser, if not normalized like this.\n * In the future the `touchBank` should use an object/map instead.\n */\nfunction normalizeIdentifier(identifier) {\n return identifier > 20 ? identifier % 20 : identifier\n}\n\n/**\n * Converts a native DOM event to a ResponderEvent.\n * Mouse events are transformed into fake touch events.\n */\nexport default function createResponderEvent(\n domEvent: any,\n responderTouchHistoryStore: ResponderTouchHistoryStore,\n): ResponderEvent {\n let rect\n let propagationWasStopped = false\n let changedTouches\n let touches\n\n const domEventChangedTouches = domEvent.changedTouches\n const domEventType = domEvent.type\n\n const metaKey = domEvent.metaKey === true\n const shiftKey = domEvent.shiftKey === true\n const force = domEventChangedTouches?.[0].force || 0\n const identifier = normalizeIdentifier(domEventChangedTouches?.[0].identifier || 0)\n const clientX = domEventChangedTouches?.[0].clientX || domEvent.clientX\n const clientY = domEventChangedTouches?.[0].clientY || domEvent.clientY\n const pageX = domEventChangedTouches?.[0].pageX || domEvent.pageX\n const pageY = domEventChangedTouches?.[0].pageY || domEvent.pageY\n const preventDefault =\n typeof domEvent.preventDefault === 'function'\n ? domEvent.preventDefault.bind(domEvent)\n : emptyFunction\n const timestamp = domEvent.timeStamp\n\n function normalizeTouches(touches) {\n return Array.prototype.slice.call(touches).map((touch) => {\n return {\n force: touch.force,\n identifier: normalizeIdentifier(touch.identifier),\n get locationX() {\n return locationX(touch.clientX)\n },\n get locationY() {\n return locationY(touch.clientY)\n },\n pageX: touch.pageX,\n pageY: touch.pageY,\n target: touch.target,\n timestamp,\n }\n })\n }\n\n if (domEventChangedTouches != null) {\n changedTouches = normalizeTouches(domEventChangedTouches)\n touches = normalizeTouches(domEvent.touches)\n } else {\n const emulatedTouches = [\n {\n force,\n identifier,\n get locationX() {\n return locationX(clientX)\n },\n get locationY() {\n return locationY(clientY)\n },\n pageX,\n pageY,\n target: domEvent.target,\n timestamp,\n },\n ]\n changedTouches = emulatedTouches\n touches =\n domEventType === 'mouseup' || domEventType === 'dragstart'\n ? emptyArray\n : emulatedTouches\n }\n\n const responderEvent = {\n bubbles: true,\n cancelable: true,\n // `currentTarget` is set before dispatch\n currentTarget: null,\n defaultPrevented: domEvent.defaultPrevented,\n dispatchConfig: emptyObject,\n eventPhase: domEvent.eventPhase,\n isDefaultPrevented() {\n return domEvent.defaultPrevented\n },\n isPropagationStopped() {\n return propagationWasStopped\n },\n isTrusted: domEvent.isTrusted,\n nativeEvent: {\n altKey: false,\n ctrlKey: false,\n metaKey,\n shiftKey,\n changedTouches,\n force,\n identifier,\n get locationX() {\n return locationX(clientX)\n },\n get locationY() {\n return locationY(clientY)\n },\n pageX,\n pageY,\n target: domEvent.target,\n timestamp,\n touches,\n type: domEventType,\n },\n persist: emptyFunction,\n preventDefault,\n stopPropagation() {\n propagationWasStopped = true\n },\n target: domEvent.target,\n timeStamp: timestamp,\n touchHistory: responderTouchHistoryStore.touchHistory,\n }\n\n // Using getters and functions serves two purposes:\n // 1) The value of `currentTarget` is not initially available.\n // 2) Measuring the clientRect may cause layout jank and should only be done on-demand.\n function locationX(x) {\n rect = rect || getBoundingClientRect(responderEvent.currentTarget)\n if (rect) {\n return x - rect.left\n }\n }\n function locationY(y) {\n rect = rect || getBoundingClientRect(responderEvent.currentTarget)\n if (rect) {\n return y - rect.top\n }\n }\n\n return responderEvent as any\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["touches"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./useResponderEvents";
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["export * from './useResponderEvents'\n"],
5
+ "mappings": "AAAA,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,55 @@
1
+ const BLUR = "blur";
2
+ const CONTEXT_MENU = "contextmenu";
3
+ const FOCUS_OUT = "focusout";
4
+ const MOUSE_DOWN = "mousedown";
5
+ const MOUSE_MOVE = "mousemove";
6
+ const MOUSE_UP = "mouseup";
7
+ const MOUSE_CANCEL = "dragstart";
8
+ const TOUCH_START = "touchstart";
9
+ const TOUCH_MOVE = "touchmove";
10
+ const TOUCH_END = "touchend";
11
+ const TOUCH_CANCEL = "touchcancel";
12
+ const SCROLL = "scroll";
13
+ const SELECT = "select";
14
+ const SELECTION_CHANGE = "selectionchange";
15
+ function isStartish(eventType) {
16
+ return eventType === TOUCH_START || eventType === MOUSE_DOWN;
17
+ }
18
+ function isMoveish(eventType) {
19
+ return eventType === TOUCH_MOVE || eventType === MOUSE_MOVE;
20
+ }
21
+ function isEndish(eventType) {
22
+ return eventType === TOUCH_END || eventType === MOUSE_UP || isCancelish(eventType);
23
+ }
24
+ function isCancelish(eventType) {
25
+ return eventType === TOUCH_CANCEL || eventType === MOUSE_CANCEL;
26
+ }
27
+ function isScroll(eventType) {
28
+ return eventType === SCROLL;
29
+ }
30
+ function isSelectionChange(eventType) {
31
+ return eventType === SELECT || eventType === SELECTION_CHANGE;
32
+ }
33
+ export {
34
+ BLUR,
35
+ CONTEXT_MENU,
36
+ FOCUS_OUT,
37
+ MOUSE_CANCEL,
38
+ MOUSE_DOWN,
39
+ MOUSE_MOVE,
40
+ MOUSE_UP,
41
+ SCROLL,
42
+ SELECT,
43
+ SELECTION_CHANGE,
44
+ TOUCH_CANCEL,
45
+ TOUCH_END,
46
+ TOUCH_MOVE,
47
+ TOUCH_START,
48
+ isCancelish,
49
+ isEndish,
50
+ isMoveish,
51
+ isScroll,
52
+ isSelectionChange,
53
+ isStartish
54
+ };
55
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/types.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nexport type Touch = {\n force: number\n identifier: number\n // The locationX and locationY properties are non-standard additions\n locationX: any\n locationY: any\n pageX: number\n pageY: number\n target: any\n // Touches in a list have a timestamp property\n timestamp: number\n}\n\nexport type TouchEvent = {\n altKey: boolean\n ctrlKey: boolean\n metaKey: boolean\n shiftKey: boolean\n // TouchList is an array in the Responder system\n changedTouches: Array<Touch>\n force: number\n // React Native adds properties to the \"nativeEvent that are usually only found on W3C Touches \u203E\\_(\u30C4)_/\u203E\n identifier: number\n locationX: any\n locationY: any\n pageX: number\n pageY: number\n target: any\n // The timestamp has a lowercase \"s\" in the Responder system\n timestamp: number\n // TouchList is an array in the Responder system\n touches: Array<Touch>\n}\n\nexport const BLUR = 'blur'\nexport const CONTEXT_MENU = 'contextmenu'\nexport const FOCUS_OUT = 'focusout'\nexport const MOUSE_DOWN = 'mousedown'\nexport const MOUSE_MOVE = 'mousemove'\nexport const MOUSE_UP = 'mouseup'\nexport const MOUSE_CANCEL = 'dragstart'\nexport const TOUCH_START = 'touchstart'\nexport const TOUCH_MOVE = 'touchmove'\nexport const TOUCH_END = 'touchend'\nexport const TOUCH_CANCEL = 'touchcancel'\nexport const SCROLL = 'scroll'\nexport const SELECT = 'select'\nexport const SELECTION_CHANGE = 'selectionchange'\n\nexport function isStartish(eventType: unknown): boolean {\n return eventType === TOUCH_START || eventType === MOUSE_DOWN\n}\n\nexport function isMoveish(eventType: unknown): boolean {\n return eventType === TOUCH_MOVE || eventType === MOUSE_MOVE\n}\n\nexport function isEndish(eventType: unknown): boolean {\n return eventType === TOUCH_END || eventType === MOUSE_UP || isCancelish(eventType)\n}\n\nexport function isCancelish(eventType: unknown): boolean {\n return eventType === TOUCH_CANCEL || eventType === MOUSE_CANCEL\n}\n\nexport function isScroll(eventType: unknown): boolean {\n return eventType === SCROLL\n}\n\nexport function isSelectionChange(eventType: unknown): boolean {\n return eventType === SELECT || eventType === SELECTION_CHANGE\n}\n"],
5
+ "mappings": "AAwCO,MAAM,OAAO;AACb,MAAM,eAAe;AACrB,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,WAAW;AACjB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,SAAS;AACf,MAAM,SAAS;AACf,MAAM,mBAAmB;AAEzB,SAAS,WAAW,WAA6B;AACtD,SAAO,cAAc,eAAe,cAAc;AACpD;AAEO,SAAS,UAAU,WAA6B;AACrD,SAAO,cAAc,cAAc,cAAc;AACnD;AAEO,SAAS,SAAS,WAA6B;AACpD,SAAO,cAAc,aAAa,cAAc,YAAY,YAAY,SAAS;AACnF;AAEO,SAAS,YAAY,WAA6B;AACvD,SAAO,cAAc,gBAAgB,cAAc;AACrD;AAEO,SAAS,SAAS,WAA6B;AACpD,SAAO,cAAc;AACvB;AAEO,SAAS,kBAAkB,WAA6B;AAC7D,SAAO,cAAc,UAAU,cAAc;AAC/C;",
6
+ "names": []
7
+ }
@@ -0,0 +1,45 @@
1
+ import * as React from "react";
2
+ import * as ResponderSystem from "./ResponderSystem";
3
+ export * from "./utils";
4
+ const emptyObject = {};
5
+ function useResponderEvents(hostRef, config = emptyObject) {
6
+ const id = React.useId();
7
+ const isAttachedRef = React.useRef(false);
8
+ React.useEffect(() => {
9
+ ResponderSystem.attachListeners();
10
+ return () => {
11
+ ResponderSystem.removeNode(id);
12
+ };
13
+ }, [id]);
14
+ React.useEffect(() => {
15
+ const {
16
+ onMoveShouldSetResponder,
17
+ onMoveShouldSetResponderCapture,
18
+ onScrollShouldSetResponder,
19
+ onScrollShouldSetResponderCapture,
20
+ onSelectionChangeShouldSetResponder,
21
+ onSelectionChangeShouldSetResponderCapture,
22
+ onStartShouldSetResponder,
23
+ onStartShouldSetResponderCapture
24
+ } = config;
25
+ const requiresResponderSystem = onMoveShouldSetResponder != null || onMoveShouldSetResponderCapture != null || onScrollShouldSetResponder != null || onScrollShouldSetResponderCapture != null || onSelectionChangeShouldSetResponder != null || onSelectionChangeShouldSetResponderCapture != null || onStartShouldSetResponder != null || onStartShouldSetResponderCapture != null;
26
+ const node = hostRef.current;
27
+ if (requiresResponderSystem) {
28
+ ResponderSystem.addNode(id, node, config);
29
+ isAttachedRef.current = true;
30
+ } else if (isAttachedRef.current) {
31
+ ResponderSystem.removeNode(id);
32
+ isAttachedRef.current = false;
33
+ }
34
+ }, [config, hostRef, id]);
35
+ if (process.env.NODE_ENV === "development") {
36
+ React.useDebugValue({
37
+ isResponder: hostRef.current === ResponderSystem.getResponderNode()
38
+ });
39
+ React.useDebugValue(config);
40
+ }
41
+ }
42
+ export {
43
+ useResponderEvents
44
+ };
45
+ //# sourceMappingURL=useResponderEvents.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/useResponderEvents.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\n\nimport * as ResponderSystem from './ResponderSystem'\n\nexport * from './utils'\n\nconst emptyObject = {}\n\nexport function useResponderEvents(\n hostRef: any,\n config: ResponderSystem.ResponderConfig = emptyObject,\n) {\n const id = React.useId()\n const isAttachedRef = React.useRef(false)\n\n // This is a separate effects so it doesn't run when the config changes.\n // On initial mount, attach global listeners if needed.\n // On unmount, remove node potentially attached to the Responder System.\n React.useEffect(() => {\n ResponderSystem.attachListeners()\n return () => {\n ResponderSystem.removeNode(id)\n }\n }, [id])\n\n // Register and unregister with the Responder System as necessary\n React.useEffect(() => {\n const {\n onMoveShouldSetResponder,\n onMoveShouldSetResponderCapture,\n onScrollShouldSetResponder,\n onScrollShouldSetResponderCapture,\n onSelectionChangeShouldSetResponder,\n onSelectionChangeShouldSetResponderCapture,\n onStartShouldSetResponder,\n onStartShouldSetResponderCapture,\n } = config\n\n const requiresResponderSystem =\n onMoveShouldSetResponder != null ||\n onMoveShouldSetResponderCapture != null ||\n onScrollShouldSetResponder != null ||\n onScrollShouldSetResponderCapture != null ||\n onSelectionChangeShouldSetResponder != null ||\n onSelectionChangeShouldSetResponderCapture != null ||\n onStartShouldSetResponder != null ||\n onStartShouldSetResponderCapture != null\n\n const node = hostRef.current\n\n if (requiresResponderSystem) {\n ResponderSystem.addNode(id, node, config)\n isAttachedRef.current = true\n } else if (isAttachedRef.current) {\n ResponderSystem.removeNode(id)\n isAttachedRef.current = false\n }\n }, [config, hostRef, id])\n\n if (process.env.NODE_ENV === 'development') {\n React.useDebugValue({\n isResponder: hostRef.current === ResponderSystem.getResponderNode(),\n })\n React.useDebugValue(config)\n }\n}\n"],
5
+ "mappings": "AAMA,YAAY,WAAW;AAEvB,YAAY,qBAAqB;AAEjC,cAAc;AAEd,MAAM,cAAc,CAAC;AAEd,SAAS,mBACd,SACA,SAA0C,aAC1C;AACA,QAAM,KAAK,MAAM,MAAM;AACvB,QAAM,gBAAgB,MAAM,OAAO,KAAK;AAKxC,QAAM,UAAU,MAAM;AACpB,oBAAgB,gBAAgB;AAChC,WAAO,MAAM;AACX,sBAAgB,WAAW,EAAE;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAGP,QAAM,UAAU,MAAM;AACpB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AAEJ,UAAM,0BACJ,4BAA4B,QAC5B,mCAAmC,QACnC,8BAA8B,QAC9B,qCAAqC,QACrC,uCAAuC,QACvC,8CAA8C,QAC9C,6BAA6B,QAC7B,oCAAoC;AAEtC,UAAM,OAAO,QAAQ;AAErB,QAAI,yBAAyB;AAC3B,sBAAgB,QAAQ,IAAI,MAAM,MAAM;AACxC,oBAAc,UAAU;AAAA,IAC1B,WAAW,cAAc,SAAS;AAChC,sBAAgB,WAAW,EAAE;AAC7B,oBAAc,UAAU;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,EAAE,CAAC;AAExB,MAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,UAAM,cAAc;AAAA,MAClB,aAAa,QAAQ,YAAY,gBAAgB,iBAAiB;AAAA,IACpE,CAAC;AACD,UAAM,cAAc,MAAM;AAAA,EAC5B;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,142 @@
1
+ const keyName = "__reactResponderId";
2
+ const canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
3
+ const getBoundingClientRect = (node) => {
4
+ if (!node)
5
+ return;
6
+ if (node.nodeType !== 1)
7
+ return;
8
+ if (node.getBoundingClientRect) {
9
+ return node.getBoundingClientRect();
10
+ }
11
+ };
12
+ function getEventPath(domEvent) {
13
+ var _a;
14
+ if (domEvent.type === "selectionchange") {
15
+ const target = (_a = window.getSelection()) == null ? void 0 : _a.anchorNode;
16
+ return composedPathFallback(target);
17
+ } else {
18
+ const path = domEvent.composedPath != null ? domEvent.composedPath() : composedPathFallback(domEvent.target);
19
+ return path;
20
+ }
21
+ }
22
+ function composedPathFallback(target) {
23
+ const path = [];
24
+ while (target != null && target !== document.body) {
25
+ path.push(target);
26
+ target = target.parentNode;
27
+ }
28
+ return path;
29
+ }
30
+ function getResponderId(node) {
31
+ if (node != null) {
32
+ return node[keyName];
33
+ }
34
+ return null;
35
+ }
36
+ function setResponderId(node, id) {
37
+ if (node != null) {
38
+ node[keyName] = id;
39
+ }
40
+ }
41
+ function getResponderPaths(domEvent) {
42
+ const idPath = [];
43
+ const nodePath = [];
44
+ const eventPath = getEventPath(domEvent);
45
+ for (let i = 0; i < eventPath.length; i++) {
46
+ const node = eventPath[i];
47
+ const id = getResponderId(node);
48
+ if (id != null) {
49
+ idPath.push(id);
50
+ nodePath.push(node);
51
+ }
52
+ }
53
+ return { idPath, nodePath };
54
+ }
55
+ function getLowestCommonAncestor(pathA, pathB) {
56
+ let pathALength = pathA.length;
57
+ let pathBLength = pathB.length;
58
+ if (
59
+ // If either path is empty
60
+ pathALength === 0 || pathBLength === 0 || // If the last elements aren't the same there can't be a common ancestor
61
+ // that is connected to the responder system
62
+ pathA[pathALength - 1] !== pathB[pathBLength - 1]
63
+ ) {
64
+ return null;
65
+ }
66
+ let itemA = pathA[0];
67
+ let indexA = 0;
68
+ let itemB = pathB[0];
69
+ let indexB = 0;
70
+ if (pathALength - pathBLength > 0) {
71
+ indexA = pathALength - pathBLength;
72
+ itemA = pathA[indexA];
73
+ pathALength = pathBLength;
74
+ }
75
+ if (pathBLength - pathALength > 0) {
76
+ indexB = pathBLength - pathALength;
77
+ itemB = pathB[indexB];
78
+ pathBLength = pathALength;
79
+ }
80
+ let depth = pathALength;
81
+ while (depth--) {
82
+ if (itemA === itemB) {
83
+ return itemA;
84
+ }
85
+ itemA = pathA[indexA++];
86
+ itemB = pathB[indexB++];
87
+ }
88
+ return null;
89
+ }
90
+ function hasTargetTouches(target, touches) {
91
+ if (!touches || touches.length === 0) {
92
+ return false;
93
+ }
94
+ for (let i = 0; i < touches.length; i++) {
95
+ const node = touches[i].target;
96
+ if (node != null) {
97
+ if (target.contains(node)) {
98
+ return true;
99
+ }
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+ function hasValidSelection(domEvent) {
105
+ if (domEvent.type === "selectionchange") {
106
+ return isSelectionValid();
107
+ }
108
+ return domEvent.type === "select";
109
+ }
110
+ function isPrimaryPointerDown(domEvent) {
111
+ const { altKey, button, buttons, ctrlKey, type } = domEvent;
112
+ const isTouch = type === "touchstart" || type === "touchmove";
113
+ const isPrimaryMouseDown = type === "mousedown" && (button === 0 || buttons === 1);
114
+ const isPrimaryMouseMove = type === "mousemove" && buttons === 1;
115
+ const noModifiers = altKey === false && ctrlKey === false;
116
+ if (isTouch || isPrimaryMouseDown && noModifiers || isPrimaryMouseMove && noModifiers) {
117
+ return true;
118
+ }
119
+ return false;
120
+ }
121
+ function isSelectionValid() {
122
+ const selection = window.getSelection();
123
+ if (!selection)
124
+ return false;
125
+ const string = selection.toString();
126
+ const anchorNode = selection.anchorNode;
127
+ const focusNode = selection.focusNode;
128
+ const isTextNode = anchorNode && anchorNode.nodeType === window.Node.TEXT_NODE || focusNode && focusNode.nodeType === window.Node.TEXT_NODE;
129
+ return string.length >= 1 && string !== "\n" && !!isTextNode;
130
+ }
131
+ export {
132
+ canUseDOM,
133
+ getBoundingClientRect,
134
+ getLowestCommonAncestor,
135
+ getResponderPaths,
136
+ hasTargetTouches,
137
+ hasValidSelection,
138
+ isPrimaryPointerDown,
139
+ isSelectionValid,
140
+ setResponderId
141
+ };
142
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst keyName = '__reactResponderId'\n\nexport const canUseDOM = !!(\n typeof window !== 'undefined' &&\n window.document &&\n window.document.createElement\n)\n\nexport const getBoundingClientRect = (node: HTMLElement | null): void | DOMRect => {\n if (!node) return\n if (node.nodeType !== 1) return\n if (node.getBoundingClientRect) {\n return node.getBoundingClientRect()\n }\n}\n\nfunction getEventPath(domEvent: any): Array<any> {\n // The 'selectionchange' event always has the 'document' as the target.\n // Use the anchor node as the initial target to reconstruct a path.\n // (We actually only need the first \"responder\" node in practice.)\n if (domEvent.type === 'selectionchange') {\n const target = window.getSelection()?.anchorNode\n return composedPathFallback(target)\n } else {\n const path =\n domEvent.composedPath != null\n ? domEvent.composedPath()\n : composedPathFallback(domEvent.target)\n return path\n }\n}\n\nfunction composedPathFallback(target: any): Array<any> {\n const path: any[] = []\n while (target != null && target !== document.body) {\n path.push(target)\n target = target.parentNode\n }\n return path\n}\n\n/**\n * Retrieve the responderId from a host node\n */\nfunction getResponderId(node: any): number | null {\n if (node != null) {\n return node[keyName]\n }\n return null\n}\n\n/**\n * Store the responderId on a host node\n */\nexport function setResponderId(node: any, id: any) {\n if (node != null) {\n node[keyName] = id\n }\n}\n\n/**\n * Filter the event path to contain only the nodes attached to the responder system\n */\nexport function getResponderPaths(domEvent: any): {\n idPath: Array<number>\n nodePath: Array<any>\n} {\n const idPath: any[] = []\n const nodePath: any[] = []\n const eventPath = getEventPath(domEvent)\n for (let i = 0; i < eventPath.length; i++) {\n const node = eventPath[i]\n const id = getResponderId(node)\n if (id != null) {\n idPath.push(id)\n nodePath.push(node)\n }\n }\n return { idPath, nodePath }\n}\n\n/**\n * Walk the paths and find the first common ancestor\n */\nexport function getLowestCommonAncestor(pathA: Array<any>, pathB: Array<any>): any {\n let pathALength = pathA.length\n let pathBLength = pathB.length\n if (\n // If either path is empty\n pathALength === 0 ||\n pathBLength === 0 ||\n // If the last elements aren't the same there can't be a common ancestor\n // that is connected to the responder system\n pathA[pathALength - 1] !== pathB[pathBLength - 1]\n ) {\n return null\n }\n\n let itemA = pathA[0]\n let indexA = 0\n let itemB = pathB[0]\n let indexB = 0\n\n // If A is deeper, skip indices that can't match.\n if (pathALength - pathBLength > 0) {\n indexA = pathALength - pathBLength\n itemA = pathA[indexA]\n pathALength = pathBLength\n }\n\n // If B is deeper, skip indices that can't match\n if (pathBLength - pathALength > 0) {\n indexB = pathBLength - pathALength\n itemB = pathB[indexB]\n pathBLength = pathALength\n }\n\n // Walk in lockstep until a match is found\n let depth = pathALength\n while (depth--) {\n if (itemA === itemB) {\n return itemA\n }\n itemA = pathA[indexA++]\n itemB = pathB[indexB++]\n }\n return null\n}\n\n/**\n * Determine whether any of the active touches are within the current responder.\n * This cannot rely on W3C `targetTouches`, as neither IE11 nor Safari implement it.\n */\nexport function hasTargetTouches(target: any, touches: any): boolean {\n if (!touches || touches.length === 0) {\n return false\n }\n for (let i = 0; i < touches.length; i++) {\n const node = touches[i].target\n if (node != null) {\n if (target.contains(node)) {\n return true\n }\n }\n }\n return false\n}\n\n/**\n * Ignore 'selectionchange' events that don't correspond with a person's intent to\n * select text.\n */\nexport function hasValidSelection(domEvent: any): boolean {\n if (domEvent.type === 'selectionchange') {\n return isSelectionValid()\n }\n return domEvent.type === 'select'\n}\n\n/**\n * Events are only valid if the primary button was used without specific modifier keys.\n */\nexport function isPrimaryPointerDown(domEvent: any): boolean {\n const { altKey, button, buttons, ctrlKey, type } = domEvent\n const isTouch = type === 'touchstart' || type === 'touchmove'\n const isPrimaryMouseDown = type === 'mousedown' && (button === 0 || buttons === 1)\n const isPrimaryMouseMove = type === 'mousemove' && buttons === 1\n const noModifiers = altKey === false && ctrlKey === false\n\n if (\n isTouch ||\n (isPrimaryMouseDown && noModifiers) ||\n (isPrimaryMouseMove && noModifiers)\n ) {\n return true\n }\n return false\n}\n\nexport function isSelectionValid(): boolean {\n const selection = window.getSelection()\n if (!selection) return false\n const string = selection.toString()\n const anchorNode = selection.anchorNode\n const focusNode = selection.focusNode\n const isTextNode =\n (anchorNode && anchorNode.nodeType === window.Node.TEXT_NODE) ||\n (focusNode && focusNode.nodeType === window.Node.TEXT_NODE)\n return string.length >= 1 && string !== '\\n' && !!isTextNode\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/react-native-use-responder-events",
3
- "version": "1.2.8",
3
+ "version": "1.2.10",
4
4
  "types": "./types/index.d.ts",
5
5
  "main": "dist/cjs",
6
6
  "module": "dist/esm",
@@ -21,7 +21,7 @@
21
21
  "react": "^18.2.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@tamagui/build": "^1.2.8",
24
+ "@tamagui/build": "^1.2.10",
25
25
  "@types/react": "^18.0.15"
26
26
  },
27
27
  "publishConfig": {