@react-aria/interactions
Advanced tools
Comparing version 3.0.0-nightly.948 to 3.0.0-nightly.953
181
dist/main.js
@@ -147,2 +147,11 @@ var _react2 = require("react"); | ||
let propsRef = useRef(null); | ||
propsRef.current = { | ||
onPress, | ||
onPressChange, | ||
onPressStart, | ||
onPressEnd, | ||
onPressUp, | ||
isDisabled | ||
}; | ||
let [isPressed, setPressed] = useState(false); | ||
@@ -155,7 +164,8 @@ let ref = useRef({ | ||
target: null, | ||
isOverTarget: false | ||
isOverTarget: false, | ||
pointerType: null | ||
}); | ||
let { | ||
addGlobalListener, | ||
removeGlobalListener | ||
removeAllGlobalListeners | ||
} = useGlobalListeners(); | ||
@@ -166,2 +176,8 @@ let pressProps = useMemo(() => { | ||
let triggerPressStart = (originalEvent, pointerType) => { | ||
let { | ||
onPressStart, | ||
onPressChange, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -194,2 +210,9 @@ return; | ||
let { | ||
onPressEnd, | ||
onPressChange, | ||
onPress, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -231,2 +254,7 @@ return; | ||
let triggerPressUp = (originalEvent, pointerType) => { | ||
let { | ||
onPressUp, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -248,2 +276,17 @@ return; | ||
let cancel = e => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(); | ||
} | ||
}; | ||
let pressProps = { | ||
@@ -308,3 +351,3 @@ onKeyDown(e) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), 'keyboard', e.target === state.target); | ||
removeGlobalListener(document, 'keyup', onKeyUp, false); // If the target is a link, trigger the click method to open the URL, | ||
removeAllGlobalListeners(); // If the target is a link, trigger the click method to open the URL, | ||
// but defer triggering pressEnd until onClick event handler. | ||
@@ -327,3 +370,8 @@ | ||
e.preventDefault(); | ||
if ($ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} // iOS safari fires pointer events from VoiceOver (but only when outside an iframe...) | ||
state.pointerType = $ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(e.nativeEvent) ? 'virtual' : e.pointerType; | ||
e.stopPropagation(); | ||
@@ -342,3 +390,3 @@ | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(); | ||
triggerPressStart(e, e.pointerType); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(document, 'pointermove', onPointerMove, false); | ||
@@ -355,12 +403,10 @@ addGlobalListener(document, 'pointerup', onPointerUp, false); | ||
// focus event will be fired. | ||
e.preventDefault(); | ||
if ($ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
} | ||
}; | ||
let unbindEvents = () => { | ||
removeGlobalListener(document, 'pointermove', onPointerMove, false); | ||
removeGlobalListener(document, 'pointerup', onPointerUp, false); | ||
removeGlobalListener(document, 'pointercancel', onPointerCancel, false); | ||
}; | ||
pressProps.onPointerUp = e => { | ||
@@ -371,3 +417,3 @@ // Only handle left clicks | ||
if (e.button === 0 && $ed8d760564e19d8c7d03a6a4$var$isOverTarget(e, e.currentTarget)) { | ||
triggerPressUp(e, e.pointerType); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -387,7 +433,7 @@ }; // Safari on iOS < 13.2 does not implement pointerenter/pointerleave events correctly. | ||
state.isOverTarget = true; | ||
triggerPressStart($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), e.pointerType); | ||
triggerPressStart($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), e.pointerType, false); | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -399,5 +445,5 @@ }; | ||
if ($ed8d760564e19d8c7d03a6a4$var$isOverTarget(e, state.target)) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), e.pointerType); | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), e.pointerType, false); | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -408,3 +454,4 @@ | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(); | ||
@@ -415,13 +462,8 @@ } | ||
let onPointerCancel = e => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), e.pointerType, false); | ||
} | ||
cancel(e); | ||
}; | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(); | ||
} | ||
pressProps.onDragStart = e => { | ||
// Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do. | ||
cancel(e); | ||
}; | ||
@@ -437,3 +479,6 @@ } else { | ||
e.preventDefault(); | ||
if ($ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
@@ -448,2 +493,3 @@ | ||
state.target = e.currentTarget; | ||
state.pointerType = $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'; | ||
@@ -454,3 +500,3 @@ if (!isDisabled && !preventFocusOnPress) { | ||
triggerPressStart(e, $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(document, 'mouseup', onMouseUp, false); | ||
@@ -464,3 +510,3 @@ }; | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
@@ -474,3 +520,3 @@ }; | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'mouse', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -481,3 +527,3 @@ }; | ||
if (!state.ignoreEmulatedMouseEvents && e.button === 0) { | ||
triggerPressUp(e, $eda9c464f45e6c61a293990c493$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -493,3 +539,3 @@ }; | ||
state.isPressed = false; | ||
removeGlobalListener(document, 'mouseup', onMouseUp, false); | ||
removeAllGlobalListeners(); | ||
@@ -501,8 +547,6 @@ if (state.ignoreEmulatedMouseEvents) { | ||
let pointerType = $eda9c464f45e6c61a293990c493$export$isVirtualClick(e) ? 'virtual' : 'mouse'; | ||
if ($ed8d760564e19d8c7d03a6a4$var$isOverTarget(e, state.target)) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), pointerType); | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), pointerType, false); | ||
triggerPressEnd($ed8d760564e19d8c7d03a6a4$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -525,3 +569,4 @@ | ||
state.isPressed = true; | ||
state.target = e.currentTarget; // Due to browser inconsistencies, especially on mobile browsers, we prevent default | ||
state.target = e.currentTarget; | ||
state.pointerType = 'touch'; // Due to browser inconsistencies, especially on mobile browsers, we prevent default | ||
// on the emulated mouse event and handle focusing the pressable element ourselves. | ||
@@ -534,3 +579,3 @@ | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$disableTextSelection(); | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(window, 'scroll', onScroll, true); | ||
@@ -551,7 +596,7 @@ }; | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -570,6 +615,6 @@ }; | ||
if (touch && $ed8d760564e19d8c7d03a6a4$var$isOverTarget(touch, e.currentTarget)) { | ||
triggerPressUp(e, 'touch'); | ||
triggerPressEnd(e, 'touch'); | ||
triggerPressUp(e, state.pointerType); | ||
triggerPressEnd(e, state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -582,3 +627,3 @@ | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(); | ||
removeGlobalListener(window, 'scroll', onScroll, true); | ||
removeAllGlobalListeners(); | ||
}; | ||
@@ -590,3 +635,3 @@ | ||
if (state.isPressed) { | ||
cancelTouchEvent(e, 'touch'); | ||
cancel(e); | ||
} | ||
@@ -597,3 +642,3 @@ }; | ||
if (state.isPressed && e.target.contains(state.target)) { | ||
cancelTouchEvent({ | ||
cancel({ | ||
currentTarget: state.target, | ||
@@ -603,16 +648,8 @@ shiftKey: false, | ||
metaKey: false | ||
}, 'touch'); | ||
}); | ||
} | ||
}; | ||
let cancelTouchEvent = (e, pointerType) => { | ||
if (state.isOverTarget) { | ||
triggerPressEnd(e, pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.activePointerId = null; | ||
state.isOverTarget = false; | ||
$ce801cc8e3ff24b95c928e0152c7b7f2$export$restoreTextSelection(); | ||
window.removeEventListener('scroll', onScroll, true); | ||
pressProps.onDragStart = e => { | ||
cancel(e); | ||
}; | ||
@@ -622,3 +659,3 @@ } | ||
return pressProps; | ||
}, [isDisabled, onPressStart, onPressChange, onPressEnd, onPress, onPressUp, addGlobalListener, preventFocusOnPress, removeGlobalListener]); // Remove user-select: none in case component unmounts immediately after pressStart | ||
}, [addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners]); // Remove user-select: none in case component unmounts immediately after pressStart | ||
// eslint-disable-next-line arrow-body-style | ||
@@ -700,2 +737,12 @@ | ||
function $ed8d760564e19d8c7d03a6a4$var$shouldPreventDefault(target) { | ||
// We cannot prevent default if the target is inside a draggable element. | ||
return !target.closest('[draggable="true"]'); | ||
} | ||
function $ed8d760564e19d8c7d03a6a4$var$isVirtualPointerEvent(event) { | ||
// If the pointer size is zero, then we assume it's from a screen reader. | ||
return event.width === 0 && event.height === 0; | ||
} | ||
const Pressable = /*#__PURE__*/_react.forwardRef((_ref, ref) => { | ||
@@ -867,3 +914,3 @@ var _ref2; | ||
return; | ||
} // If a focus event occurs without a preceding keyboard or pointer event, switch to keyboard modality. | ||
} // If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality. | ||
// This occurs, for example, when navigating a form with the next/previous buttons on iOS. | ||
@@ -873,4 +920,4 @@ | ||
if (!$b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus) { | ||
$b83372066b2b4e1d9257843b2455c$var$currentModality = 'keyboard'; | ||
$b83372066b2b4e1d9257843b2455c$var$triggerChangeHandlers('keyboard', e); | ||
$b83372066b2b4e1d9257843b2455c$var$currentModality = 'virtual'; | ||
$b83372066b2b4e1d9257843b2455c$var$triggerChangeHandlers('virtual', e); | ||
} | ||
@@ -927,2 +974,10 @@ | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$b83372066b2b4e1d9257843b2455c$var$setupGlobalFocusEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $b83372066b2b4e1d9257843b2455c$var$setupGlobalFocusEvents); | ||
} | ||
} | ||
/** | ||
@@ -929,0 +984,0 @@ * If true, keyboard focus is visible. |
@@ -123,2 +123,11 @@ import _react, { useContext, useEffect, useMemo, useRef, useState } from "react"; | ||
let propsRef = useRef(null); | ||
propsRef.current = { | ||
onPress, | ||
onPressChange, | ||
onPressStart, | ||
onPressEnd, | ||
onPressUp, | ||
isDisabled | ||
}; | ||
let [isPressed, setPressed] = useState(false); | ||
@@ -131,7 +140,8 @@ let ref = useRef({ | ||
target: null, | ||
isOverTarget: false | ||
isOverTarget: false, | ||
pointerType: null | ||
}); | ||
let { | ||
addGlobalListener, | ||
removeGlobalListener | ||
removeAllGlobalListeners | ||
} = useGlobalListeners(); | ||
@@ -142,2 +152,8 @@ let pressProps = useMemo(() => { | ||
let triggerPressStart = (originalEvent, pointerType) => { | ||
let { | ||
onPressStart, | ||
onPressChange, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -170,2 +186,9 @@ return; | ||
let { | ||
onPressEnd, | ||
onPressChange, | ||
onPress, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -207,2 +230,7 @@ return; | ||
let triggerPressUp = (originalEvent, pointerType) => { | ||
let { | ||
onPressUp, | ||
isDisabled | ||
} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -224,2 +252,17 @@ return; | ||
let cancel = e => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
$e17c9db826984f8ab8e5d837bf0b8$export$restoreTextSelection(); | ||
} | ||
}; | ||
let pressProps = { | ||
@@ -284,3 +327,3 @@ onKeyDown(e) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), 'keyboard', e.target === state.target); | ||
removeGlobalListener(document, 'keyup', onKeyUp, false); // If the target is a link, trigger the click method to open the URL, | ||
removeAllGlobalListeners(); // If the target is a link, trigger the click method to open the URL, | ||
// but defer triggering pressEnd until onClick event handler. | ||
@@ -303,3 +346,8 @@ | ||
e.preventDefault(); | ||
if ($ffc54430b1dbeee65879852feaaff07d$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} // iOS safari fires pointer events from VoiceOver (but only when outside an iframe...) | ||
state.pointerType = $ffc54430b1dbeee65879852feaaff07d$var$isVirtualPointerEvent(e.nativeEvent) ? 'virtual' : e.pointerType; | ||
e.stopPropagation(); | ||
@@ -318,3 +366,3 @@ | ||
$e17c9db826984f8ab8e5d837bf0b8$export$disableTextSelection(); | ||
triggerPressStart(e, e.pointerType); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(document, 'pointermove', onPointerMove, false); | ||
@@ -331,12 +379,10 @@ addGlobalListener(document, 'pointerup', onPointerUp, false); | ||
// focus event will be fired. | ||
e.preventDefault(); | ||
if ($ffc54430b1dbeee65879852feaaff07d$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
} | ||
}; | ||
let unbindEvents = () => { | ||
removeGlobalListener(document, 'pointermove', onPointerMove, false); | ||
removeGlobalListener(document, 'pointerup', onPointerUp, false); | ||
removeGlobalListener(document, 'pointercancel', onPointerCancel, false); | ||
}; | ||
pressProps.onPointerUp = e => { | ||
@@ -347,3 +393,3 @@ // Only handle left clicks | ||
if (e.button === 0 && $ffc54430b1dbeee65879852feaaff07d$var$isOverTarget(e, e.currentTarget)) { | ||
triggerPressUp(e, e.pointerType); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -363,7 +409,7 @@ }; // Safari on iOS < 13.2 does not implement pointerenter/pointerleave events correctly. | ||
state.isOverTarget = true; | ||
triggerPressStart($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), e.pointerType); | ||
triggerPressStart($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), e.pointerType, false); | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -375,5 +421,5 @@ }; | ||
if ($ffc54430b1dbeee65879852feaaff07d$var$isOverTarget(e, state.target)) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), e.pointerType); | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), e.pointerType, false); | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -384,3 +430,4 @@ | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
$e17c9db826984f8ab8e5d837bf0b8$export$restoreTextSelection(); | ||
@@ -391,13 +438,8 @@ } | ||
let onPointerCancel = e => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), e.pointerType, false); | ||
} | ||
cancel(e); | ||
}; | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
$e17c9db826984f8ab8e5d837bf0b8$export$restoreTextSelection(); | ||
} | ||
pressProps.onDragStart = e => { | ||
// Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do. | ||
cancel(e); | ||
}; | ||
@@ -413,3 +455,6 @@ } else { | ||
e.preventDefault(); | ||
if ($ffc54430b1dbeee65879852feaaff07d$var$shouldPreventDefault(e.target)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
@@ -424,2 +469,3 @@ | ||
state.target = e.currentTarget; | ||
state.pointerType = $f67ef9f1b8ed09b4b00fd0840cd8b94b$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'; | ||
@@ -430,3 +476,3 @@ if (!isDisabled && !preventFocusOnPress) { | ||
triggerPressStart(e, $f67ef9f1b8ed09b4b00fd0840cd8b94b$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(document, 'mouseup', onMouseUp, false); | ||
@@ -440,3 +486,3 @@ }; | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
@@ -450,3 +496,3 @@ }; | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'mouse', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -457,3 +503,3 @@ }; | ||
if (!state.ignoreEmulatedMouseEvents && e.button === 0) { | ||
triggerPressUp(e, $f67ef9f1b8ed09b4b00fd0840cd8b94b$export$isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -469,3 +515,3 @@ }; | ||
state.isPressed = false; | ||
removeGlobalListener(document, 'mouseup', onMouseUp, false); | ||
removeAllGlobalListeners(); | ||
@@ -477,8 +523,6 @@ if (state.ignoreEmulatedMouseEvents) { | ||
let pointerType = $f67ef9f1b8ed09b4b00fd0840cd8b94b$export$isVirtualClick(e) ? 'virtual' : 'mouse'; | ||
if ($ffc54430b1dbeee65879852feaaff07d$var$isOverTarget(e, state.target)) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), pointerType); | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), pointerType, false); | ||
triggerPressEnd($ffc54430b1dbeee65879852feaaff07d$var$createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -501,3 +545,4 @@ | ||
state.isPressed = true; | ||
state.target = e.currentTarget; // Due to browser inconsistencies, especially on mobile browsers, we prevent default | ||
state.target = e.currentTarget; | ||
state.pointerType = 'touch'; // Due to browser inconsistencies, especially on mobile browsers, we prevent default | ||
// on the emulated mouse event and handle focusing the pressable element ourselves. | ||
@@ -510,3 +555,3 @@ | ||
$e17c9db826984f8ab8e5d837bf0b8$export$disableTextSelection(); | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
addGlobalListener(window, 'scroll', onScroll, true); | ||
@@ -527,7 +572,7 @@ }; | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -546,6 +591,6 @@ }; | ||
if (touch && $ffc54430b1dbeee65879852feaaff07d$var$isOverTarget(touch, e.currentTarget)) { | ||
triggerPressUp(e, 'touch'); | ||
triggerPressEnd(e, 'touch'); | ||
triggerPressUp(e, state.pointerType); | ||
triggerPressEnd(e, state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -558,3 +603,3 @@ | ||
$e17c9db826984f8ab8e5d837bf0b8$export$restoreTextSelection(); | ||
removeGlobalListener(window, 'scroll', onScroll, true); | ||
removeAllGlobalListeners(); | ||
}; | ||
@@ -566,3 +611,3 @@ | ||
if (state.isPressed) { | ||
cancelTouchEvent(e, 'touch'); | ||
cancel(e); | ||
} | ||
@@ -573,3 +618,3 @@ }; | ||
if (state.isPressed && e.target.contains(state.target)) { | ||
cancelTouchEvent({ | ||
cancel({ | ||
currentTarget: state.target, | ||
@@ -579,16 +624,8 @@ shiftKey: false, | ||
metaKey: false | ||
}, 'touch'); | ||
}); | ||
} | ||
}; | ||
let cancelTouchEvent = (e, pointerType) => { | ||
if (state.isOverTarget) { | ||
triggerPressEnd(e, pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.activePointerId = null; | ||
state.isOverTarget = false; | ||
$e17c9db826984f8ab8e5d837bf0b8$export$restoreTextSelection(); | ||
window.removeEventListener('scroll', onScroll, true); | ||
pressProps.onDragStart = e => { | ||
cancel(e); | ||
}; | ||
@@ -598,3 +635,3 @@ } | ||
return pressProps; | ||
}, [isDisabled, onPressStart, onPressChange, onPressEnd, onPress, onPressUp, addGlobalListener, preventFocusOnPress, removeGlobalListener]); // Remove user-select: none in case component unmounts immediately after pressStart | ||
}, [addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners]); // Remove user-select: none in case component unmounts immediately after pressStart | ||
// eslint-disable-next-line arrow-body-style | ||
@@ -674,2 +711,12 @@ | ||
function $ffc54430b1dbeee65879852feaaff07d$var$shouldPreventDefault(target) { | ||
// We cannot prevent default if the target is inside a draggable element. | ||
return !target.closest('[draggable="true"]'); | ||
} | ||
function $ffc54430b1dbeee65879852feaaff07d$var$isVirtualPointerEvent(event) { | ||
// If the pointer size is zero, then we assume it's from a screen reader. | ||
return event.width === 0 && event.height === 0; | ||
} | ||
export const Pressable = /*#__PURE__*/_react.forwardRef((_ref, ref) => { | ||
@@ -833,3 +880,3 @@ var _ref2; | ||
return; | ||
} // If a focus event occurs without a preceding keyboard or pointer event, switch to keyboard modality. | ||
} // If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality. | ||
// This occurs, for example, when navigating a form with the next/previous buttons on iOS. | ||
@@ -839,4 +886,4 @@ | ||
if (!$d01f69bb2ab5f70dfd0005370a2a2cbc$var$hasEventBeforeFocus) { | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$currentModality = 'keyboard'; | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$triggerChangeHandlers('keyboard', e); | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$currentModality = 'virtual'; | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$triggerChangeHandlers('virtual', e); | ||
} | ||
@@ -893,2 +940,10 @@ | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$setupGlobalFocusEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $d01f69bb2ab5f70dfd0005370a2a2cbc$var$setupGlobalFocusEvents); | ||
} | ||
} | ||
/** | ||
@@ -895,0 +950,0 @@ * If true, keyboard focus is visible. |
{ | ||
"name": "@react-aria/interactions", | ||
"version": "3.0.0-nightly.948+df2f596b", | ||
"version": "3.0.0-nightly.953+efbc96af", | ||
"description": "Spectrum UI components in React", | ||
@@ -21,4 +21,4 @@ "license": "Apache-2.0", | ||
"@babel/runtime": "^7.6.2", | ||
"@react-aria/utils": "3.0.0-nightly.948+df2f596b", | ||
"@react-types/shared": "3.0.0-nightly.948+df2f596b" | ||
"@react-aria/utils": "3.0.0-nightly.953+efbc96af", | ||
"@react-types/shared": "3.0.0-nightly.953+efbc96af" | ||
}, | ||
@@ -31,3 +31,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "df2f596bd62ba33c88e76f7093411d6a77b36a7f" | ||
"gitHead": "efbc96af731b0820a50731049fabc17d20536edd" | ||
} |
@@ -92,7 +92,7 @@ /* | ||
// If a focus event occurs without a preceding keyboard or pointer event, switch to keyboard modality. | ||
// If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality. | ||
// This occurs, for example, when navigating a form with the next/previous buttons on iOS. | ||
if (!hasEventBeforeFocus) { | ||
currentModality = 'keyboard'; | ||
triggerChangeHandlers('keyboard', e); | ||
currentModality = 'virtual'; | ||
triggerChangeHandlers('virtual', e); | ||
} | ||
@@ -149,2 +149,10 @@ | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
setupGlobalFocusEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', setupGlobalFocusEvents); | ||
} | ||
} | ||
/** | ||
@@ -151,0 +159,0 @@ * If true, keyboard focus is visible. |
@@ -47,2 +47,3 @@ /* | ||
isOverTarget: boolean, | ||
pointerType: PointerType, | ||
userSelect?: string | ||
@@ -106,2 +107,4 @@ } | ||
} = usePressResponderContext(props); | ||
let propsRef = useRef<PressHookProps>(null); | ||
propsRef.current = {onPress, onPressChange, onPressStart, onPressEnd, onPressUp, isDisabled}; | ||
@@ -115,6 +118,7 @@ let [isPressed, setPressed] = useState(false); | ||
target: null, | ||
isOverTarget: false | ||
isOverTarget: false, | ||
pointerType: null | ||
}); | ||
let {addGlobalListener, removeGlobalListener} = useGlobalListeners(); | ||
let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners(); | ||
@@ -124,2 +128,3 @@ let pressProps = useMemo(() => { | ||
let triggerPressStart = (originalEvent: EventBase, pointerType: PointerType) => { | ||
let {onPressStart, onPressChange, isDisabled} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -148,2 +153,3 @@ return; | ||
let triggerPressEnd = (originalEvent: EventBase, pointerType: PointerType, wasPressed = true) => { | ||
let {onPressEnd, onPressChange, onPress, isDisabled} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -185,2 +191,3 @@ return; | ||
let triggerPressUp = (originalEvent: EventBase, pointerType: PointerType) => { | ||
let {onPressUp, isDisabled} = propsRef.current; | ||
if (isDisabled) { | ||
@@ -202,2 +209,16 @@ return; | ||
let cancel = (e: EventBase) => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
restoreTextSelection(); | ||
} | ||
}; | ||
let pressProps: HTMLAttributes<HTMLElement> = { | ||
@@ -262,3 +283,3 @@ onKeyDown(e) { | ||
triggerPressEnd(createEvent(state.target, e), 'keyboard', e.target === state.target); | ||
removeGlobalListener(document, 'keyup', onKeyUp, false); | ||
removeAllGlobalListeners(); | ||
@@ -282,3 +303,9 @@ // If the target is a link, trigger the click method to open the URL, | ||
// default on pointer down and handle focusing the pressable element ourselves. | ||
e.preventDefault(); | ||
if (shouldPreventDefault(e.target as Element)) { | ||
e.preventDefault(); | ||
} | ||
// iOS safari fires pointer events from VoiceOver (but only when outside an iframe...) | ||
state.pointerType = isVirtualPointerEvent(e.nativeEvent) ? 'virtual' : e.pointerType; | ||
e.stopPropagation(); | ||
@@ -296,3 +323,3 @@ if (!state.isPressed) { | ||
disableTextSelection(); | ||
triggerPressStart(e, e.pointerType); | ||
triggerPressStart(e, state.pointerType); | ||
@@ -310,12 +337,10 @@ addGlobalListener(document, 'pointermove', onPointerMove, false); | ||
// focus event will be fired. | ||
e.preventDefault(); | ||
if (shouldPreventDefault(e.target as Element)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
} | ||
}; | ||
let unbindEvents = () => { | ||
removeGlobalListener(document, 'pointermove', onPointerMove, false); | ||
removeGlobalListener(document, 'pointerup', onPointerUp, false); | ||
removeGlobalListener(document, 'pointercancel', onPointerCancel, false); | ||
}; | ||
pressProps.onPointerUp = (e) => { | ||
@@ -326,3 +351,3 @@ // Only handle left clicks | ||
if (e.button === 0 && isOverTarget(e, e.currentTarget)) { | ||
triggerPressUp(e, e.pointerType as PointerType); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -342,7 +367,7 @@ }; | ||
state.isOverTarget = true; | ||
triggerPressStart(createEvent(state.target, e), e.pointerType as PointerType); | ||
triggerPressStart(createEvent(state.target, e), state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd(createEvent(state.target, e), e.pointerType as PointerType, false); | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -354,5 +379,5 @@ }; | ||
if (isOverTarget(e, state.target)) { | ||
triggerPressEnd(createEvent(state.target, e), e.pointerType as PointerType); | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd(createEvent(state.target, e), e.pointerType as PointerType, false); | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -363,3 +388,4 @@ | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
state.pointerType = null; | ||
removeAllGlobalListeners(); | ||
restoreTextSelection(); | ||
@@ -370,13 +396,9 @@ } | ||
let onPointerCancel = (e: PointerEvent) => { | ||
if (state.isPressed) { | ||
if (state.isOverTarget) { | ||
triggerPressEnd(createEvent(state.target, e), e.pointerType as PointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.isOverTarget = false; | ||
state.activePointerId = null; | ||
unbindEvents(); | ||
restoreTextSelection(); | ||
} | ||
cancel(e); | ||
}; | ||
pressProps.onDragStart = (e) => { | ||
// Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do. | ||
cancel(e); | ||
}; | ||
} else { | ||
@@ -391,3 +413,6 @@ pressProps.onMouseDown = (e) => { | ||
// default on mouse down and handle focusing the pressable element ourselves. | ||
e.preventDefault(); | ||
if (shouldPreventDefault(e.target as Element)) { | ||
e.preventDefault(); | ||
} | ||
e.stopPropagation(); | ||
@@ -401,2 +426,3 @@ if (state.ignoreEmulatedMouseEvents) { | ||
state.target = e.currentTarget; | ||
state.pointerType = isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'; | ||
@@ -407,3 +433,3 @@ if (!isDisabled && !preventFocusOnPress) { | ||
triggerPressStart(e, isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
@@ -417,3 +443,3 @@ addGlobalListener(document, 'mouseup', onMouseUp, false); | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'mouse'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
@@ -426,3 +452,3 @@ }; | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'mouse', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -433,3 +459,3 @@ }; | ||
if (!state.ignoreEmulatedMouseEvents && e.button === 0) { | ||
triggerPressUp(e, isVirtualClick(e.nativeEvent) ? 'virtual' : 'mouse'); | ||
triggerPressUp(e, state.pointerType); | ||
} | ||
@@ -445,3 +471,3 @@ }; | ||
state.isPressed = false; | ||
removeGlobalListener(document, 'mouseup', onMouseUp, false); | ||
removeAllGlobalListeners(); | ||
@@ -453,7 +479,6 @@ if (state.ignoreEmulatedMouseEvents) { | ||
let pointerType: PointerType = isVirtualClick(e) ? 'virtual' : 'mouse'; | ||
if (isOverTarget(e, state.target)) { | ||
triggerPressEnd(createEvent(state.target, e), pointerType); | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd(createEvent(state.target, e), pointerType, false); | ||
triggerPressEnd(createEvent(state.target, e), state.pointerType, false); | ||
} | ||
@@ -475,2 +500,3 @@ | ||
state.target = e.currentTarget; | ||
state.pointerType = 'touch'; | ||
@@ -484,3 +510,3 @@ // Due to browser inconsistencies, especially on mobile browsers, we prevent default | ||
disableTextSelection(); | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
@@ -500,7 +526,7 @@ addGlobalListener(window, 'scroll', onScroll, true); | ||
state.isOverTarget = true; | ||
triggerPressStart(e, 'touch'); | ||
triggerPressStart(e, state.pointerType); | ||
} | ||
} else if (state.isOverTarget) { | ||
state.isOverTarget = false; | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -517,6 +543,6 @@ }; | ||
if (touch && isOverTarget(touch, e.currentTarget)) { | ||
triggerPressUp(e, 'touch'); | ||
triggerPressEnd(e, 'touch'); | ||
triggerPressUp(e, state.pointerType); | ||
triggerPressEnd(e, state.pointerType); | ||
} else if (state.isOverTarget) { | ||
triggerPressEnd(e, 'touch', false); | ||
triggerPressEnd(e, state.pointerType, false); | ||
} | ||
@@ -529,3 +555,3 @@ | ||
restoreTextSelection(); | ||
removeGlobalListener(window, 'scroll', onScroll, true); | ||
removeAllGlobalListeners(); | ||
}; | ||
@@ -536,3 +562,3 @@ | ||
if (state.isPressed) { | ||
cancelTouchEvent(e, 'touch'); | ||
cancel(e); | ||
} | ||
@@ -543,3 +569,3 @@ }; | ||
if (state.isPressed && (e.target as HTMLElement).contains(state.target)) { | ||
cancelTouchEvent({ | ||
cancel({ | ||
currentTarget: state.target, | ||
@@ -549,16 +575,8 @@ shiftKey: false, | ||
metaKey: false | ||
}, 'touch'); | ||
}); | ||
} | ||
}; | ||
let cancelTouchEvent = (e: EventBase, pointerType: PointerType) => { | ||
if (state.isOverTarget) { | ||
triggerPressEnd(e, pointerType, false); | ||
} | ||
state.isPressed = false; | ||
state.activePointerId = null; | ||
state.isOverTarget = false; | ||
restoreTextSelection(); | ||
window.removeEventListener('scroll', onScroll, true); | ||
pressProps.onDragStart = (e) => { | ||
cancel(e); | ||
}; | ||
@@ -568,3 +586,3 @@ } | ||
return pressProps; | ||
}, [isDisabled, onPressStart, onPressChange, onPressEnd, onPress, onPressUp, addGlobalListener, preventFocusOnPress, removeGlobalListener]); | ||
}, [addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners]); | ||
@@ -650,1 +668,11 @@ // Remove user-select: none in case component unmounts immediately after pressStart | ||
} | ||
function shouldPreventDefault(target: Element) { | ||
// We cannot prevent default if the target is inside a draggable element. | ||
return !target.closest('[draggable="true"]'); | ||
} | ||
function isVirtualPointerEvent(event: PointerEvent) { | ||
// If the pointer size is zero, then we assume it's from a screen reader. | ||
return event.width === 0 && event.height === 0; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
402044
4544