@react-aria/interactions 3.4.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -13,11 +13,14 @@ var {
13
13
 
14
14
  var {
15
15
  mergeProps,
16
+ isIOS,
16
17
  runAfterTransition,
17
18
  focusWithoutScrolling,
18
19
  useGlobalListeners,
19
20
  useSyncRef,
20
- isMac
21
+ isMac,
22
+ useEvent,
23
+ useDescription
21
24
  } = require("@react-aria/utils");
22
25
 
23
26
  var _babelRuntimeHelpersObjectWithoutPropertiesLoose = $parcel$interopDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
@@ -28,43 +31,71 @@ function $parcel$interopDefault(a) {
28
31
  return a && a.__esModule ? a.default : a;
29
32
  }
30
33
 
34
+ // Note that state only matters here for iOS. Non-iOS gets user-select: none applied to the target element
35
+ // rather than at the document level so we just need to apply/remove user-select: none for each pressed element individually
31
36
  let $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'default';
32
37
  let $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = '';
38
+ let $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap = new WeakMap();
33
39
 
34
- function $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection() {
35
- if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state === 'default') {
36
- $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = document.documentElement.style.webkitUserSelect;
37
- document.documentElement.style.webkitUserSelect = 'none';
38
- }
40
+ function $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(target) {
41
+ if (isIOS()) {
42
+ if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state === 'default') {
43
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = document.documentElement.style.webkitUserSelect;
44
+ document.documentElement.style.webkitUserSelect = 'none';
45
+ }
39
46
 
40
- $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'disabled';
47
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'disabled';
48
+ } else if (target) {
49
+ // If not iOS, store the target's original user-select and change to user-select: none
50
+ // Ignore state since it doesn't apply for non iOS
51
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap.set(target, target.style.userSelect);
52
+ target.style.userSelect = 'none';
53
+ }
41
54
  }
42
55
 
43
- function $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection() {
44
- // If the state is already default, there's nothing to do.
45
- // If it is restoring, then there's no need to queue a second restore.
46
- if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state !== 'disabled') {
47
- return;
48
- }
56
+ function $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(target) {
57
+ if (isIOS()) {
58
+ // If the state is already default, there's nothing to do.
59
+ // If it is restoring, then there's no need to queue a second restore.
60
+ if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state !== 'disabled') {
61
+ return;
62
+ }
49
63
 
50
- $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'restoring'; // There appears to be a delay on iOS where selection still might occur
51
- // after pointer up, so wait a bit before removing user-select.
64
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'restoring'; // There appears to be a delay on iOS where selection still might occur
65
+ // after pointer up, so wait a bit before removing user-select.
66
+
67
+ setTimeout(() => {
68
+ // Wait for any CSS transitions to complete so we don't recompute style
69
+ // for the whole page in the middle of the animation and cause jank.
70
+ runAfterTransition(() => {
71
+ // Avoid race conditions
72
+ if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state === 'restoring') {
73
+ if (document.documentElement.style.webkitUserSelect === 'none') {
74
+ document.documentElement.style.webkitUserSelect = $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect || '';
75
+ }
52
76
 
53
- setTimeout(() => {
54
- // Wait for any CSS transitions to complete so we don't recompute style
55
- // for the whole page in the middle of the animation and cause jank.
56
- runAfterTransition(() => {
57
- // Avoid race conditions
58
- if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state === 'restoring') {
59
- if (document.documentElement.style.webkitUserSelect === 'none') {
60
- document.documentElement.style.webkitUserSelect = $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect || '';
77
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = '';
78
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'default';
61
79
  }
80
+ });
81
+ }, 300);
82
+ } else {
83
+ // If not iOS, restore the target's original user-select if any
84
+ // Ignore state since it doesn't apply for non iOS
85
+ if (target && $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap.has(target)) {
86
+ let targetOldUserSelect = $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap.get(target);
62
87
 
63
- $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = '';
64
- $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'default';
88
+ if (target.style.userSelect === 'none') {
89
+ target.style.userSelect = targetOldUserSelect;
65
90
  }
66
- });
67
- }, 300);
91
+
92
+ if (target.getAttribute('style') === '') {
93
+ target.removeAttribute('style');
94
+ }
95
+
96
+ $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap.delete(target);
97
+ }
98
+ }
68
99
  }
69
100
 
