@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 +440 -152
- package/dist/main.js.map +1 -1
- package/dist/module.js +429 -149
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +53 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/PressResponder.tsx +4 -2
- package/src/index.ts +1 -0
- package/src/textSelection.ts +59 -28
- package/src/useFocusVisible.ts +33 -16
- package/src/useHover.ts +28 -9
- package/src/useInteractOutside.ts +46 -44
- package/src/useLongPress.ts +128 -0
- package/src/usePress.ts +181 -38
- package/src/useScrollWheel.ts +3 -12
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 (
|
|
36
|
-
$ce801cc8e3ff24b95c928e0152c7b7f2$var$
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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
|
-
|
|
64
|
-
|
|
88
|
+
if (target.style.userSelect === 'none') {
|
|
89
|
+
target.style.userSelect = targetOldUserSelect;
|
|
65
90
|
}
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
}
|
|
363
|
-
// https://bugs.webkit.org/show_bug.cgi?id=222627
|
|
364
|
-
|
|
417
|
+
}
|
|
365
418
|
|
|
366
|
-
state.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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 () =>
|
|
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
|
-
|
|
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
|
|
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;
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
1203
|
+
fn(isFocusVisible());
|
|
1015
1204
|
};
|
|
1016
1205
|
|
|
1017
1206
|
$b83372066b2b4e1d9257843b2455c$var$changeHandlers.add(handler);
|
|
1018
|
-
return () =>
|
|
1019
|
-
|
|
1020
|
-
};
|
|
1021
|
-
}, [isTextInput]);
|
|
1022
|
-
return {
|
|
1023
|
-
isFocusVisible: isFocusVisibleState
|
|
1024
|
-
};
|
|
1207
|
+
return () => $b83372066b2b4e1d9257843b2455c$var$changeHandlers.delete(handler);
|
|
1208
|
+
}, deps);
|
|
1025
1209
|
}
|
|
1026
1210
|
|
|
1027
|
-
exports.
|
|
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
|
|
1337
|
+
let {
|
|
1338
|
+
hoverProps,
|
|
1339
|
+
triggerHoverEnd
|
|
1340
|
+
} = useMemo(() => {
|
|
1152
1341
|
let triggerHoverStart = (event, pointerType) => {
|
|
1153
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1423
|
+
if (!isDisabled && e.currentTarget.contains(e.target)) {
|
|
1424
|
+
triggerHoverEnd(e, 'mouse');
|
|
1425
|
+
}
|
|
1227
1426
|
};
|
|
1228
1427
|
}
|
|
1229
1428
|
|
|
1230
|
-
return
|
|
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 (
|
|
1258
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
1498
|
+
return () => {
|
|
1280
1499
|
document.removeEventListener('pointerdown', onPointerDown, true);
|
|
1281
1500
|
document.removeEventListener('pointerup', onPointerUp, true);
|
|
1282
1501
|
};
|
|
1283
|
-
} else {
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
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
|
-
|
|
1512
|
+
let onTouchEnd = e => {
|
|
1513
|
+
state.ignoreEmulatedMouseEvents = true;
|
|
1305
1514
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
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
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
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
|
-
|
|
1666
|
-
|
|
1875
|
+
useEvent(ref, 'wheel', isDisabled ? null : onScrollHandler);
|
|
1876
|
+
}
|
|
1667
1877
|
|
|
1668
|
-
|
|
1669
|
-
|
|
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
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
}
|
|
1960
|
+
});
|
|
1961
|
+
let descriptionProps = useDescription(onLongPress && !isDisabled ? accessibilityDescription : null);
|
|
1962
|
+
return {
|
|
1963
|
+
longPressProps: mergeProps(pressProps, descriptionProps)
|
|
1964
|
+
};
|
|
1677
1965
|
}
|
|
1678
1966
|
|
|
1679
|
-
exports.
|
|
1967
|
+
exports.useLongPress = useLongPress;
|
|
1680
1968
|
//# sourceMappingURL=main.js.map
|