@react-aria/interactions 3.0.0-nightly.1289 → 3.0.0-nightly.1299
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 +104 -51
- package/dist/main.js.map +1 -1
- package/dist/module.js +104 -51
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/textSelection.ts +57 -34
- package/src/usePress.ts +54 -16
package/dist/main.js
CHANGED
|
@@ -31,51 +31,71 @@ function $parcel$interopDefault(a) {
|
|
|
31
31
|
return a && a.__esModule ? a.default : a;
|
|
32
32
|
}
|
|
33
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
|
|
34
36
|
let $ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'default';
|
|
35
37
|
let $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = '';
|
|
38
|
+
let $ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap = new WeakMap();
|
|
36
39
|
|
|
37
|
-
function $ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
+
}
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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';
|
|
47
53
|
}
|
|
48
|
-
|
|
49
|
-
$ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'disabled';
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
function $ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
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
|
+
}
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
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
|
+
}
|
|
63
76
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// for the whole page in the middle of the animation and cause jank.
|
|
67
|
-
runAfterTransition(() => {
|
|
68
|
-
// Avoid race conditions
|
|
69
|
-
if ($ce801cc8e3ff24b95c928e0152c7b7f2$var$state === 'restoring') {
|
|
70
|
-
if (document.documentElement.style.webkitUserSelect === 'none') {
|
|
71
|
-
document.documentElement.style.webkitUserSelect = $ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect || '';
|
|
77
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$var$savedUserSelect = '';
|
|
78
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$var$state = 'default';
|
|
72
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);
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
if (target.style.userSelect === 'none') {
|
|
89
|
+
target.style.userSelect = targetOldUserSelect;
|
|
76
90
|
}
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
|
|
92
|
+
if (target.getAttribute('style') === '') {
|
|
93
|
+
target.removeAttribute('style');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$var$modifiedElementMap.delete(target);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
}
|
|
80
100
|
|
|
81
101
|
/*
|
|
@@ -146,9 +166,10 @@ function usePress(props) {
|
|
|
146
166
|
isDisabled,
|
|
147
167
|
isPressed: isPressedProp,
|
|
148
168
|
preventFocusOnPress,
|
|
149
|
-
shouldCancelOnPointerExit
|
|
169
|
+
shouldCancelOnPointerExit,
|
|
170
|
+
allowTextSelectionOnPress
|
|
150
171
|
} = _usePressResponderCon,
|
|
151
|
-
domProps = _babelRuntimeHelpersObjectWithoutPropertiesLoose(_usePressResponderCon, ["onPress", "onPressChange", "onPressStart", "onPressEnd", "onPressUp", "isDisabled", "isPressed", "preventFocusOnPress", "shouldCancelOnPointerExit", "ref"]);
|
|
172
|
+
domProps = _babelRuntimeHelpersObjectWithoutPropertiesLoose(_usePressResponderCon, ["onPress", "onPressChange", "onPressStart", "onPressEnd", "onPressUp", "isDisabled", "isPressed", "preventFocusOnPress", "shouldCancelOnPointerExit", "allowTextSelectionOnPress", "ref"]);
|
|
152
173
|
|
|
153
174
|
let propsRef = useRef(null);
|
|
154
175
|
propsRef.current = {
|
|
@@ -293,7 +314,10 @@ function usePress(props) {
|
|
|
293
314
|
state.activePointerId = null;
|
|
294
315
|
state.pointerType = null;
|
|
295
316
|
removeAllGlobalListeners();
|
|
296
|
-
|
|
317
|
+
|
|
318
|
+
if (!allowTextSelectionOnPress) {
|
|
319
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
|
|
320
|
+
}
|
|
297
321
|
}
|
|
298
322
|
};
|
|
299
323
|
|
|
@@ -336,7 +360,7 @@ function usePress(props) {
|
|
|
336
360
|
// trigger as if it were a keyboard click.
|
|
337
361
|
|
|
338
362
|
|
|
339
|
-
if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent)) {
|
|
363
|
+
if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && (state.pointerType === 'virtual' || $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent))) {
|
|
340
364
|
// Ensure the element receives focus (VoiceOver on iOS does not do this)
|
|
341
365
|
if (!isDisabled && !preventFocusOnPress) {
|
|
342
366
|
focusWithoutScrolling(e.currentTarget);
|
|
@@ -375,17 +399,24 @@ function usePress(props) {
|
|
|
375
399
|
// Only handle left clicks, and ignore events that bubbled through portals.
|
|
376
400
|
if (e.button !== 0 || !e.currentTarget.contains(e.target)) {
|
|
377
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';
|
|
410
|
+
return;
|
|
378
411
|
} // Due to browser inconsistencies, especially on mobile browsers, we prevent
|
|
379
412
|
// default on pointer down and handle focusing the pressable element ourselves.
|
|
380
413
|
|
|
381
414
|
|
|
382
415
|
if ($ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(e.target)) {
|
|
383
416
|
e.preventDefault();
|
|
384
|
-
}
|
|
385
|
-
// https://bugs.webkit.org/show_bug.cgi?id=222627
|
|
386
|
-
|
|
417
|
+
}
|
|
387
418
|
|
|
388
|
-
state.pointerType =
|
|
419
|
+
state.pointerType = e.pointerType;
|
|
389
420
|
e.stopPropagation();
|
|
390
421
|
|
|
391
422
|
if (!state.isPressed) {
|
|
@@ -398,7 +429,10 @@ function usePress(props) {
|
|
|
398
429
|
focusWithoutScrolling(e.currentTarget);
|
|
399
430
|
}
|
|
400
431
|
|
|
401
|
-
|
|
432
|
+
if (!allowTextSelectionOnPress) {
|
|
433
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(state.target);
|
|
434
|
+
}
|
|
435
|
+
|
|
402
436
|
triggerPressStart(e, state.pointerType);
|
|
403
437
|
addGlobalListener(document, 'pointermove', onPointerMove, false);
|
|
404
438
|
addGlobalListener(document, 'pointerup', onPointerUp, false);
|
|
@@ -424,7 +458,8 @@ function usePress(props) {
|
|
|
424
458
|
};
|
|
425
459
|
|
|
426
460
|
pressProps.onPointerUp = e => {
|
|
427
|
-
|
|
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') {
|
|
428
463
|
return;
|
|
429
464
|
} // Only handle left clicks
|
|
430
465
|
// Safari on iOS sometimes fires pointerup events, even
|
|
@@ -432,7 +467,7 @@ function usePress(props) {
|
|
|
432
467
|
|
|
433
468
|
|
|
434
469
|
if (e.button === 0 && $ed8d760564e19d8c7d03a6a4$var$isOverTarget(e, e.currentTarget)) {
|
|
435
|
-
triggerPressUp(e, state.pointerType ||
|
|
470
|
+
triggerPressUp(e, state.pointerType || e.pointerType);
|
|
436
471
|
}
|
|
437
472
|
}; // Safari on iOS < 13.2 does not implement pointerenter/pointerleave events correctly.
|
|
438
473
|
// Use pointer move events instead to implement our own hit testing.
|
|
@@ -472,7 +507,10 @@ function usePress(props) {
|
|
|
472
507
|
state.activePointerId = null;
|
|
473
508
|
state.pointerType = null;
|
|
474
509
|
removeAllGlobalListeners();
|
|
475
|
-
|
|
510
|
+
|
|
511
|
+
if (!allowTextSelectionOnPress) {
|
|
512
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
|
|
513
|
+
}
|
|
476
514
|
}
|
|
477
515
|
};
|
|
478
516
|
|
|
@@ -607,7 +645,10 @@ function usePress(props) {
|
|
|
607
645
|
focusWithoutScrolling(e.currentTarget);
|
|
608
646
|
}
|
|
609
647
|
|
|
610
|
-
|
|
648
|
+
if (!allowTextSelectionOnPress) {
|
|
649
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(state.target);
|
|
650
|
+
}
|
|
651
|
+
|
|
611
652
|
triggerPressStart(e, state.pointerType);
|
|
612
653
|
addGlobalListener(window, 'scroll', onScroll, true);
|
|
613
654
|
};
|
|
@@ -664,7 +705,11 @@ function usePress(props) {
|
|
|
664
705
|
state.activePointerId = null;
|
|
665
706
|
state.isOverTarget = false;
|
|
666
707
|
state.ignoreEmulatedMouseEvents = true;
|
|
667
|
-
|
|
708
|
+
|
|
709
|
+
if (!allowTextSelectionOnPress) {
|
|
710
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(state.target);
|
|
711
|
+
}
|
|
712
|
+
|
|
668
713
|
removeAllGlobalListeners();
|
|
669
714
|
};
|
|
670
715
|
|
|
@@ -702,12 +747,16 @@ function usePress(props) {
|
|
|
702
747
|
}
|
|
703
748
|
|
|
704
749
|
return pressProps;
|
|
705
|
-
}, [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
|
|
706
751
|
// eslint-disable-next-line arrow-body-style
|
|
707
752
|
|
|
708
753
|
useEffect(() => {
|
|
709
|
-
return () =>
|
|
710
|
-
|
|
754
|
+
return () => {
|
|
755
|
+
if (!allowTextSelectionOnPress) {
|
|
756
|
+
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(ref.current.target);
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
}, [allowTextSelectionOnPress]);
|
|
711
760
|
return {
|
|
712
761
|
isPressed: isPressedProp || isPressed,
|
|
713
762
|
pressProps: mergeProps(domProps, pressProps)
|
|
@@ -814,7 +863,11 @@ function $ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(target) {
|
|
|
814
863
|
|
|
815
864
|
function $ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(event) {
|
|
816
865
|
// If the pointer size is zero, then we assume it's from a screen reader.
|
|
817
|
-
return event
|
|
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;
|
|
818
871
|
}
|
|
819
872
|
|
|
820
873
|
const Pressable = /*#__PURE__*/_react.forwardRef((_ref, ref) => {
|