70
101
  /*
@@ -134,9 +165,11 @@ function usePress(props) {
134
165
  onPressUp,
135
166
  isDisabled,
136
167
  isPressed: isPressedProp,
137
- preventFocusOnPress
168
+ preventFocusOnPress,
169
+ shouldCancelOnPointerExit,
170
+ allowTextSelectionOnPress
138
171
  } = _usePressResponderCon,
139
- domProps = _babelRuntimeHelpersObjectWithoutPropertiesLoose(_usePressResponderCon, ["onPress", "onPressChange", "onPressStart", "onPressEnd", "onPressUp", "isDisabled", "isPressed", "preventFocusOnPress", "ref"]);
172
+ domProps = _babelRuntimeHelpersObjectWithoutPropertiesLoose(_usePressResponderCon, ["onPress", "onPressChange", "onPressStart", "onPressEnd", "onPressUp", "isDisabled", "isPressed", "preventFocusOnPress", "shouldCancelOnPointerExit", "allowTextSelectionOnPress", "ref"]);
140
173
 
141
174
  let propsRef = useRef(null);
142
175
  propsRef.current = {
@@ -145,7 +178,8 @@ function usePress(props) {
145
178
  onPressStart,
146
179
  onPressEnd,
147
180
  onPressUp,
148
- isDisabled
181
+ isDisabled,
182
+ shouldCancelOnPointerExit
149
183
  };
150
184
  let [isPressed, setPressed] = useState(false);
151
185
  let ref = useRef({
@@ -183,7 +217,8 @@ function usePress(props) {
183
217
  target: originalEvent.currentTarget,
184
218
  shiftKey: originalEvent.shiftKey,
185
219
  metaKey: originalEvent.metaKey,
186
- ctrlKey: originalEvent.ctrlKey
220
+ ctrlKey: originalEvent.ctrlKey,
221
+ altKey: originalEvent.altKey
187
222
  });
188
223
  }
189
224
 
@@ -221,7 +256,8 @@ function usePress(props) {
221
256
  target: originalEvent.currentTarget,
222
257
  shiftKey: originalEvent.shiftKey,
223
258
  metaKey: originalEvent.metaKey,
224
- ctrlKey: originalEvent.ctrlKey
259
+ ctrlKey: originalEvent.ctrlKey,
260
+ altKey: originalEvent.altKey
225
261
  });
226
262
  }
227
263
 
@@ -238,7 +274,8 @@ function usePress(props) {
238
274
  target: originalEvent.currentTarget,
239
275
  shiftKey: originalEvent.shiftKey,
240
276
  metaKey: originalEvent.metaKey,
241
- ctrlKey: originalEvent.ctrlKey
277
+ ctrlKey: originalEvent.ctrlKey,
278
+ altKey: originalEvent.altKey
242
279
  });
243
280
  }
244
281
  };
@@ -260,7 +297,8 @@ function usePress(props) {
260
297
  target: originalEvent.currentTarget,
261
298
  shiftKey: originalEvent.shiftKey,
262
299
  metaKey: originalEvent.metaKey,
263
- ctrlKey: originalEvent.ctrlKey
300
+ ctrlKey: originalEvent.ctrlKey,
301
+ altKey: originalEvent.altKey
264
302
  });
265
303
  }
266
304
  };
@@ -276,13 +314,16 @@ function usePress(props) {
276
314
  state.activePointerId = null;
277
315
  state.pointerType = null;
278
316
  removeAllGlobalListeners();
279
- $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection();
317
+
318
+ if (!allowTextSelectionOnPress) {
319
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
320
+ }
280
321
  }
281
322
  };
282
323
 
283
324
  let pressProps = {
284
325
  onKeyDown(e) {
285
- if ($ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(e.nativeEvent)) {
326
+ if ($ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(e.nativeEvent) && e.currentTarget.contains(e.target)) {
286
327
  e.preventDefault();
287
328
  e.stopPropagation(); // If the event is repeating, it may have started on a different element
288
329
  // after which focus moved to the current element. Ignore these events and
@@ -300,12 +341,16 @@ function usePress(props) {
300
341
  },
301
342
 
302
343
  onKeyUp(e) {
303
- if ($ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(e.nativeEvent) && !e.repeat) {
344
+ if ($ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(e.nativeEvent) && !e.repeat && e.currentTarget.contains(e.target)) {
304
345
  triggerPressUp($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), 'keyboard');
305
346
  }
306
347
  },
307
348
 
308
349
  onClick(e) {
350
+ if (e && !e.currentTarget.contains(e.target)) {
351
+ return;
352
+ }
353
+
309
354
  if (e && e.button === 0) {
310
355
  e.stopPropagation();
311
356
 
@@ -315,7 +360,7 @@ function usePress(props) {
315
360
  // trigger as if it were a keyboard click.
316
361
 
317
362
 
318
- if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent)) {
363
+ if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && (state.pointerType === 'virtual' || $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent))) {
319
364
  // Ensure the element receives focus (VoiceOver on iOS does not do this)
320
365
  if (!isDisabled && !preventFocusOnPress) {
321
366
  focusWithoutScrolling(e.currentTarget);
@@ -338,11 +383,12 @@ function usePress(props) {
338
383
  e.preventDefault();
339
384
  e.stopPropagation();
340
385
  state.isPressed = false;
341
- triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), 'keyboard', e.target === state.target);
386
+ let target = e.target;
387
+ triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), 'keyboard', state.target.contains(target));
342
388
  removeAllGlobalListeners(); // If the target is a link, trigger the click method to open the URL,
343
389
  // but defer triggering pressEnd until onClick event handler.
344
390
 
345
- if (e.target === state.target && $ed8d760564e19d8c7d03a6a4$var$isHTMLAnchorLink(state.target) || state.target.getAttribute('role') === 'link') {
391
+ if (state.target.contains(target) && $ed8d760564e19d8c7d03a6a4$var$isHTMLAnchorLink(state.target) || state.target.getAttribute('role') === 'link') {
346
392
  state.target.click();
347
393
  }
348
394
  }
@@ -350,8 +396,17 @@ function usePress(props) {
350
396
 
351
397
  if (typeof PointerEvent !== 'undefined') {
352
398
  pressProps.onPointerDown = e => {
353
- // Only handle left clicks
354
- if (e.button !== 0) {
399
+ // Only handle left clicks, and ignore events that bubbled through portals.
400
+ if (e.button !== 0 || !e.currentTarget.contains(e.target)) {
401
+ return;
402
+ } // iOS safari fires pointer events from VoiceOver with incorrect coordinates/target.
403
+ // Ignore and let the onClick handler take care of it instead.
404
+ // https://bugs.webkit.org/show_bug.cgi?id=222627
405
+ // https://bugs.webkit.org/show_bug.cgi?id=223202
406
+
407
+
408
+ if ($ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(e.nativeEvent)) {
409
+ state.pointerType = 'virtual';
355
410
  return;
356
411
  } // Due to browser inconsistencies, especially on mobile browsers, we prevent
357
412
  // default on pointer down and handle focusing the pressable element ourselves.
@@ -359,11 +414,9 @@ function usePress(props) {
359
414
 
360
415
  if ($ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(e.target)) {
361
416
  e.preventDefault();
362
- } // iOS safari fires pointer events from VoiceOver (but only when outside an iframe...)
363
- // https://bugs.webkit.org/show_bug.cgi?id=222627
364
-
417
+ }
365
418
 
366
- state.pointerType = $ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(e.nativeEvent) ? 'virtual' : e.pointerType;
419
+ state.pointerType = e.pointerType;
367
420
  e.stopPropagation();
368
421
 
369
422
  if (!state.isPressed) {
@@ -376,7 +429,10 @@ function usePress(props) {
376
429
  focusWithoutScrolling(e.currentTarget);
377
430
  }
378
431
 
379
- $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection();
432
+ if (!allowTextSelectionOnPress) {
433
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(state.target);
434
+ }
435
+
380
436
  triggerPressStart(e, state.pointerType);
381
437
  addGlobalListener(document, 'pointermove', onPointerMove, false);
382
438
  addGlobalListener(document, 'pointerup', onPointerUp, false);
@@ -385,6 +441,10 @@ function usePress(props) {
385
441
  };
386
442
 
387
443
  pressProps.onMouseDown = e => {
444
+ if (!e.currentTarget.contains(e.target)) {
445
+ return;
446
+ }
447
+
388
448
  if (e.button === 0) {
389
449
  // Chrome and Firefox on touch Windows devices require mouse down events
390
450
  // to be canceled in addition to pointer events, or an extra asynchronous
@@ -398,11 +458,16 @@ function usePress(props) {
398
458
  };
399
459
 
400
460
  pressProps.onPointerUp = e => {
401
- // Only handle left clicks
461
+ // iOS fires pointerup with zero width and height, so check the pointerType recorded during pointerdown.
462
+ if (!e.currentTarget.contains(e.target) || state.pointerType === 'virtual') {
463
+ return;
464
+ } // Only handle left clicks
402
465
  // Safari on iOS sometimes fires pointerup events, even
403
466
  // when the touch isn't over the target, so double check.
467
+
468
+
404
469
  if (e.button === 0 && $ed8d760564e19d8c7d03a6a4$var$isOverTarget(e, e.currentTarget)) {
405
- triggerPressUp(e, state.pointerType);
470
+ triggerPressUp(e, state.pointerType || e.pointerType);
406
471
  }
407
472
  }; // Safari on iOS < 13.2 does not implement pointerenter/pointerleave events correctly.
408
473
  // Use pointer move events instead to implement our own hit testing.
@@ -422,6 +487,10 @@ function usePress(props) {
422
487
  } else if (state.isOverTarget) {
423
488
  state.isOverTarget = false;
424
489
  triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType, false);
490
+
491
+ if (propsRef.current.shouldCancelOnPointerExit) {
492
+ cancel(e);
493
+ }
425
494
  }
426
495
  };
427
496
 
@@ -438,7 +507,10 @@ function usePress(props) {
438
507
  state.activePointerId = null;
439
508
  state.pointerType = null;
440
509
  removeAllGlobalListeners();
441
- $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection();
510
+
511
+ if (!allowTextSelectionOnPress) {
512
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
513
+ }
442
514
  }
443
515
  };
444
516
 
@@ -447,13 +519,17 @@ function usePress(props) {
447
519
  };
448
520
 
449
521
  pressProps.onDragStart = e => {
450
- // Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do.
522
+ if (!e.currentTarget.contains(e.target)) {
523
+ return;
524
+ } // Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do.
525
+
526
+
451
527
  cancel(e);
452
528
  };
453
529
  } else {
454
530
  pressProps.onMouseDown = e => {
455
531
  // Only handle left clicks
456
- if (e.button !== 0) {
532
+ if (e.button !== 0 || !e.currentTarget.contains(e.target)) {
457
533
  return;
458
534
  } // Due to browser inconsistencies, especially on mobile browsers, we prevent
459
535
  // default on mouse down and handle focusing the pressable element ourselves.
@@ -483,6 +559,10 @@ function usePress(props) {
483
559
  };
484
560
 
485
561
  pressProps.onMouseEnter = e => {
562
+ if (!e.currentTarget.contains(e.target)) {
563
+ return;
564
+ }
565
+
486
566
  e.stopPropagation();
487
567
 
488
568
  if (state.isPressed && !state.ignoreEmulatedMouseEvents) {
@@ -492,15 +572,27 @@ function usePress(props) {
492
572
  };
493
573
 
494
574
  pressProps.onMouseLeave = e => {
575
+ if (!e.currentTarget.contains(e.target)) {
576
+ return;
577
+ }
578
+
495
579
  e.stopPropagation();
496
580
 
497
581
  if (state.isPressed && !state.ignoreEmulatedMouseEvents) {
498
582
  state.isOverTarget = false;
499
583
  triggerPressEnd(e, state.pointerType, false);
584
+
585
+ if (propsRef.current.shouldCancelOnPointerExit) {
586
+ cancel(e);
587
+ }
500
588
  }
501
589
  };
502
590
 
503
591
  pressProps.onMouseUp = e => {
592
+ if (!e.currentTarget.contains(e.target)) {
593
+ return;
594
+ }
595
+
504
596
  if (!state.ignoreEmulatedMouseEvents && e.button === 0) {
505
597
  triggerPressUp(e, state.pointerType);
506
598
  }
@@ -530,6 +622,10 @@ function usePress(props) {
530
622
  };
531
623
 
532
624
  pressProps.onTouchStart = e => {
625
+ if (!e.currentTarget.contains(e.target)) {
626
+ return;
627
+ }
628
+
533
629
  e.stopPropagation();
534
630
  let touch = $ed8d760564e19d8c7d03a6a4$var$getTouchFromEvent(e.nativeEvent);
535
631
 
@@ -549,12 +645,19 @@ function usePress(props) {
549
645
  focusWithoutScrolling(e.currentTarget);
550
646
  }
551
647
 
552
- $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection();
648
+ if (!allowTextSelectionOnPress) {
649
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(state.target);
650
+ }
651
+
553
652
  triggerPressStart(e, state.pointerType);
554
653
  addGlobalListener(window, 'scroll', onScroll, true);
555
654
  };
556
655
 
557
656
  pressProps.onTouchMove = e => {
657
+ if (!e.currentTarget.contains(e.target)) {
658
+ return;
659
+ }
660
+
558
661
  e.stopPropagation();
559
662
 
560
663
  if (!state.isPressed) {
@@ -571,10 +674,18 @@ function usePress(props) {
571
674
  } else if (state.isOverTarget) {
572
675
  state.isOverTarget = false;
573
676
  triggerPressEnd(e, state.pointerType, false);
677
+
678
+ if (propsRef.current.shouldCancelOnPointerExit) {
679
+ cancel(e);
680
+ }
574
681
  }
575
682
  };
576
683
 
577
684
  pressProps.onTouchEnd = e => {
685
+ if (!e.currentTarget.contains(e.target)) {
686
+ return;
687
+ }
688
+
578
689
  e.stopPropagation();
579
690
 
580
691
  if (!state.isPressed) {
@@ -594,11 +705,19 @@ function usePress(props) {
594
705
  state.activePointerId = null;
595
706
  state.isOverTarget = false;
596
707
  state.ignoreEmulatedMouseEvents = true;
597
- $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection();
708
+
709
+ if (!allowTextSelectionOnPress) {
710
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
711
+ }
712
+
598
713
  removeAllGlobalListeners();
599
714
  };
600
715
 
601
716
  pressProps.onTouchCancel = e => {
717
+ if (!e.currentTarget.contains(e.target)) {
718
+ return;
719
+ }
720
+
602
721
  e.stopPropagation();
603
722
 
604
723
  if (state.isPressed) {
@@ -612,23 +731,32 @@ function usePress(props) {
612
731
  currentTarget: state.target,
613
732
  shiftKey: false,
614
733
  ctrlKey: false,
615
- metaKey: false
734
+ metaKey: false,
735
+ altKey: false
616
736
  });
617
737
  }
618
738
  };
619
739
 
620
740
  pressProps.onDragStart = e => {
741
+ if (!e.currentTarget.contains(e.target)) {
742
+ return;
743
+ }
744
+
621
745
  cancel(e);
622
746
  };
623
747
  }
624
748
 
625
749
  return pressProps;
626
- }, [addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners]); // Remove user-select: none in case component unmounts immediately after pressStart
750
+ }, [addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners, allowTextSelectionOnPress]); // Remove user-select: none in case component unmounts immediately after pressStart
627
751
  // eslint-disable-next-line arrow-body-style
628
752
 
629
753
  useEffect(() => {
630
- return () => $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection();
631
- }, []);
754
+ return () => {
755
+ if (!allowTextSelectionOnPress) {
756
+ $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(ref.current.target);
757
+ }
758
+ };
759
+ }, [allowTextSelectionOnPress]);
632
760
  return {
633
761
  isPressed: isPressedProp || isPressed,
634
762
  pressProps: mergeProps(domProps, pressProps)
@@ -644,6 +772,7 @@ function $ed8d760564e19d8c7d03a6a4$var$isHTMLAnchorLink(target) {
644
772
  function $ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(event) {
645
773
  const {
646
774
  key,
775
+ code,
647
776
  target
648
777
  } = event;
649
778
  const element = target;
@@ -654,7 +783,7 @@ function $ed8d760564e19d8c7d03a6a4$var$isValidKeyboardEvent(event) {
654
783
  const role = element.getAttribute('role'); // Accessibility for keyboards. Space and Enter only.
655
784
  // "Spacebar" is for IE 11
656
785
 
657
- return (key === 'Enter' || key === ' ' || key === 'Spacebar') && tagName !== 'INPUT' && tagName !== 'TEXTAREA' && isContentEditable !== true && ( // A link with a valid href should be handled natively,
786
+ return (key === 'Enter' || key === ' ' || key === 'Spacebar' || code === 'Space') && tagName !== 'INPUT' && tagName !== 'TEXTAREA' && isContentEditable !== true && ( // A link with a valid href should be handled natively,
658
787
  // unless it also has role='button' and was triggered using Space.
659
788
  !$ed8d760564e19d8c7d03a6a4$var$isHTMLAnchorLink(element) || role === 'button' && key !== 'Enter') && // An element with role='link' should only trigger with Enter key
660
789
  !(role === 'link' && key !== 'Enter');
@@ -691,13 +820,40 @@ function $ed8d760564e19d8c7d03a6a4$var$createEvent(target, e) {
691
820
  currentTarget: target,
692
821
  shiftKey: e.shiftKey,
693
822
  ctrlKey: e.ctrlKey,
694
- metaKey: e.metaKey
823
+ metaKey: e.metaKey,
824
+ altKey: e.altKey
825
+ };
826
+ }
827
+
828
+ function $ed8d760564e19d8c7d03a6a4$var$getPointClientRect(point) {
829
+ let offsetX = point.width / 2 || point.radiusX || 0;
830
+ let offsetY = point.height / 2 || point.radiusY || 0;
831
+ return {
832
+ top: point.clientY - offsetY,
833
+ right: point.clientX + offsetX,
834
+ bottom: point.clientY + offsetY,
835
+ left: point.clientX - offsetX
695
836
  };
696
837
  }
697
838
 
839
+ function $ed8d760564e19d8c7d03a6a4$var$areRectanglesOverlapping(a, b) {
840
+ // check if they cannot overlap on x axis
841
+ if (a.left > b.right || b.left > a.right) {
842
+ return false;
843
+ } // check if they cannot overlap on y axis
844
+
845
+
846
+ if (a.top > b.bottom || b.top > a.bottom) {
847
+ return false;
848
+ }
849
+
850
+ return true;
851
+ }
852
+
698
853
  function $ed8d760564e19d8c7d03a6a4$var$isOverTarget(point, target) {
699
854
  let rect = target.getBoundingClientRect();
700
- return (point.clientX || 0) >= (rect.left || 0) && (point.clientX || 0) <= (rect.right || 0) && (point.clientY || 0) >= (rect.top || 0) && (point.clientY || 0) <= (rect.bottom || 0);
855
+ let pointRect = $ed8d760564e19d8c7d03a6a4$var$getPointClientRect(point);
856
+ return $ed8d760564e19d8c7d03a6a4$var$areRectanglesOverlapping(rect, pointRect);
701
857
  }
702
858
 
703
859
  function $ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(target) {
@@ -707,7 +863,11 @@ function $ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(target) {
707
863
 
708
864
  function $ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(event) {
709
865
  // If the pointer size is zero, then we assume it's from a screen reader.
710
- return event.width === 0 && event.height === 0;
866
+ // Android TalkBack double tap will sometimes return a event with width and height of 1
867
+ // and pointerType === 'mouse' so we need to check for a specific combination of event attributes.
868
+ // Cannot use "event.pressure === 0" as the sole check due to Safari pointer events always returning pressure === 0
869
+ // instead of .5, see https://bugs.webkit.org/show_bug.cgi?id=206216
870
+ return event.width === 0 && event.height === 0 || event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0;
711
871
  }
712
872
 
713
873
  const Pressable = /*#__PURE__*/_react.forwardRef((_ref, ref) => {
@@ -745,7 +905,7 @@ const PressResponder = /*#__PURE__*/_react.forwardRef((_ref, ref) => {
745
905
  let isRegistered = useRef(false);
746
906
  let prevContext = useContext($c6b6d42ec461c27a6a09002bf49a250e$export$PressResponderContext);
747
907
  let context = mergeProps(prevContext || {}, _babelRuntimeHelpersExtends({}, props, {
748
- ref,
908
+ ref: ref || (prevContext == null ? void 0 : prevContext.ref),
749
909
 
750
910
  register() {
751
911
  isRegistered.current = true;
@@ -756,6 +916,7 @@ const PressResponder = /*#__PURE__*/_react.forwardRef((_ref, ref) => {
756
916
  }
757
917
 
758
918
  }));
919
+ useSyncRef(prevContext, ref);
759
920
  useEffect(() => {
760
921
  if (!isRegistered.current) {
761
922
  console.warn('A PressResponder was rendered without a pressable child. ' + 'Either call the usePress hook, or wrap your DOM node with <Pressable> component.');
@@ -824,7 +985,8 @@ exports.useFocus = useFocus;
824
985
  let $b83372066b2b4e1d9257843b2455c$var$currentModality = null;
825
986
  let $b83372066b2b4e1d9257843b2455c$var$changeHandlers = new Set();
826
987
  let $b83372066b2b4e1d9257843b2455c$var$hasSetupGlobalListeners = false;
827
- let $b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus = false; // Only Tab or Esc keys will make focus visible on text input elements
988
+ let $b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus = false;
989
+ let $b83372066b2b4e1d9257843b2455c$var$hasBlurredWindowRecently = false; // Only Tab or Esc keys will make focus visible on text input elements
828
990
 
829
991
  const $b83372066b2b4e1d9257843b2455c$var$FOCUS_VISIBLE_INPUT_KEYS = {
830
992
  Tab: true,
@@ -842,7 +1004,8 @@ function $b83372066b2b4e1d9257843b2455c$var$triggerChangeHandlers(modality, e) {
842
1004
 
843
1005
 
844
1006
  function $b83372066b2b4e1d9257843b2455c$var$isValidKey(e) {
845
- return !(e.metaKey || !isMac() && e.altKey || e.ctrlKey);
1007
+ // Control and Shift keys trigger when navigating back to the tab with keyboard.
1008
+ return !(e.metaKey || !isMac() && e.altKey || e.ctrlKey || e.key === 'Control' || e.key === 'Shift' || e.key === 'Meta');
846
1009
  }
847
1010
 
848
1011
  function $b83372066b2b4e1d9257843b2455c$var$handleKeyboardEvent(e) {
@@ -880,18 +1043,20 @@ function $b83372066b2b4e1d9257843b2455c$var$handleFocusEvent(e) {
880
1043
  // This occurs, for example, when navigating a form with the next/previous buttons on iOS.
881
1044
 
882
1045
 
883
- if (!$b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus) {
1046
+ if (!$b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus && !$b83372066b2b4e1d9257843b2455c$var$hasBlurredWindowRecently) {
884
1047
  $b83372066b2b4e1d9257843b2455c$var$currentModality = 'virtual';
885
1048
  $b83372066b2b4e1d9257843b2455c$var$triggerChangeHandlers('virtual', e);
886
1049
  }
887
1050
 
888
1051
  $b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus = false;
1052
+ $b83372066b2b4e1d9257843b2455c$var$hasBlurredWindowRecently = false;
889
1053
  }
890
1054
 
891
1055
  function $b83372066b2b4e1d9257843b2455c$var$handleWindowBlur() {
892
1056
  // When the window is blurred, reset state. This is necessary when tabbing out of the window,
893
1057
  // for example, since a subsequent focus event won't be fired.
894
1058
  $b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus = false;
1059
+ $b83372066b2b4e1d9257843b2455c$var$hasBlurredWindowRecently = true;
895
1060
  }
896
1061
  /**
897
1062
  * Setup global event listeners to control when keyboard focus style should be visible.
@@ -986,45 +1151,64 @@ function useInteractionModality() {
986
1151
  return modality;
987
1152
  }
988
1153
  /**
989
- * Manages focus visible state for the page, and subscribes individual components for updates.
1154
+ * If this is attached to text input component, return if the event is a focus event (Tab/Escape keys pressed) so that
1155
+ * focus visible style can be properly set.
990
1156
  */
991
1157
 
992
1158
 
993
1159
  exports.useInteractionModality = useInteractionModality;
994
1160
 
1161
+ function $b83372066b2b4e1d9257843b2455c$var$isKeyboardFocusEvent(isTextInput, modality, e) {
1162
+ return !(isTextInput && modality === 'keyboard' && e instanceof KeyboardEvent && !$b83372066b2b4e1d9257843b2455c$var$FOCUS_VISIBLE_INPUT_KEYS[e.key]);
1163
+ }
1164
+ /**
1165
+ * Manages focus visible state for the page, and subscribes individual components for updates.
1166
+ */
1167
+
1168
+
995
1169
  function useFocusVisible(props) {
996
1170
  if (props === void 0) {
997
1171
  props = {};
998
1172
  }
999
1173
 
1000
- $b83372066b2b4e1d9257843b2455c$var$setupGlobalFocusEvents();
1001
1174
  let {
1002
1175
  isTextInput,
1003
1176
  autoFocus
1004
1177
  } = props;
1005
1178
  let [isFocusVisibleState, setFocusVisible] = useState(autoFocus || isFocusVisible());
1179
+ useFocusVisibleListener(isFocusVisible => {
1180
+ setFocusVisible(isFocusVisible);
1181
+ }, [isTextInput], {
1182
+ isTextInput
1183
+ });
1184
+ return {
1185
+ isFocusVisible: isFocusVisibleState
1186
+ };
1187
+ }
1188
+ /**
1189
+ * Listens for trigger change and reports if focus is visible (i.e., modality is not pointer).
1190
+ */
1191
+
1192
+
1193
+ exports.useFocusVisible = useFocusVisible;
1194
+
1195
+ function useFocusVisibleListener(fn, deps, opts) {
1196
+ $b83372066b2b4e1d9257843b2455c$var$setupGlobalFocusEvents();
1006
1197
  useEffect(() => {
1007
1198
  let handler = (modality, e) => {
1008
- // If this is a text input component, don't update the focus visible style when
1009
- // typing except for when the Tab and Escape keys are pressed.
1010
- if (isTextInput && modality === 'keyboard' && e instanceof KeyboardEvent && !$b83372066b2b4e1d9257843b2455c$var$FOCUS_VISIBLE_INPUT_KEYS[e.key]) {
1199
+ if (!$b83372066b2b4e1d9257843b2455c$var$isKeyboardFocusEvent(opts == null ? void 0 : opts.isTextInput, modality, e)) {
1011
1200
  return;
1012
1201
  }
1013
1202
 
1014
- setFocusVisible(isFocusVisible());
1203
+ fn(isFocusVisible());
1015
1204
  };
1016
1205
 
1017
1206
  $b83372066b2b4e1d9257843b2455c$var$changeHandlers.add(handler);
1018
- return () => {
1019
- $b83372066b2b4e1d9257843b2455c$var$changeHandlers.delete(handler);
1020
- };
1021
- }, [isTextInput]);
1022
- return {
1023
- isFocusVisible: isFocusVisibleState
1024
- };
1207
+ return () => $b83372066b2b4e1d9257843b2455c$var$changeHandlers.delete(handler);
1208
+ }, deps);
1025
1209
  }
1026
1210
 
1027
- exports.useFocusVisible = useFocusVisible;
1211
+ exports.useFocusVisibleListener = useFocusVisibleListener;
1028
1212
 
1029
1213
  /**
1030
1214
  * Handles focus events for the target and its descendants.
@@ -1145,17 +1329,25 @@ function useHover(props) {
1145
1329
  let [isHovered, setHovered] = useState(false);
1146
1330
  let state = useRef({
1147
1331
  isHovered: false,
1148
- ignoreEmulatedMouseEvents: false
1332
+ ignoreEmulatedMouseEvents: false,
1333
+ pointerType: '',
1334
+ target: null
1149
1335
  }).current;
1150
1336
  useEffect($c4bc39b19aed2151a14d70718d3e34b1$var$setupGlobalTouchEvents, []);
1151
- let hoverProps = useMemo(() => {
1337
+ let {
1338
+ hoverProps,
1339
+ triggerHoverEnd
1340
+ } = useMemo(() => {
1152
1341
  let triggerHoverStart = (event, pointerType) => {
1153
- if (isDisabled || pointerType === 'touch' || state.isHovered) {
1342
+ state.pointerType = pointerType;
1343
+
1344
+ if (isDisabled || pointerType === 'touch' || state.isHovered || !event.currentTarget.contains(event.target)) {
1154
1345
  return;
1155
1346
  }
1156
1347
 
1157
1348
  state.isHovered = true;
1158
- let target = event.target;
1349
+ let target = event.currentTarget;
1350
+ state.target = target;
1159
1351
 
1160
1352
  if (onHoverStart) {
1161
1353
  onHoverStart({
@@ -1173,12 +1365,15 @@ function useHover(props) {
1173
1365
  };
1174
1366
 
1175
1367
  let triggerHoverEnd = (event, pointerType) => {
1368
+ state.pointerType = '';
1369
+ state.target = null;
1370
+
1176
1371
  if (pointerType === 'touch' || !state.isHovered) {
1177
1372
  return;
1178
1373
  }
1179
1374
 
1180
1375
  state.isHovered = false;
1181
- let target = event.target;
1376
+ let target = event.currentTarget;
1182
1377
 
1183
1378
  if (onHoverEnd) {
1184
1379
  onHoverEnd({
@@ -1207,7 +1402,9 @@ function useHover(props) {
1207
1402
  };
1208
1403
 
1209
1404
  hoverProps.onPointerLeave = e => {
1210
- triggerHoverEnd(e, e.pointerType);
1405
+ if (!isDisabled && e.currentTarget.contains(e.target)) {
1406
+ triggerHoverEnd(e, e.pointerType);
1407
+ }
1211
1408
  };
1212
1409
  } else {
1213
1410
  hoverProps.onTouchStart = () => {
@@ -1223,12 +1420,26 @@ function useHover(props) {
1223
1420
  };
1224
1421
 
1225
1422
  hoverProps.onMouseLeave = e => {
1226
- triggerHoverEnd(e, 'mouse');
1423
+ if (!isDisabled && e.currentTarget.contains(e.target)) {
1424
+ triggerHoverEnd(e, 'mouse');
1425
+ }
1227
1426
  };
1228
1427
  }
1229
1428
 
1230
- return hoverProps;
1429
+ return {
1430
+ hoverProps,
1431
+ triggerHoverEnd
1432
+ };
1231
1433
  }, [onHoverStart, onHoverChange, onHoverEnd, isDisabled, state]);
1434
+ useEffect(() => {
1435
+ // Call the triggerHoverEnd as soon as isDisabled changes to true
1436
+ // Safe to call triggerHoverEnd, it will early return if we aren't currently hovering
1437
+ if (isDisabled) {
1438
+ triggerHoverEnd({
1439
+ currentTarget: state.target
1440
+ }, state.pointerType);
1441
+ }
1442
+ }, [isDisabled]);
1232
1443
  return {
1233
1444
  hoverProps,
1234
1445
  isHovered
@@ -1245,81 +1456,80 @@ function useInteractOutside(props) {
1245
1456
  let {
1246
1457
  ref,
1247
1458
  onInteractOutside,
1248
- isDisabled
1459
+ isDisabled,
1460
+ onInteractOutsideStart
1249
1461
  } = props;
1250
1462
  let stateRef = useRef({
1251
1463
  isPointerDown: false,
1252
- ignoreEmulatedMouseEvents: false
1464
+ ignoreEmulatedMouseEvents: false,
1465
+ onInteractOutside,
1466
+ onInteractOutsideStart
1253
1467
  });
1254
1468
  let state = stateRef.current;
1469
+ state.onInteractOutside = onInteractOutside;
1470
+ state.onInteractOutsideStart = onInteractOutsideStart;
1255
1471
  useEffect(() => {
1472
+ if (isDisabled) {
1473
+ return;
1474
+ }
1475
+
1256
1476
  let onPointerDown = e => {
1257
- if (isDisabled) {
1258
- return;
1259
- }
1477
+ if ($f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref) && state.onInteractOutside) {
1478
+ if (state.onInteractOutsideStart) {
1479
+ state.onInteractOutsideStart(e);
1480
+ }
1260
1481
 
1261
- if ($f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1262
1482
  state.isPointerDown = true;
1263
1483
  }
1264
- };
1265
- /*
1266
- // FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=1675846 prevents us from using this pointerevent
1267
- // once it's fixed we can uncomment
1268
- // Use pointer events if available. Otherwise, fall back to mouse and touch events.
1484
+ }; // Use pointer events if available. Otherwise, fall back to mouse and touch events.
1485
+
1486
+
1269
1487
  if (typeof PointerEvent !== 'undefined') {
1270
- let onPointerUp = (e) => {
1271
- if (state.isPointerDown && onInteractOutside && isValidEvent(e, ref)) {
1488
+ let onPointerUp = e => {
1489
+ if (state.isPointerDown && state.onInteractOutside && $f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1272
1490
  state.isPointerDown = false;
1273
- onInteractOutside(e);
1491
+ state.onInteractOutside(e);
1274
1492
  }
1275
- };
1276
- // changing these to capture phase fixed combobox
1493
+ }; // changing these to capture phase fixed combobox
1494
+
1495
+
1277
1496
  document.addEventListener('pointerdown', onPointerDown, true);
1278
1497
  document.addEventListener('pointerup', onPointerUp, true);
1279
- return () => {
1498
+ return () => {
1280
1499
  document.removeEventListener('pointerdown', onPointerDown, true);
1281
1500
  document.removeEventListener('pointerup', onPointerUp, true);
1282
1501
  };
1283
- } else {*/
1284
-
1285
-
1286
- let onMouseUp = e => {
1287
- if (isDisabled) {
1288
- return;
1289
- }
1290
-
1291
- if (state.ignoreEmulatedMouseEvents) {
1292
- state.ignoreEmulatedMouseEvents = false;
1293
- } else if (state.isPointerDown && onInteractOutside && $f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1294
- state.isPointerDown = false;
1295
- onInteractOutside(e);
1296
- }
1297
- };
1298
-
1299
- let onTouchEnd = e => {
1300
- if (isDisabled) {
1301
- return;
1302
- }
1502
+ } else {
1503
+ let onMouseUp = e => {
1504
+ if (state.ignoreEmulatedMouseEvents) {
1505
+ state.ignoreEmulatedMouseEvents = false;
1506
+ } else if (state.isPointerDown && state.onInteractOutside && $f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1507
+ state.isPointerDown = false;
1508
+ state.onInteractOutside(e);
1509
+ }
1510
+ };
1303
1511
 
1304
- state.ignoreEmulatedMouseEvents = true;
1512
+ let onTouchEnd = e => {
1513
+ state.ignoreEmulatedMouseEvents = true;
1305
1514
 
1306
- if (onInteractOutside && state.isPointerDown && $f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1307
- state.isPointerDown = false;
1308
- onInteractOutside(e);
1309
- }
1310
- };
1515
+ if (state.onInteractOutside && state.isPointerDown && $f07e167670fb16f6a9d7f8a0eda7e156$var$isValidEvent(e, ref)) {
1516
+ state.isPointerDown = false;
1517
+ state.onInteractOutside(e);
1518
+ }
1519
+ };
1311
1520
 
1312
- document.addEventListener('mousedown', onPointerDown, true);
1313
- document.addEventListener('mouseup', onMouseUp, true);
1314
- document.addEventListener('touchstart', onPointerDown, true);
1315
- document.addEventListener('touchend', onTouchEnd, true);
1316
- return () => {
1317
- document.removeEventListener('mousedown', onPointerDown, true);
1318
- document.removeEventListener('mouseup', onMouseUp, true);
1319
- document.removeEventListener('touchstart', onPointerDown, true);
1320
- document.removeEventListener('touchend', onTouchEnd, true);
1321
- };
1322
- }, [onInteractOutside, ref, state.ignoreEmulatedMouseEvents, state.isPointerDown, isDisabled]);
1521
+ document.addEventListener('mousedown', onPointerDown, true);
1522
+ document.addEventListener('mouseup', onMouseUp, true);
1523
+ document.addEventListener('touchstart', onPointerDown, true);
1524
+ document.addEventListener('touchend', onTouchEnd, true);
1525
+ return () => {
1526
+ document.removeEventListener('mousedown', onPointerDown, true);
1527
+ document.removeEventListener('mouseup', onMouseUp, true);
1528
+ document.removeEventListener('touchstart', onPointerDown, true);
1529
+ document.removeEventListener('touchend', onTouchEnd, true);
1530
+ };
1531
+ }
1532
+ }, [ref, state, isDisabled]);
1323
1533
  }
1324
1534
 
1325
1535
  exports.useInteractOutside = useInteractOutside;
@@ -1662,19 +1872,97 @@ function useScrollWheel(props, ref) {
1662
1872
  });
1663
1873
  }
1664
1874
  }, [onScroll]);
1665
- useEffect(() => {
1666
- let elem = ref.current;
1875
+ useEvent(ref, 'wheel', isDisabled ? null : onScrollHandler);
1876
+ }
1667
1877
 
1668
- if (isDisabled) {
1669
- return;
1878
+ exports.useScrollWheel = useScrollWheel;
1879
+ const $c770c63e4e3d986910ca483d5a$var$DEFAULT_THRESHOLD = 500;
1880
+ /**
1881
+ * Handles long press interactions across mouse and touch devices. Supports a customizable time threshold,
1882
+ * accessibility description, and normalizes behavior across browsers and devices.
1883
+ */
1884
+
1885
+ function useLongPress(props) {
1886
+ let {
1887
+ isDisabled,
1888
+ onLongPressStart,
1889
+ onLongPressEnd,
1890
+ onLongPress,
1891
+ threshold = $c770c63e4e3d986910ca483d5a$var$DEFAULT_THRESHOLD,
1892
+ accessibilityDescription
1893
+ } = props;
1894
+ const timeRef = useRef(null);
1895
+ let {
1896
+ addGlobalListener,
1897
+ removeGlobalListener
1898
+ } = useGlobalListeners();
1899
+ let {
1900
+ pressProps
1901
+ } = usePress({
1902
+ isDisabled,
1903
+
1904
+ onPressStart(e) {
1905
+ if (e.pointerType === 'mouse' || e.pointerType === 'touch') {
1906
+ if (onLongPressStart) {
1907
+ onLongPressStart(_babelRuntimeHelpersExtends({}, e, {
1908
+ type: 'longpressstart'
1909
+ }));
1910
+ }
1911
+
1912
+ timeRef.current = setTimeout(() => {
1913
+ // Prevent other usePress handlers from also handling this event.
1914
+ e.target.dispatchEvent(new PointerEvent('pointercancel', {
1915
+ bubbles: true
1916
+ }));
1917
+
1918
+ if (onLongPress) {
1919
+ onLongPress(_babelRuntimeHelpersExtends({}, e, {
1920
+ type: 'longpress'
1921
+ }));
1922
+ }
1923
+
1924
+ timeRef.current = null;
1925
+ }, threshold); // Prevent context menu, which may be opened on long press on touch devices
1926
+
1927
+ if (e.pointerType === 'touch') {
1928
+ let onContextMenu = e => {
1929
+ e.preventDefault();
1930
+ };
1931
+
1932
+ addGlobalListener(e.target, 'contextmenu', onContextMenu, {
1933
+ once: true
1934
+ });
1935
+ addGlobalListener(window, 'pointerup', () => {
1936
+ // If no contextmenu event is fired quickly after pointerup, remove the handler
1937
+ // so future context menu events outside a long press are not prevented.
1938
+ setTimeout(() => {
1939
+ removeGlobalListener(e.target, 'contextmenu', onContextMenu);
1940
+ }, 30);
1941
+ }, {
1942
+ once: true
1943
+ });
1944
+ }
1945
+ }
1946
+ },
1947
+
1948
+ onPressEnd(e) {
1949
+ if (timeRef.current) {
1950
+ clearTimeout(timeRef.current);
1951
+ }
1952
+
1953
+ if (onLongPressEnd && (e.pointerType === 'mouse' || e.pointerType === 'touch')) {
1954
+ onLongPressEnd(_babelRuntimeHelpersExtends({}, e, {
1955
+ type: 'longpressend'
1956
+ }));
1957
+ }
1670
1958
  }
1671
1959
 
1672
- elem.addEventListener('wheel', onScrollHandler);
1673
- return () => {
1674
- elem.removeEventListener('wheel', onScrollHandler);
1675
- };
1676
- }, [onScrollHandler, ref, isDisabled]);
1960
+ });
1961
+ let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : null);
1962
+ return {
1963
+ longPressProps: mergeProps(pressProps, descriptionProps)
1964
+ };
1677
1965
  }
1678
1966
 
1679
- exports.useScrollWheel = useScrollWheel;
1967
+ exports.useLongPress = useLongPress;
1680
1968
  //# sourceMappingURL=main.js.map