New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@react-aria/interactions

Package Overview
Dependencies
Maintainers
2
Versions
916
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-aria/interactions - npm Package Compare versions

Comparing version 3.0.0-nightly-326f48154-241216 to 3.0.0-nightly-3dbdc1e8e-250214

6

dist/createEventHandler.main.js

@@ -30,6 +30,10 @@

stopPropagation () {
console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
if (shouldStopPropagation) console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
else shouldStopPropagation = true;
},
continuePropagation () {
shouldStopPropagation = false;
},
isPropagationStopped () {
return shouldStopPropagation;
}

@@ -36,0 +40,0 @@ };

@@ -24,6 +24,10 @@ /*

stopPropagation () {
console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
if (shouldStopPropagation) console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
else shouldStopPropagation = true;
},
continuePropagation () {
shouldStopPropagation = false;
},
isPropagationStopped () {
return shouldStopPropagation;
}

@@ -30,0 +34,0 @@ };

3

dist/useFocus.main.js

@@ -45,3 +45,4 @@ var $625cf83917e112ad$exports = require("./utils.main.js");

const ownerDocument = (0, $hrHul$reactariautils.getOwnerDocument)(e.target);
if (e.target === e.currentTarget && ownerDocument.activeElement === e.target) {
const activeElement = ownerDocument ? (0, $hrHul$reactariautils.getActiveElement)(ownerDocument) : (0, $hrHul$reactariautils.getActiveElement)();
if (e.target === e.currentTarget && activeElement === (0, $hrHul$reactariautils.getEventTarget)(e.nativeEvent)) {
if (onFocusProp) onFocusProp(e);

@@ -48,0 +49,0 @@ if (onFocusChange) onFocusChange(true);

import {useSyntheticBlurEvent as $8a9cb279dc87e130$export$715c682d09d639cc} from "./utils.module.js";
import {useCallback as $hf0lj$useCallback} from "react";
import {getOwnerDocument as $hf0lj$getOwnerDocument} from "@react-aria/utils";
import {getOwnerDocument as $hf0lj$getOwnerDocument, getActiveElement as $hf0lj$getActiveElement, getEventTarget as $hf0lj$getEventTarget} from "@react-aria/utils";

@@ -39,3 +39,4 @@ /*

const ownerDocument = (0, $hf0lj$getOwnerDocument)(e.target);
if (e.target === e.currentTarget && ownerDocument.activeElement === e.target) {
const activeElement = ownerDocument ? (0, $hf0lj$getActiveElement)(ownerDocument) : (0, $hf0lj$getActiveElement)();
if (e.target === e.currentTarget && activeElement === (0, $hf0lj$getEventTarget)(e.nativeEvent)) {
if (onFocusProp) onFocusProp(e);

@@ -42,0 +43,0 @@ if (onFocusChange) onFocusChange(true);

@@ -0,1 +1,2 @@

var $625cf83917e112ad$exports = require("./utils.main.js");
var $cR3F8$reactariautils = require("@react-aria/utils");

@@ -34,2 +35,3 @@ var $cR3F8$react = require("react");

let $e77252a287ef94ab$var$currentModality = null;

@@ -78,3 +80,3 @@ let $e77252a287ef94ab$var$changeHandlers = new Set();

// cause keyboard focus rings to appear.
if (e.target === window || e.target === document) return;
if (e.target === window || e.target === document || (0, $625cf83917e112ad$exports.ignoreFocusEvent)) return;
// If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality.

@@ -90,2 +92,3 @@ // This occurs, for example, when navigating a form with the next/previous buttons on iOS.

function $e77252a287ef94ab$var$handleWindowBlur() {
if (0, $625cf83917e112ad$exports.ignoreFocusEvent) return;
// When the window is blurred, reset state. This is necessary when tabbing out of the window,

@@ -213,3 +216,3 @@ // for example, since a subsequent focus event won't be fired.

*/ function $e77252a287ef94ab$var$isKeyboardFocusEvent(isTextInput, modality, e) {
var _e_target;
let document1 = (0, $cR3F8$reactariautils.getOwnerDocument)(e === null || e === void 0 ? void 0 : e.target);
const IHTMLInputElement = typeof window !== 'undefined' ? (0, $cR3F8$reactariautils.getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).HTMLInputElement : HTMLInputElement;

@@ -219,3 +222,5 @@ const IHTMLTextAreaElement = typeof window !== 'undefined' ? (0, $cR3F8$reactariautils.getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).HTMLTextAreaElement : HTMLTextAreaElement;

const IKeyboardEvent = typeof window !== 'undefined' ? (0, $cR3F8$reactariautils.getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).KeyboardEvent : KeyboardEvent;
isTextInput = isTextInput || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLInputElement && !$e77252a287ef94ab$var$nonTextInputTypes.has(e === null || e === void 0 ? void 0 : (_e_target = e.target) === null || _e_target === void 0 ? void 0 : _e_target.type) || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLTextAreaElement || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLElement && (e === null || e === void 0 ? void 0 : e.target.isContentEditable);
// For keyboard events that occur on a non-input element that will move focus into input element (aka ArrowLeft going from Datepicker button to the main input group)
// we need to rely on the user passing isTextInput into here. This way we can skip toggling focus visiblity for said input element
isTextInput = isTextInput || document1.activeElement instanceof IHTMLInputElement && !$e77252a287ef94ab$var$nonTextInputTypes.has(document1.activeElement.type) || document1.activeElement instanceof IHTMLTextAreaElement || document1.activeElement instanceof IHTMLElement && document1.activeElement.isContentEditable;
return !(isTextInput && modality === 'keyboard' && e instanceof IKeyboardEvent && !$e77252a287ef94ab$var$FOCUS_VISIBLE_INPUT_KEYS[e.key]);

@@ -241,2 +246,3 @@ }

let handler = (modality, e)=>{
// We want to early return for any keyboard events that occur inside text inputs EXCEPT for Tab and Escape
if (!$e77252a287ef94ab$var$isKeyboardFocusEvent(!!(opts === null || opts === void 0 ? void 0 : opts.isTextInput), modality, e)) return;

@@ -243,0 +249,0 @@ fn($e77252a287ef94ab$export$b9b3dfddab17db27());

@@ -0,1 +1,2 @@

import {ignoreFocusEvent as $8a9cb279dc87e130$export$fda7da73ab5d4c48} from "./utils.module.js";
import {isMac as $28AnR$isMac, isVirtualClick as $28AnR$isVirtualClick, getOwnerWindow as $28AnR$getOwnerWindow, getOwnerDocument as $28AnR$getOwnerDocument} from "@react-aria/utils";

@@ -22,2 +23,3 @@ import {useState as $28AnR$useState, useEffect as $28AnR$useEffect} from "react";

let $507fabe10e71c6fb$var$currentModality = null;

@@ -66,3 +68,3 @@ let $507fabe10e71c6fb$var$changeHandlers = new Set();

// cause keyboard focus rings to appear.
if (e.target === window || e.target === document) return;
if (e.target === window || e.target === document || (0, $8a9cb279dc87e130$export$fda7da73ab5d4c48)) return;
// If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality.

@@ -78,2 +80,3 @@ // This occurs, for example, when navigating a form with the next/previous buttons on iOS.

function $507fabe10e71c6fb$var$handleWindowBlur() {
if (0, $8a9cb279dc87e130$export$fda7da73ab5d4c48) return;
// When the window is blurred, reset state. This is necessary when tabbing out of the window,

@@ -201,3 +204,3 @@ // for example, since a subsequent focus event won't be fired.

*/ function $507fabe10e71c6fb$var$isKeyboardFocusEvent(isTextInput, modality, e) {
var _e_target;
let document1 = (0, $28AnR$getOwnerDocument)(e === null || e === void 0 ? void 0 : e.target);
const IHTMLInputElement = typeof window !== 'undefined' ? (0, $28AnR$getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).HTMLInputElement : HTMLInputElement;

@@ -207,3 +210,5 @@ const IHTMLTextAreaElement = typeof window !== 'undefined' ? (0, $28AnR$getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).HTMLTextAreaElement : HTMLTextAreaElement;

const IKeyboardEvent = typeof window !== 'undefined' ? (0, $28AnR$getOwnerWindow)(e === null || e === void 0 ? void 0 : e.target).KeyboardEvent : KeyboardEvent;
isTextInput = isTextInput || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLInputElement && !$507fabe10e71c6fb$var$nonTextInputTypes.has(e === null || e === void 0 ? void 0 : (_e_target = e.target) === null || _e_target === void 0 ? void 0 : _e_target.type) || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLTextAreaElement || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLElement && (e === null || e === void 0 ? void 0 : e.target.isContentEditable);
// For keyboard events that occur on a non-input element that will move focus into input element (aka ArrowLeft going from Datepicker button to the main input group)
// we need to rely on the user passing isTextInput into here. This way we can skip toggling focus visiblity for said input element
isTextInput = isTextInput || document1.activeElement instanceof IHTMLInputElement && !$507fabe10e71c6fb$var$nonTextInputTypes.has(document1.activeElement.type) || document1.activeElement instanceof IHTMLTextAreaElement || document1.activeElement instanceof IHTMLElement && document1.activeElement.isContentEditable;
return !(isTextInput && modality === 'keyboard' && e instanceof IKeyboardEvent && !$507fabe10e71c6fb$var$FOCUS_VISIBLE_INPUT_KEYS[e.key]);

@@ -229,2 +234,3 @@ }

let handler = (modality, e)=>{
// We want to early return for any keyboard events that occur inside text inputs EXCEPT for Tab and Escape
if (!$507fabe10e71c6fb$var$isKeyboardFocusEvent(!!(opts === null || opts === void 0 ? void 0 : opts.isTextInput), modality, e)) return;

@@ -231,0 +237,0 @@ fn($507fabe10e71c6fb$export$b9b3dfddab17db27());

var $625cf83917e112ad$exports = require("./utils.main.js");
var $kDAhS$react = require("react");
var $kDAhS$reactariautils = require("@react-aria/utils");

@@ -26,2 +27,3 @@

function $d16842bbd0359d1b$export$420e68273165f4ec(props) {

@@ -50,3 +52,5 @@ let { isDisabled: isDisabled, onBlurWithin: onBlurWithin, onFocusWithin: onFocusWithin, onFocusWithinChange: onFocusWithinChange } = props;

// focus handler already moved focus somewhere else.
if (!state.current.isFocusWithin && document.activeElement === e.target) {
const ownerDocument = (0, $kDAhS$reactariautils.getOwnerDocument)(e.target);
const activeElement = (0, $kDAhS$reactariautils.getActiveElement)(ownerDocument);
if (!state.current.isFocusWithin && activeElement === (0, $kDAhS$reactariautils.getEventTarget)(e.nativeEvent)) {
if (onFocusWithin) onFocusWithin(e);

@@ -64,3 +68,3 @@ if (onFocusWithinChange) onFocusWithinChange(true);

focusWithinProps: {
// These should not have been null, that would conflict in mergeProps
// These cannot be null, that would conflict in mergeProps
onFocus: undefined,

@@ -67,0 +71,0 @@ onBlur: undefined

import {useSyntheticBlurEvent as $8a9cb279dc87e130$export$715c682d09d639cc} from "./utils.module.js";
import {useRef as $3b9Q0$useRef, useCallback as $3b9Q0$useCallback} from "react";
import {getOwnerDocument as $3b9Q0$getOwnerDocument, getActiveElement as $3b9Q0$getActiveElement, getEventTarget as $3b9Q0$getEventTarget} from "@react-aria/utils";

@@ -20,2 +21,3 @@ /*

function $9ab94262bd0047c7$export$420e68273165f4ec(props) {

@@ -44,3 +46,5 @@ let { isDisabled: isDisabled, onBlurWithin: onBlurWithin, onFocusWithin: onFocusWithin, onFocusWithinChange: onFocusWithinChange } = props;

// focus handler already moved focus somewhere else.
if (!state.current.isFocusWithin && document.activeElement === e.target) {
const ownerDocument = (0, $3b9Q0$getOwnerDocument)(e.target);
const activeElement = (0, $3b9Q0$getActiveElement)(ownerDocument);
if (!state.current.isFocusWithin && activeElement === (0, $3b9Q0$getEventTarget)(e.nativeEvent)) {
if (onFocusWithin) onFocusWithin(e);

@@ -58,3 +62,3 @@ if (onFocusWithinChange) onFocusWithinChange(true);

focusWithinProps: {
// These should not have been null, that would conflict in mergeProps
// These cannot be null, that would conflict in mergeProps
onFocus: undefined,

@@ -61,0 +65,0 @@ onBlur: undefined

@@ -97,3 +97,8 @@ var $9Icr4$reactariautils = require("@react-aria/utils");

}
return ref.current && !ref.current.contains(event.target);
if (!ref.current) return false;
// When the event source is inside a Shadow DOM, event.target is just the shadow root.
// Using event.composedPath instead means we can get the actual element inside the shadow root.
// This only works if the shadow root is open, there is no way to detect if it is closed.
// If the event composed path contains the ref, interaction is inside.
return !event.composedPath().includes(ref.current);
}

@@ -100,0 +105,0 @@

@@ -91,3 +91,8 @@ import {useEffectEvent as $ispOf$useEffectEvent, getOwnerDocument as $ispOf$getOwnerDocument} from "@react-aria/utils";

}
return ref.current && !ref.current.contains(event.target);
if (!ref.current) return false;
// When the event source is inside a Shadow DOM, event.target is just the shadow root.
// Using event.composedPath instead means we can get the actual element inside the shadow root.
// This only works if the shadow root is open, there is no way to detect if it is closed.
// If the event composed path contains the ref, interaction is inside.
return !event.composedPath().includes(ref.current);
}

@@ -94,0 +99,0 @@

@@ -43,2 +43,4 @@ var $0294ea432cd92340$exports = require("./usePress.main.js");

}));
// Ensure target is focused. On touch devices, browsers typically focus on pointer up.
if ((0, $5sxTM$reactariautils.getOwnerDocument)(e.target).activeElement !== e.target) (0, $5sxTM$reactariautils.focusWithoutScrolling)(e.target);
if (onLongPress) onLongPress({

@@ -45,0 +47,0 @@ ...e,

import {usePress as $f6c31cce2adf654f$export$45712eceda6fad21} from "./usePress.module.js";
import {useGlobalListeners as $4k2kv$useGlobalListeners, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
import {useGlobalListeners as $4k2kv$useGlobalListeners, getOwnerDocument as $4k2kv$getOwnerDocument, focusWithoutScrolling as $4k2kv$focusWithoutScrolling, useDescription as $4k2kv$useDescription, mergeProps as $4k2kv$mergeProps} from "@react-aria/utils";
import {useRef as $4k2kv$useRef} from "react";

@@ -37,2 +37,4 @@

}));
// Ensure target is focused. On touch devices, browsers typically focus on pointer up.
if ((0, $4k2kv$getOwnerDocument)(e.target).activeElement !== e.target) (0, $4k2kv$focusWithoutScrolling)(e.target);
if (onLongPress) onLongPress({

@@ -39,0 +41,0 @@ ...e,

var $f7e14e656343df57$exports = require("./textSelection.main.js");
var $01d3f539e91688c8$exports = require("./context.main.js");
var $625cf83917e112ad$exports = require("./utils.main.js");
var $bBqCQ$swchelperscjs_class_private_field_getcjs = require("@swc/helpers/cjs/_class_private_field_get.cjs");

@@ -7,2 +8,3 @@ var $bBqCQ$swchelperscjs_class_private_field_initcjs = require("@swc/helpers/cjs/_class_private_field_init.cjs");

var $bBqCQ$reactariautils = require("@react-aria/utils");
var $bBqCQ$reactdom = require("react-dom");
var $bBqCQ$react = require("react");

@@ -37,2 +39,4 @@

function $0294ea432cd92340$var$usePressResponderContext(props) {

@@ -100,3 +104,2 @@ // Consume context from <PressResponder> and merge with props.

ignoreEmulatedMouseEvents: false,
ignoreClickAfterPress: false,
didFirePressStart: false,

@@ -107,3 +110,4 @@ isTriggeringEvent: false,

isOverTarget: false,
pointerType: null
pointerType: null,
disposables: []
});

@@ -130,3 +134,2 @@ let { addGlobalListener: addGlobalListener, removeAllGlobalListeners: removeAllGlobalListeners } = (0, $bBqCQ$reactariautils.useGlobalListeners)();

if (!state.didFirePressStart) return false;
state.ignoreClickAfterPress = true;
state.didFirePressStart = false;

@@ -165,3 +168,3 @@ state.isTriggeringEvent = true;

if (state.isPressed && state.target) {
if (state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
if (state.didFirePressStart && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
state.isPressed = false;

@@ -173,2 +176,4 @@ state.isOverTarget = false;

if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)(state.target);
for (let dispose of state.disposables)dispose();
state.disposables = [];
}

@@ -183,5 +188,5 @@ });

onKeyDown (e) {
if ($0294ea432cd92340$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && e.currentTarget.contains(e.target)) {
if ($0294ea432cd92340$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && (0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) {
var _state_metaKeyEvents;
if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard((0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent), e.key)) e.preventDefault();
// If the event is repeating, it may have started on a different element

@@ -194,2 +199,3 @@ // after which focus moved to the current element. Ignore these events and

state.isPressed = true;
state.pointerType = 'keyboard';
shouldStopPropagation = triggerPressStart(e, 'keyboard');

@@ -201,3 +207,3 @@ // Focus may move before the key up event, so register the event on the document

let pressUp = (e)=>{
if ($0294ea432cd92340$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && originalTarget.contains(e.target) && state.target) triggerPressUp($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard');
if ($0294ea432cd92340$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && (0, $bBqCQ$reactariautils.nodeContains)(originalTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e)) && state.target) triggerPressUp($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard');
};

@@ -218,3 +224,3 @@ addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'keyup', (0, $bBqCQ$reactariautils.chain)(pressUp, onKeyUp), true);

onClick (e) {
if (e && !e.currentTarget.contains(e.target)) return;
if (e && !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (e && e.button === 0 && !state.isTriggeringEvent && !(0, $bBqCQ$reactariautils.openLink).isOpening) {

@@ -225,5 +231,3 @@ let shouldStopPropagation = true;

// trigger as if it were a keyboard click.
if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent))) {
// Ensure the element receives focus (VoiceOver on iOS does not do this)
if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
if (!state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent))) {
let stopPressStart = triggerPressStart(e, 'virtual');

@@ -233,5 +237,9 @@ let stopPressUp = triggerPressUp(e, 'virtual');

shouldStopPropagation = stopPressStart && stopPressUp && stopPressEnd;
} else if (state.isPressed && state.pointerType !== 'keyboard') {
let pointerType = state.pointerType || e.nativeEvent.pointerType || 'virtual';
shouldStopPropagation = triggerPressEnd($0294ea432cd92340$var$createEvent(e.currentTarget, e), pointerType, true);
state.isOverTarget = false;
cancel(e);
}
state.ignoreEmulatedMouseEvents = false;
state.ignoreClickAfterPress = false;
if (shouldStopPropagation) e.stopPropagation();

@@ -245,5 +253,5 @@ }

var _state_metaKeyEvents1;
if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
let target = e.target;
triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard', state.target.contains(target));
if ($0294ea432cd92340$var$shouldPreventDefaultKeyboard((0, $bBqCQ$reactariautils.getEventTarget)(e), e.key)) e.preventDefault();
let target = (0, $bBqCQ$reactariautils.getEventTarget)(e);
triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), 'keyboard', (0, $bBqCQ$reactariautils.nodeContains)(state.target, (0, $bBqCQ$reactariautils.getEventTarget)(e)));
removeAllGlobalListeners();

@@ -253,3 +261,3 @@ // If a link was triggered with a key other than Enter, open the URL ourselves.

// only applies when using the Enter key.
if (e.key !== 'Enter' && $0294ea432cd92340$var$isHTMLAnchorLink(state.target) && state.target.contains(target) && !e[$0294ea432cd92340$var$LINK_CLICKED]) {
if (e.key !== 'Enter' && $0294ea432cd92340$var$isHTMLAnchorLink(state.target) && (0, $bBqCQ$reactariautils.nodeContains)(state.target, target) && !e[$0294ea432cd92340$var$LINK_CLICKED]) {
// Store a hidden property on the event so we only trigger link click once,

@@ -275,3 +283,3 @@ // even if there are multiple usePress instances attached to the element.

// Only handle left clicks, and ignore events that bubbled through portals.
if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
if (e.button !== 0 || !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
// iOS safari fires pointer events from VoiceOver with incorrect coordinates/target.

@@ -285,5 +293,2 @@ // Ignore and let the onClick handler take care of it instead.

}
// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on pointer down and handle focusing the pressable element ourselves.
if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
state.pointerType = e.pointerType;

@@ -296,3 +301,2 @@ let shouldStopPropagation = true;

state.target = e.currentTarget;
if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.disableTextSelection)(state.target);

@@ -302,3 +306,3 @@ shouldStopPropagation = triggerPressStart(e, state.pointerType);

// This enables onPointerLeave and onPointerEnter to fire.
let target = e.target;
let target = (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent);
if ('releasePointerCapture' in target) target.releasePointerCapture(e.pointerId);

@@ -311,8 +315,8 @@ addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'pointerup', onPointerUp, false);

pressProps.onMouseDown = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (e.button === 0) {
// Chrome and Firefox on touch Windows devices require mouse down events
// to be canceled in addition to pointer events, or an extra asynchronous
// focus event will be fired.
if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
if (preventFocusOnPress) {
let dispose = (0, $625cf83917e112ad$exports.preventFocus)(e.target);
if (dispose) state.disposables.push(dispose);
}
e.stopPropagation();

@@ -323,3 +327,3 @@ }

// iOS fires pointerup with zero width and height, so check the pointerType recorded during pointerdown.
if (!e.currentTarget.contains(e.target) || state.pointerType === 'virtual') return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent)) || state.pointerType === 'virtual') return;
// Only handle left clicks

@@ -343,27 +347,32 @@ if (e.button === 0) triggerPressUp(e, state.pointerType || e.pointerType);

if (e.pointerId === state.activePointerId && state.isPressed && e.button === 0 && state.target) {
if (state.target.contains(e.target) && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType);
else if (state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
state.isPressed = false;
if ((0, $bBqCQ$reactariautils.nodeContains)(state.target, (0, $bBqCQ$reactariautils.getEventTarget)(e)) && state.pointerType != null) {
// Wait for onClick to fire onPress. This avoids browser issues when the DOM
// is mutated between onPointerUp and onClick, and is more compatible with third party libraries.
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// However, iOS and Android do not focus or fire onClick after a long press.
// We work around this by triggering a click ourselves after a timeout.
// This timeout is canceled during the click event in case the real one fires first.
// The timeout must be at least 32ms, because Safari on iOS delays the click event on
// non-form elements without certain ARIA roles (for hover emulation).
// https://github.com/WebKit/WebKit/blob/dccfae42bb29bd4bdef052e469f604a9387241c0/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L875-L892
let clicked = false;
let timeout = setTimeout(()=>{
if (state.isPressed && state.target instanceof HTMLElement) {
if (clicked) cancel(e);
else {
(0, $bBqCQ$reactariautils.focusWithoutScrolling)(state.target);
state.target.click();
}
}
}, 40);
// Use a capturing listener to track if a click occurred.
// If stopPropagation is called it may never reach our handler.
addGlobalListener(e.currentTarget, 'click', ()=>clicked = true, true);
state.disposables.push(()=>clearTimeout(timeout));
} else cancel(e);
// Ignore subsequent onPointerLeave event before onClick on touch devices.
state.isOverTarget = false;
state.activePointerId = null;
state.pointerType = null;
removeAllGlobalListeners();
if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)(state.target);
// Prevent subsequent touchend event from triggering onClick on unrelated elements on Android. See below.
// Both 'touch' and 'pen' pointerTypes trigger onTouchEnd, but 'mouse' does not.
if ('ontouchend' in state.target && e.pointerType !== 'mouse') addGlobalListener(state.target, 'touchend', onTouchEnd, {
once: true
});
}
};
// This is a workaround for an Android Chrome/Firefox issue where click events are fired on an incorrect element
// if the original target is removed during onPointerUp (before onClick).
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// Note: this event must be registered directly on the element, not via React props in order to work.
// https://github.com/facebook/react/issues/9809
let onTouchEnd = (e)=>{
// Don't preventDefault if we actually want the default (e.g. submit/link click).
if ($0294ea432cd92340$var$shouldPreventDefaultUp(e.currentTarget)) e.preventDefault();
};
let onPointerCancel = (e)=>{

@@ -373,3 +382,3 @@ cancel(e);

pressProps.onDragStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
// Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do.

@@ -379,8 +388,7 @@ cancel(e);

} else {
// NOTE: this fallback branch is almost entirely used by unit tests.
// All browsers now support pointer events, but JSDOM still does not.
pressProps.onMouseDown = (e)=>{
// Only handle left clicks
if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on mouse down and handle focusing the pressable element ourselves.
if ($0294ea432cd92340$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
if (e.button !== 0 || !(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (state.ignoreEmulatedMouseEvents) {

@@ -394,9 +402,13 @@ e.stopPropagation();

state.pointerType = (0, $bBqCQ$reactariautils.isVirtualClick)(e.nativeEvent) ? 'virtual' : 'mouse';
if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
let shouldStopPropagation = triggerPressStart(e, state.pointerType);
// Flush sync so that focus moved during react re-renders occurs before we yield back to the browser.
let shouldStopPropagation = (0, $bBqCQ$reactdom.flushSync)(()=>triggerPressStart(e, state.pointerType));
if (shouldStopPropagation) e.stopPropagation();
if (preventFocusOnPress) {
let dispose = (0, $625cf83917e112ad$exports.preventFocus)(e.target);
if (dispose) state.disposables.push(dispose);
}
addGlobalListener((0, $bBqCQ$reactariautils.getOwnerDocument)(e.currentTarget), 'mouseup', onMouseUp, false);
};
pressProps.onMouseEnter = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
let shouldStopPropagation = true;

@@ -410,3 +422,3 @@ if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {

pressProps.onMouseLeave = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
let shouldStopPropagation = true;

@@ -421,3 +433,3 @@ if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {

pressProps.onMouseUp = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (!state.ignoreEmulatedMouseEvents && e.button === 0) triggerPressUp(e, state.pointerType || 'mouse');

@@ -428,4 +440,2 @@ };

if (e.button !== 0) return;
state.isPressed = false;
removeAllGlobalListeners();
if (state.ignoreEmulatedMouseEvents) {

@@ -435,8 +445,8 @@ state.ignoreEmulatedMouseEvents = false;

}
if (state.target && $0294ea432cd92340$var$isOverTarget(e, state.target) && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType);
else if (state.target && state.isOverTarget && state.pointerType != null) triggerPressEnd($0294ea432cd92340$var$createEvent(state.target, e), state.pointerType, false);
if (state.target && state.target.contains(e.target) && state.pointerType != null) ;
else cancel(e);
state.isOverTarget = false;
};
pressProps.onTouchStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
let touch = $0294ea432cd92340$var$getTouchFromEvent(e.nativeEvent);

@@ -450,5 +460,2 @@ if (!touch) return;

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.
if (!isDisabled && !preventFocusOnPress) (0, $bBqCQ$reactariautils.focusWithoutScrolling)(e.currentTarget);
if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.disableTextSelection)(state.target);

@@ -460,3 +467,3 @@ let shouldStopPropagation = triggerPressStart($0294ea432cd92340$var$createTouchEvent(state.target, e), state.pointerType);

pressProps.onTouchMove = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (!state.isPressed) {

@@ -481,3 +488,3 @@ e.stopPropagation();

pressProps.onTouchEnd = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
if (!state.isPressed) {

@@ -502,3 +509,3 @@ e.stopPropagation();

pressProps.onTouchCancel = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
e.stopPropagation();

@@ -508,3 +515,3 @@ if (state.isPressed) cancel($0294ea432cd92340$var$createTouchEvent(state.target, e));

let onScroll = (e)=>{
if (state.isPressed && e.target.contains(state.target)) cancel({
if (state.isPressed && (0, $bBqCQ$reactariautils.nodeContains)((0, $bBqCQ$reactariautils.getEventTarget)(e), state.target)) cancel({
currentTarget: state.target,

@@ -518,3 +525,3 @@ shiftKey: false,

pressProps.onDragStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $bBqCQ$reactariautils.nodeContains)(e.currentTarget, (0, $bBqCQ$reactariautils.getEventTarget)(e.nativeEvent))) return;
cancel(e);

@@ -538,6 +545,8 @@ };

(0, $bBqCQ$react.useEffect)(()=>{
let state = ref.current;
return ()=>{
var _ref_current_target;
if (!allowTextSelectionOnPress) // eslint-disable-next-line react-hooks/exhaustive-deps
(0, $f7e14e656343df57$exports.restoreTextSelection)((_ref_current_target = ref.current.target) !== null && _ref_current_target !== void 0 ? _ref_current_target : undefined);
var _state_target;
if (!allowTextSelectionOnPress) (0, $f7e14e656343df57$exports.restoreTextSelection)((_state_target = state.target) !== null && _state_target !== void 0 ? _state_target : undefined);
for (let dispose of state.disposables)dispose();
state.disposables = [];
};

@@ -633,6 +642,2 @@ }, [

}
function $0294ea432cd92340$var$shouldPreventDefaultDown(target) {
// We cannot prevent default if the target is a draggable element.
return !(target instanceof HTMLElement) || !target.hasAttribute('draggable');
}
function $0294ea432cd92340$var$shouldPreventDefaultUp(target) {

@@ -639,0 +644,0 @@ if (target instanceof HTMLInputElement) return false;

import {disableTextSelection as $14c0b72509d70225$export$16a4697467175487, restoreTextSelection as $14c0b72509d70225$export$b0d6fa1ab32e3295} from "./textSelection.module.js";
import {PressResponderContext as $ae1eeba8b9eafd08$export$5165eccb35aaadb5} from "./context.module.js";
import {preventFocus as $8a9cb279dc87e130$export$cabe61c495ee3649} from "./utils.module.js";
import {_ as $7mdmh$_} from "@swc/helpers/_/_class_private_field_get";
import {_ as $7mdmh$_1} from "@swc/helpers/_/_class_private_field_init";
import {_ as $7mdmh$_2} from "@swc/helpers/_/_class_private_field_set";
import {mergeProps as $7mdmh$mergeProps, useSyncRef as $7mdmh$useSyncRef, useGlobalListeners as $7mdmh$useGlobalListeners, useEffectEvent as $7mdmh$useEffectEvent, getOwnerDocument as $7mdmh$getOwnerDocument, chain as $7mdmh$chain, isMac as $7mdmh$isMac, openLink as $7mdmh$openLink, isVirtualClick as $7mdmh$isVirtualClick, focusWithoutScrolling as $7mdmh$focusWithoutScrolling, isVirtualPointerEvent as $7mdmh$isVirtualPointerEvent, getOwnerWindow as $7mdmh$getOwnerWindow} from "@react-aria/utils";
import {mergeProps as $7mdmh$mergeProps, useSyncRef as $7mdmh$useSyncRef, useGlobalListeners as $7mdmh$useGlobalListeners, useEffectEvent as $7mdmh$useEffectEvent, nodeContains as $7mdmh$nodeContains, getEventTarget as $7mdmh$getEventTarget, getOwnerDocument as $7mdmh$getOwnerDocument, chain as $7mdmh$chain, isMac as $7mdmh$isMac, openLink as $7mdmh$openLink, isVirtualClick as $7mdmh$isVirtualClick, isVirtualPointerEvent as $7mdmh$isVirtualPointerEvent, focusWithoutScrolling as $7mdmh$focusWithoutScrolling, getOwnerWindow as $7mdmh$getOwnerWindow} from "@react-aria/utils";
import {flushSync as $7mdmh$flushSync} from "react-dom";
import {useContext as $7mdmh$useContext, useState as $7mdmh$useState, useRef as $7mdmh$useRef, useMemo as $7mdmh$useMemo, useEffect as $7mdmh$useEffect} from "react";

@@ -30,2 +32,4 @@

function $f6c31cce2adf654f$var$usePressResponderContext(props) {

@@ -93,3 +97,2 @@ // Consume context from <PressResponder> and merge with props.

ignoreEmulatedMouseEvents: false,
ignoreClickAfterPress: false,
didFirePressStart: false,

@@ -100,3 +103,4 @@ isTriggeringEvent: false,

isOverTarget: false,
pointerType: null
pointerType: null,
disposables: []
});

@@ -123,3 +127,2 @@ let { addGlobalListener: addGlobalListener, removeAllGlobalListeners: removeAllGlobalListeners } = (0, $7mdmh$useGlobalListeners)();

if (!state.didFirePressStart) return false;
state.ignoreClickAfterPress = true;
state.didFirePressStart = false;

@@ -158,3 +161,3 @@ state.isTriggeringEvent = true;

if (state.isPressed && state.target) {
if (state.isOverTarget && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false);
if (state.didFirePressStart && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false);
state.isPressed = false;

@@ -166,2 +169,4 @@ state.isOverTarget = false;

if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)(state.target);
for (let dispose of state.disposables)dispose();
state.disposables = [];
}

@@ -176,5 +181,5 @@ });

onKeyDown (e) {
if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && e.currentTarget.contains(e.target)) {
if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && (0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) {
var _state_metaKeyEvents;
if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard((0, $7mdmh$getEventTarget)(e.nativeEvent), e.key)) e.preventDefault();
// If the event is repeating, it may have started on a different element

@@ -187,2 +192,3 @@ // after which focus moved to the current element. Ignore these events and

state.isPressed = true;
state.pointerType = 'keyboard';
shouldStopPropagation = triggerPressStart(e, 'keyboard');

@@ -194,3 +200,3 @@ // Focus may move before the key up event, so register the event on the document

let pressUp = (e)=>{
if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && originalTarget.contains(e.target) && state.target) triggerPressUp($f6c31cce2adf654f$var$createEvent(state.target, e), 'keyboard');
if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e, originalTarget) && !e.repeat && (0, $7mdmh$nodeContains)(originalTarget, (0, $7mdmh$getEventTarget)(e)) && state.target) triggerPressUp($f6c31cce2adf654f$var$createEvent(state.target, e), 'keyboard');
};

@@ -211,3 +217,3 @@ addGlobalListener((0, $7mdmh$getOwnerDocument)(e.currentTarget), 'keyup', (0, $7mdmh$chain)(pressUp, onKeyUp), true);

onClick (e) {
if (e && !e.currentTarget.contains(e.target)) return;
if (e && !(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (e && e.button === 0 && !state.isTriggeringEvent && !(0, $7mdmh$openLink).isOpening) {

@@ -218,5 +224,3 @@ let shouldStopPropagation = true;

// trigger as if it were a keyboard click.
if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $7mdmh$isVirtualClick)(e.nativeEvent))) {
// Ensure the element receives focus (VoiceOver on iOS does not do this)
if (!isDisabled && !preventFocusOnPress) (0, $7mdmh$focusWithoutScrolling)(e.currentTarget);
if (!state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || (0, $7mdmh$isVirtualClick)(e.nativeEvent))) {
let stopPressStart = triggerPressStart(e, 'virtual');

@@ -226,5 +230,9 @@ let stopPressUp = triggerPressUp(e, 'virtual');

shouldStopPropagation = stopPressStart && stopPressUp && stopPressEnd;
} else if (state.isPressed && state.pointerType !== 'keyboard') {
let pointerType = state.pointerType || e.nativeEvent.pointerType || 'virtual';
shouldStopPropagation = triggerPressEnd($f6c31cce2adf654f$var$createEvent(e.currentTarget, e), pointerType, true);
state.isOverTarget = false;
cancel(e);
}
state.ignoreEmulatedMouseEvents = false;
state.ignoreClickAfterPress = false;
if (shouldStopPropagation) e.stopPropagation();

@@ -238,5 +246,5 @@ }

var _state_metaKeyEvents1;
if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault();
let target = e.target;
triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), 'keyboard', state.target.contains(target));
if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard((0, $7mdmh$getEventTarget)(e), e.key)) e.preventDefault();
let target = (0, $7mdmh$getEventTarget)(e);
triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), 'keyboard', (0, $7mdmh$nodeContains)(state.target, (0, $7mdmh$getEventTarget)(e)));
removeAllGlobalListeners();

@@ -246,3 +254,3 @@ // If a link was triggered with a key other than Enter, open the URL ourselves.

// only applies when using the Enter key.
if (e.key !== 'Enter' && $f6c31cce2adf654f$var$isHTMLAnchorLink(state.target) && state.target.contains(target) && !e[$f6c31cce2adf654f$var$LINK_CLICKED]) {
if (e.key !== 'Enter' && $f6c31cce2adf654f$var$isHTMLAnchorLink(state.target) && (0, $7mdmh$nodeContains)(state.target, target) && !e[$f6c31cce2adf654f$var$LINK_CLICKED]) {
// Store a hidden property on the event so we only trigger link click once,

@@ -268,3 +276,3 @@ // even if there are multiple usePress instances attached to the element.

// Only handle left clicks, and ignore events that bubbled through portals.
if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
if (e.button !== 0 || !(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
// iOS safari fires pointer events from VoiceOver with incorrect coordinates/target.

@@ -278,5 +286,2 @@ // Ignore and let the onClick handler take care of it instead.

}
// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on pointer down and handle focusing the pressable element ourselves.
if ($f6c31cce2adf654f$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
state.pointerType = e.pointerType;

@@ -289,3 +294,2 @@ let shouldStopPropagation = true;

state.target = e.currentTarget;
if (!isDisabled && !preventFocusOnPress) (0, $7mdmh$focusWithoutScrolling)(e.currentTarget);
if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$16a4697467175487)(state.target);

@@ -295,3 +299,3 @@ shouldStopPropagation = triggerPressStart(e, state.pointerType);

// This enables onPointerLeave and onPointerEnter to fire.
let target = e.target;
let target = (0, $7mdmh$getEventTarget)(e.nativeEvent);
if ('releasePointerCapture' in target) target.releasePointerCapture(e.pointerId);

@@ -304,8 +308,8 @@ addGlobalListener((0, $7mdmh$getOwnerDocument)(e.currentTarget), 'pointerup', onPointerUp, false);

pressProps.onMouseDown = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (e.button === 0) {
// Chrome and Firefox on touch Windows devices require mouse down events
// to be canceled in addition to pointer events, or an extra asynchronous
// focus event will be fired.
if ($f6c31cce2adf654f$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
if (preventFocusOnPress) {
let dispose = (0, $8a9cb279dc87e130$export$cabe61c495ee3649)(e.target);
if (dispose) state.disposables.push(dispose);
}
e.stopPropagation();

@@ -316,3 +320,3 @@ }

// iOS fires pointerup with zero width and height, so check the pointerType recorded during pointerdown.
if (!e.currentTarget.contains(e.target) || state.pointerType === 'virtual') return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent)) || state.pointerType === 'virtual') return;
// Only handle left clicks

@@ -336,27 +340,32 @@ if (e.button === 0) triggerPressUp(e, state.pointerType || e.pointerType);

if (e.pointerId === state.activePointerId && state.isPressed && e.button === 0 && state.target) {
if (state.target.contains(e.target) && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType);
else if (state.isOverTarget && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false);
state.isPressed = false;
if ((0, $7mdmh$nodeContains)(state.target, (0, $7mdmh$getEventTarget)(e)) && state.pointerType != null) {
// Wait for onClick to fire onPress. This avoids browser issues when the DOM
// is mutated between onPointerUp and onClick, and is more compatible with third party libraries.
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// However, iOS and Android do not focus or fire onClick after a long press.
// We work around this by triggering a click ourselves after a timeout.
// This timeout is canceled during the click event in case the real one fires first.
// The timeout must be at least 32ms, because Safari on iOS delays the click event on
// non-form elements without certain ARIA roles (for hover emulation).
// https://github.com/WebKit/WebKit/blob/dccfae42bb29bd4bdef052e469f604a9387241c0/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L875-L892
let clicked = false;
let timeout = setTimeout(()=>{
if (state.isPressed && state.target instanceof HTMLElement) {
if (clicked) cancel(e);
else {
(0, $7mdmh$focusWithoutScrolling)(state.target);
state.target.click();
}
}
}, 40);
// Use a capturing listener to track if a click occurred.
// If stopPropagation is called it may never reach our handler.
addGlobalListener(e.currentTarget, 'click', ()=>clicked = true, true);
state.disposables.push(()=>clearTimeout(timeout));
} else cancel(e);
// Ignore subsequent onPointerLeave event before onClick on touch devices.
state.isOverTarget = false;
state.activePointerId = null;
state.pointerType = null;
removeAllGlobalListeners();
if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)(state.target);
// Prevent subsequent touchend event from triggering onClick on unrelated elements on Android. See below.
// Both 'touch' and 'pen' pointerTypes trigger onTouchEnd, but 'mouse' does not.
if ('ontouchend' in state.target && e.pointerType !== 'mouse') addGlobalListener(state.target, 'touchend', onTouchEnd, {
once: true
});
}
};
// This is a workaround for an Android Chrome/Firefox issue where click events are fired on an incorrect element
// if the original target is removed during onPointerUp (before onClick).
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// Note: this event must be registered directly on the element, not via React props in order to work.
// https://github.com/facebook/react/issues/9809
let onTouchEnd = (e)=>{
// Don't preventDefault if we actually want the default (e.g. submit/link click).
if ($f6c31cce2adf654f$var$shouldPreventDefaultUp(e.currentTarget)) e.preventDefault();
};
let onPointerCancel = (e)=>{

@@ -366,3 +375,3 @@ cancel(e);

pressProps.onDragStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
// Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do.

@@ -372,8 +381,7 @@ cancel(e);

} else {
// NOTE: this fallback branch is almost entirely used by unit tests.
// All browsers now support pointer events, but JSDOM still does not.
pressProps.onMouseDown = (e)=>{
// Only handle left clicks
if (e.button !== 0 || !e.currentTarget.contains(e.target)) return;
// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on mouse down and handle focusing the pressable element ourselves.
if ($f6c31cce2adf654f$var$shouldPreventDefaultDown(e.currentTarget)) e.preventDefault();
if (e.button !== 0 || !(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (state.ignoreEmulatedMouseEvents) {

@@ -387,9 +395,13 @@ e.stopPropagation();

state.pointerType = (0, $7mdmh$isVirtualClick)(e.nativeEvent) ? 'virtual' : 'mouse';
if (!isDisabled && !preventFocusOnPress) (0, $7mdmh$focusWithoutScrolling)(e.currentTarget);
let shouldStopPropagation = triggerPressStart(e, state.pointerType);
// Flush sync so that focus moved during react re-renders occurs before we yield back to the browser.
let shouldStopPropagation = (0, $7mdmh$flushSync)(()=>triggerPressStart(e, state.pointerType));
if (shouldStopPropagation) e.stopPropagation();
if (preventFocusOnPress) {
let dispose = (0, $8a9cb279dc87e130$export$cabe61c495ee3649)(e.target);
if (dispose) state.disposables.push(dispose);
}
addGlobalListener((0, $7mdmh$getOwnerDocument)(e.currentTarget), 'mouseup', onMouseUp, false);
};
pressProps.onMouseEnter = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
let shouldStopPropagation = true;

@@ -403,3 +415,3 @@ if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {

pressProps.onMouseLeave = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
let shouldStopPropagation = true;

@@ -414,3 +426,3 @@ if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) {

pressProps.onMouseUp = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (!state.ignoreEmulatedMouseEvents && e.button === 0) triggerPressUp(e, state.pointerType || 'mouse');

@@ -421,4 +433,2 @@ };

if (e.button !== 0) return;
state.isPressed = false;
removeAllGlobalListeners();
if (state.ignoreEmulatedMouseEvents) {

@@ -428,8 +438,8 @@ state.ignoreEmulatedMouseEvents = false;

}
if (state.target && $f6c31cce2adf654f$var$isOverTarget(e, state.target) && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType);
else if (state.target && state.isOverTarget && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false);
if (state.target && state.target.contains(e.target) && state.pointerType != null) ;
else cancel(e);
state.isOverTarget = false;
};
pressProps.onTouchStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
let touch = $f6c31cce2adf654f$var$getTouchFromEvent(e.nativeEvent);

@@ -443,5 +453,2 @@ if (!touch) return;

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.
if (!isDisabled && !preventFocusOnPress) (0, $7mdmh$focusWithoutScrolling)(e.currentTarget);
if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$16a4697467175487)(state.target);

@@ -453,3 +460,3 @@ let shouldStopPropagation = triggerPressStart($f6c31cce2adf654f$var$createTouchEvent(state.target, e), state.pointerType);

pressProps.onTouchMove = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (!state.isPressed) {

@@ -474,3 +481,3 @@ e.stopPropagation();

pressProps.onTouchEnd = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
if (!state.isPressed) {

@@ -495,3 +502,3 @@ e.stopPropagation();

pressProps.onTouchCancel = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
e.stopPropagation();

@@ -501,3 +508,3 @@ if (state.isPressed) cancel($f6c31cce2adf654f$var$createTouchEvent(state.target, e));

let onScroll = (e)=>{
if (state.isPressed && e.target.contains(state.target)) cancel({
if (state.isPressed && (0, $7mdmh$nodeContains)((0, $7mdmh$getEventTarget)(e), state.target)) cancel({
currentTarget: state.target,

@@ -511,3 +518,3 @@ shiftKey: false,

pressProps.onDragStart = (e)=>{
if (!e.currentTarget.contains(e.target)) return;
if (!(0, $7mdmh$nodeContains)(e.currentTarget, (0, $7mdmh$getEventTarget)(e.nativeEvent))) return;
cancel(e);

@@ -531,6 +538,8 @@ };

(0, $7mdmh$useEffect)(()=>{
let state = ref.current;
return ()=>{
var _ref_current_target;
if (!allowTextSelectionOnPress) // eslint-disable-next-line react-hooks/exhaustive-deps
(0, $14c0b72509d70225$export$b0d6fa1ab32e3295)((_ref_current_target = ref.current.target) !== null && _ref_current_target !== void 0 ? _ref_current_target : undefined);
var _state_target;
if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)((_state_target = state.target) !== null && _state_target !== void 0 ? _state_target : undefined);
for (let dispose of state.disposables)dispose();
state.disposables = [];
};

@@ -626,6 +635,2 @@ }, [

}
function $f6c31cce2adf654f$var$shouldPreventDefaultDown(target) {
// We cannot prevent default if the target is a draggable element.
return !(target instanceof HTMLElement) || !target.hasAttribute('draggable');
}
function $f6c31cce2adf654f$var$shouldPreventDefaultUp(target) {

@@ -632,0 +637,0 @@ if (target instanceof HTMLInputElement) return false;

@@ -0,3 +1,3 @@

var $iJhOP$reactariautils = require("@react-aria/utils");
var $iJhOP$react = require("react");
var $iJhOP$reactariautils = require("@react-aria/utils");

@@ -10,2 +10,4 @@

$parcel$export(module.exports, "useSyntheticBlurEvent", () => $625cf83917e112ad$export$715c682d09d639cc);
$parcel$export(module.exports, "ignoreFocusEvent", () => $625cf83917e112ad$export$fda7da73ab5d4c48);
$parcel$export(module.exports, "preventFocus", () => $625cf83917e112ad$export$cabe61c495ee3649);
/*

@@ -118,4 +120,57 @@ * Copyright 2020 Adobe. All rights reserved.

}
let $625cf83917e112ad$export$fda7da73ab5d4c48 = false;
function $625cf83917e112ad$export$cabe61c495ee3649(target) {
// The browser will focus the nearest focusable ancestor of our target.
while(target && !(0, $iJhOP$reactariautils.isFocusable)(target))target = target.parentElement;
let window = (0, $iJhOP$reactariautils.getOwnerWindow)(target);
let activeElement = window.document.activeElement;
if (!activeElement || activeElement === target) return;
$625cf83917e112ad$export$fda7da73ab5d4c48 = true;
let isRefocusing = false;
let onBlur = (e)=>{
if (e.target === activeElement || isRefocusing) e.stopImmediatePropagation();
};
let onFocusOut = (e)=>{
if (e.target === activeElement || isRefocusing) {
e.stopImmediatePropagation();
// If there was no focusable ancestor, we don't expect a focus event.
// Re-focus the original active element here.
if (!target && !isRefocusing) {
isRefocusing = true;
(0, $iJhOP$reactariautils.focusWithoutScrolling)(activeElement);
cleanup();
}
}
};
let onFocus = (e)=>{
if (e.target === target || isRefocusing) e.stopImmediatePropagation();
};
let onFocusIn = (e)=>{
if (e.target === target || isRefocusing) {
e.stopImmediatePropagation();
if (!isRefocusing) {
isRefocusing = true;
(0, $iJhOP$reactariautils.focusWithoutScrolling)(activeElement);
cleanup();
}
}
};
window.addEventListener('blur', onBlur, true);
window.addEventListener('focusout', onFocusOut, true);
window.addEventListener('focusin', onFocusIn, true);
window.addEventListener('focus', onFocus, true);
let cleanup = ()=>{
cancelAnimationFrame(raf);
window.removeEventListener('blur', onBlur, true);
window.removeEventListener('focusout', onFocusOut, true);
window.removeEventListener('focusin', onFocusIn, true);
window.removeEventListener('focus', onFocus, true);
$625cf83917e112ad$export$fda7da73ab5d4c48 = false;
isRefocusing = false;
};
let raf = requestAnimationFrame(cleanup);
return cleanup;
}
//# sourceMappingURL=utils.main.js.map

@@ -0,3 +1,3 @@

import {useLayoutEffect as $6dfIe$useLayoutEffect, useEffectEvent as $6dfIe$useEffectEvent, isFocusable as $6dfIe$isFocusable, getOwnerWindow as $6dfIe$getOwnerWindow, focusWithoutScrolling as $6dfIe$focusWithoutScrolling} from "@react-aria/utils";
import {useRef as $6dfIe$useRef, useCallback as $6dfIe$useCallback} from "react";
import {useLayoutEffect as $6dfIe$useLayoutEffect, useEffectEvent as $6dfIe$useEffectEvent} from "@react-aria/utils";

@@ -111,5 +111,58 @@ /*

}
let $8a9cb279dc87e130$export$fda7da73ab5d4c48 = false;
function $8a9cb279dc87e130$export$cabe61c495ee3649(target) {
// The browser will focus the nearest focusable ancestor of our target.
while(target && !(0, $6dfIe$isFocusable)(target))target = target.parentElement;
let window = (0, $6dfIe$getOwnerWindow)(target);
let activeElement = window.document.activeElement;
if (!activeElement || activeElement === target) return;
$8a9cb279dc87e130$export$fda7da73ab5d4c48 = true;
let isRefocusing = false;
let onBlur = (e)=>{
if (e.target === activeElement || isRefocusing) e.stopImmediatePropagation();
};
let onFocusOut = (e)=>{
if (e.target === activeElement || isRefocusing) {
e.stopImmediatePropagation();
// If there was no focusable ancestor, we don't expect a focus event.
// Re-focus the original active element here.
if (!target && !isRefocusing) {
isRefocusing = true;
(0, $6dfIe$focusWithoutScrolling)(activeElement);
cleanup();
}
}
};
let onFocus = (e)=>{
if (e.target === target || isRefocusing) e.stopImmediatePropagation();
};
let onFocusIn = (e)=>{
if (e.target === target || isRefocusing) {
e.stopImmediatePropagation();
if (!isRefocusing) {
isRefocusing = true;
(0, $6dfIe$focusWithoutScrolling)(activeElement);
cleanup();
}
}
};
window.addEventListener('blur', onBlur, true);
window.addEventListener('focusout', onFocusOut, true);
window.addEventListener('focusin', onFocusIn, true);
window.addEventListener('focus', onFocus, true);
let cleanup = ()=>{
cancelAnimationFrame(raf);
window.removeEventListener('blur', onBlur, true);
window.removeEventListener('focusout', onFocusOut, true);
window.removeEventListener('focusin', onFocusIn, true);
window.removeEventListener('focus', onFocus, true);
$8a9cb279dc87e130$export$fda7da73ab5d4c48 = false;
isRefocusing = false;
};
let raf = requestAnimationFrame(cleanup);
return cleanup;
}
export {$8a9cb279dc87e130$export$905e7fc544a71f36 as SyntheticFocusEvent, $8a9cb279dc87e130$export$715c682d09d639cc as useSyntheticBlurEvent};
export {$8a9cb279dc87e130$export$905e7fc544a71f36 as SyntheticFocusEvent, $8a9cb279dc87e130$export$715c682d09d639cc as useSyntheticBlurEvent, $8a9cb279dc87e130$export$fda7da73ab5d4c48 as ignoreFocusEvent, $8a9cb279dc87e130$export$cabe61c495ee3649 as preventFocus};
//# sourceMappingURL=utils.module.js.map
{
"name": "@react-aria/interactions",
"version": "3.0.0-nightly-326f48154-241216",
"version": "3.0.0-nightly-3dbdc1e8e-250214",
"description": "Spectrum UI components in React",

@@ -25,9 +25,11 @@ "license": "Apache-2.0",

"dependencies": {
"@react-aria/ssr": "3.0.0-nightly-326f48154-241216",
"@react-aria/utils": "3.0.0-nightly-326f48154-241216",
"@react-types/shared": "3.0.0-nightly-326f48154-241216",
"@react-aria/ssr": "3.0.0-nightly-3dbdc1e8e-250214",
"@react-aria/utils": "3.0.0-nightly-3dbdc1e8e-250214",
"@react-stately/flags": "3.0.0-nightly-3dbdc1e8e-250214",
"@react-types/shared": "3.0.0-nightly-3dbdc1e8e-250214",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
},

@@ -34,0 +36,0 @@ "publishConfig": {

@@ -35,6 +35,13 @@ /*

stopPropagation() {
console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
if (shouldStopPropagation) {
console.error('stopPropagation is now the default behavior for events in React Spectrum. You can use continuePropagation() to revert this behavior.');
} else {
shouldStopPropagation = true;
}
},
continuePropagation() {
shouldStopPropagation = false;
},
isPropagationStopped() {
return shouldStopPropagation;
}

@@ -41,0 +48,0 @@ };

@@ -20,3 +20,3 @@ /*

import {FocusEvent, useCallback} from 'react';
import {getOwnerDocument} from '@react-aria/utils';
import {getActiveElement, getEventTarget, getOwnerDocument} from '@react-aria/utils';
import {useSyntheticBlurEvent} from './utils';

@@ -68,4 +68,4 @@

const ownerDocument = getOwnerDocument(e.target);
if (e.target === e.currentTarget && ownerDocument.activeElement === e.target) {
const activeElement = ownerDocument ? getActiveElement(ownerDocument) : getActiveElement();
if (e.target === e.currentTarget && activeElement === getEventTarget(e.nativeEvent)) {
if (onFocusProp) {

@@ -72,0 +72,0 @@ onFocusProp(e);

@@ -19,2 +19,3 @@ /*

import {getOwnerDocument, getOwnerWindow, isMac, isVirtualClick} from '@react-aria/utils';
import {ignoreFocusEvent} from './utils';
import {useEffect, useState} from 'react';

@@ -96,3 +97,3 @@ import {useIsSSR} from '@react-aria/ssr';

// cause keyboard focus rings to appear.
if (e.target === window || e.target === document) {
if (e.target === window || e.target === document || ignoreFocusEvent) {
return;

@@ -113,2 +114,6 @@ }

function handleWindowBlur() {
if (ignoreFocusEvent) {
return;
}
// When the window is blurred, reset state. This is necessary when tabbing out of the window,

@@ -182,2 +187,3 @@ // for example, since a subsequent focus event won't be fired.

documentObject.removeEventListener('click', handleClickEvent, true);
windowObject.removeEventListener('focus', handleFocusEvent, true);

@@ -291,2 +297,3 @@ windowObject.removeEventListener('blur', handleWindowBlur, false);

function isKeyboardFocusEvent(isTextInput: boolean, modality: Modality, e: HandlerEvent) {
let document = getOwnerDocument(e?.target as Element);
const IHTMLInputElement = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).HTMLInputElement : HTMLInputElement;

@@ -297,6 +304,8 @@ const IHTMLTextAreaElement = typeof window !== 'undefined' ? getOwnerWindow(e?.target as Element).HTMLTextAreaElement : HTMLTextAreaElement;

// For keyboard events that occur on a non-input element that will move focus into input element (aka ArrowLeft going from Datepicker button to the main input group)
// we need to rely on the user passing isTextInput into here. This way we can skip toggling focus visiblity for said input element
isTextInput = isTextInput ||
(e?.target instanceof IHTMLInputElement && !nonTextInputTypes.has(e?.target?.type)) ||
e?.target instanceof IHTMLTextAreaElement ||
(e?.target instanceof IHTMLElement && e?.target.isContentEditable);
(document.activeElement instanceof IHTMLInputElement && !nonTextInputTypes.has(document.activeElement.type)) ||
document.activeElement instanceof IHTMLTextAreaElement ||
(document.activeElement instanceof IHTMLElement && document.activeElement.isContentEditable);
return !(isTextInput && modality === 'keyboard' && e instanceof IKeyboardEvent && !FOCUS_VISIBLE_INPUT_KEYS[e.key]);

@@ -326,2 +335,3 @@ }

let handler = (modality: Modality, e: HandlerEvent) => {
// We want to early return for any keyboard events that occur inside text inputs EXCEPT for Tab and Escape
if (!isKeyboardFocusEvent(!!(opts?.isTextInput), modality, e)) {

@@ -328,0 +338,0 @@ return;

@@ -20,2 +20,3 @@ /*

import {FocusEvent, useCallback, useRef} from 'react';
import {getActiveElement, getEventTarget, getOwnerDocument} from '@react-aria/utils';
import {useSyntheticBlurEvent} from './utils';

@@ -74,3 +75,5 @@

// focus handler already moved focus somewhere else.
if (!state.current.isFocusWithin && document.activeElement === e.target) {
const ownerDocument = getOwnerDocument(e.target);
const activeElement = getActiveElement(ownerDocument);
if (!state.current.isFocusWithin && activeElement === getEventTarget(e.nativeEvent)) {
if (onFocusWithin) {

@@ -92,3 +95,3 @@ onFocusWithin(e);

focusWithinProps: {
// These should not have been null, that would conflict in mergeProps
// These cannot be null, that would conflict in mergeProps
onFocus: undefined,

@@ -95,0 +98,0 @@ onBlur: undefined

@@ -119,3 +119,2 @@ /*

}
if (event.target) {

@@ -127,3 +126,2 @@ // if the event target is no longer in the document, ignore

}
// If the target is within a top layer element (e.g. toasts), ignore.

@@ -135,3 +133,11 @@ if (event.target.closest('[data-react-aria-top-layer]')) {

return ref.current && !ref.current.contains(event.target);
if (!ref.current) {
return false;
}
// When the event source is inside a Shadow DOM, event.target is just the shadow root.
// Using event.composedPath instead means we can get the actual element inside the shadow root.
// This only works if the shadow root is open, there is no way to detect if it is closed.
// If the event composed path contains the ref, interaction is inside.
return !event.composedPath().includes(ref.current);
}

@@ -13,4 +13,4 @@ /*

import {DOMAttributes, LongPressEvent} from '@react-types/shared';
import {mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';
import {DOMAttributes, FocusableElement, LongPressEvent} from '@react-types/shared';
import {focusWithoutScrolling, getOwnerDocument, mergeProps, useDescription, useGlobalListeners} from '@react-aria/utils';
import {usePress} from './usePress';

@@ -85,2 +85,8 @@ import {useRef} from 'react';

e.target.dispatchEvent(new PointerEvent('pointercancel', {bubbles: true}));
// Ensure target is focused. On touch devices, browsers typically focus on pointer up.
if (getOwnerDocument(e.target).activeElement !== e.target) {
focusWithoutScrolling(e.target as FocusableElement);
}
if (onLongPress) {

@@ -87,0 +93,0 @@ onLongPress({

@@ -18,6 +18,23 @@ /*

import {chain, focusWithoutScrolling, getOwnerDocument, getOwnerWindow, isMac, isVirtualClick, isVirtualPointerEvent, mergeProps, openLink, useEffectEvent, useGlobalListeners, useSyncRef} from '@react-aria/utils';
import {
chain,
focusWithoutScrolling,
getEventTarget,
getOwnerDocument,
getOwnerWindow,
isMac,
isVirtualClick,
isVirtualPointerEvent,
mergeProps,
nodeContains,
openLink,
useEffectEvent,
useGlobalListeners,
useSyncRef
} from '@react-aria/utils';
import {disableTextSelection, restoreTextSelection} from './textSelection';
import {DOMAttributes, FocusableElement, PressEvent as IPressEvent, PointerType, PressEvents, RefObject} from '@react-types/shared';
import {flushSync} from 'react-dom';
import {PressResponderContext} from './context';
import {preventFocus} from './utils';
import {TouchEvent as RTouchEvent, useContext, useEffect, useMemo, useRef, useState} from 'react';

@@ -51,3 +68,2 @@

ignoreEmulatedMouseEvents: boolean,
ignoreClickAfterPress: boolean,
didFirePressStart: boolean,

@@ -60,3 +76,4 @@ isTriggeringEvent: boolean,

userSelect?: string,
metaKeyEvents?: Map<string, KeyboardEvent>
metaKeyEvents?: Map<string, KeyboardEvent>,
disposables: Array<() => void>
}

@@ -173,3 +190,2 @@

ignoreEmulatedMouseEvents: false,
ignoreClickAfterPress: false,
didFirePressStart: false,

@@ -180,3 +196,4 @@ isTriggeringEvent: false,

isOverTarget: false,
pointerType: null
pointerType: null,
disposables: []
});

@@ -216,3 +233,2 @@

state.ignoreClickAfterPress = true;
state.didFirePressStart = false;

@@ -264,3 +280,3 @@ state.isTriggeringEvent = true;

if (state.isPressed && state.target) {
if (state.isOverTarget && state.pointerType != null) {
if (state.didFirePressStart && state.pointerType != null) {
triggerPressEnd(createEvent(state.target, e), state.pointerType, false);

@@ -276,2 +292,6 @@ }

}
for (let dispose of state.disposables) {
dispose();
}
state.disposables = [];
}

@@ -290,4 +310,4 @@ });

onKeyDown(e) {
if (isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && e.currentTarget.contains(e.target as Element)) {
if (shouldPreventDefaultKeyboard(e.target as Element, e.key)) {
if (isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
if (shouldPreventDefaultKeyboard(getEventTarget(e.nativeEvent), e.key)) {
e.preventDefault();

@@ -303,2 +323,3 @@ }

state.isPressed = true;
state.pointerType = 'keyboard';
shouldStopPropagation = triggerPressStart(e, 'keyboard');

@@ -311,3 +332,3 @@

let pressUp = (e) => {
if (isValidKeyboardEvent(e, originalTarget) && !e.repeat && originalTarget.contains(e.target as Element) && state.target) {
if (isValidKeyboardEvent(e, originalTarget) && !e.repeat && nodeContains(originalTarget, getEventTarget(e)) && state.target) {
triggerPressUp(createEvent(state.target, e), 'keyboard');

@@ -339,3 +360,3 @@ }

onClick(e) {
if (e && !e.currentTarget.contains(e.target as Element)) {
if (e && !nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -349,11 +370,6 @@ }

}
// If triggered from a screen reader or by using element.click(),
// trigger as if it were a keyboard click.
if (!state.ignoreClickAfterPress && !state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || isVirtualClick(e.nativeEvent))) {
// Ensure the element receives focus (VoiceOver on iOS does not do this)
if (!isDisabled && !preventFocusOnPress) {
focusWithoutScrolling(e.currentTarget);
}
if (!state.ignoreEmulatedMouseEvents && !state.isPressed && (state.pointerType === 'virtual' || isVirtualClick(e.nativeEvent))) {
let stopPressStart = triggerPressStart(e, 'virtual');

@@ -363,6 +379,10 @@ let stopPressUp = triggerPressUp(e, 'virtual');

shouldStopPropagation = stopPressStart && stopPressUp && stopPressEnd;
} else if (state.isPressed && state.pointerType !== 'keyboard') {
let pointerType = state.pointerType || (e.nativeEvent as PointerEvent).pointerType as PointerType || 'virtual';
shouldStopPropagation = triggerPressEnd(createEvent(e.currentTarget, e), pointerType, true);
state.isOverTarget = false;
cancel(e);
}
state.ignoreEmulatedMouseEvents = false;
state.ignoreClickAfterPress = false;
if (shouldStopPropagation) {

@@ -377,8 +397,8 @@ e.stopPropagation();

if (state.isPressed && state.target && isValidKeyboardEvent(e, state.target)) {
if (shouldPreventDefaultKeyboard(e.target as Element, e.key)) {
if (shouldPreventDefaultKeyboard(getEventTarget(e), e.key)) {
e.preventDefault();
}
let target = e.target as Element;
triggerPressEnd(createEvent(state.target, e), 'keyboard', state.target.contains(target));
let target = getEventTarget(e);
triggerPressEnd(createEvent(state.target, e), 'keyboard', nodeContains(state.target, getEventTarget(e)));
removeAllGlobalListeners();

@@ -389,3 +409,3 @@

// only applies when using the Enter key.
if (e.key !== 'Enter' && isHTMLAnchorLink(state.target) && state.target.contains(target) && !e[LINK_CLICKED]) {
if (e.key !== 'Enter' && isHTMLAnchorLink(state.target) && nodeContains(state.target, target) && !e[LINK_CLICKED]) {
// Store a hidden property on the event so we only trigger link click once,

@@ -414,3 +434,3 @@ // even if there are multiple usePress instances attached to the element.

// Only handle left clicks, and ignore events that bubbled through portals.
if (e.button !== 0 || !e.currentTarget.contains(e.target as Element)) {
if (e.button !== 0 || !nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -428,8 +448,2 @@ }

// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on pointer down and handle focusing the pressable element ourselves.
if (shouldPreventDefaultDown(e.currentTarget as Element)) {
e.preventDefault();
}
state.pointerType = e.pointerType;

@@ -442,8 +456,4 @@

state.activePointerId = e.pointerId;
state.target = e.currentTarget;
state.target = e.currentTarget as FocusableElement;
if (!isDisabled && !preventFocusOnPress) {
focusWithoutScrolling(e.currentTarget);
}
if (!allowTextSelectionOnPress) {

@@ -457,3 +467,3 @@ disableTextSelection(state.target);

// This enables onPointerLeave and onPointerEnter to fire.
let target = e.target as Element;
let target = getEventTarget(e.nativeEvent);
if ('releasePointerCapture' in target) {

@@ -473,3 +483,3 @@ target.releasePointerCapture(e.pointerId);

pressProps.onMouseDown = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -479,7 +489,7 @@ }

if (e.button === 0) {
// Chrome and Firefox on touch Windows devices require mouse down events
// to be canceled in addition to pointer events, or an extra asynchronous
// focus event will be fired.
if (shouldPreventDefaultDown(e.currentTarget as Element)) {
e.preventDefault();
if (preventFocusOnPress) {
let dispose = preventFocus(e.target as FocusableElement);
if (dispose) {
state.disposables.push(dispose);
}
}

@@ -493,3 +503,3 @@

// iOS fires pointerup with zero width and height, so check the pointerType recorded during pointerdown.
if (!e.currentTarget.contains(e.target as Element) || state.pointerType === 'virtual') {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent)) || state.pointerType === 'virtual') {
return;

@@ -521,38 +531,37 @@ }

if (e.pointerId === state.activePointerId && state.isPressed && e.button === 0 && state.target) {
if (state.target.contains(e.target as Element) && state.pointerType != null) {
triggerPressEnd(createEvent(state.target, e), state.pointerType);
} else if (state.isOverTarget && state.pointerType != null) {
triggerPressEnd(createEvent(state.target, e), state.pointerType, false);
if (nodeContains(state.target, getEventTarget(e)) && state.pointerType != null) {
// Wait for onClick to fire onPress. This avoids browser issues when the DOM
// is mutated between onPointerUp and onClick, and is more compatible with third party libraries.
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// However, iOS and Android do not focus or fire onClick after a long press.
// We work around this by triggering a click ourselves after a timeout.
// This timeout is canceled during the click event in case the real one fires first.
// The timeout must be at least 32ms, because Safari on iOS delays the click event on
// non-form elements without certain ARIA roles (for hover emulation).
// https://github.com/WebKit/WebKit/blob/dccfae42bb29bd4bdef052e469f604a9387241c0/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm#L875-L892
let clicked = false;
let timeout = setTimeout(() => {
if (state.isPressed && state.target instanceof HTMLElement) {
if (clicked) {
cancel(e);
} else {
focusWithoutScrolling(state.target);
state.target.click();
}
}
}, 40);
// Use a capturing listener to track if a click occurred.
// If stopPropagation is called it may never reach our handler.
addGlobalListener(e.currentTarget as Document, 'click', () => clicked = true, true);
state.disposables.push(() => clearTimeout(timeout));
} else {
cancel(e);
}
state.isPressed = false;
// Ignore subsequent onPointerLeave event before onClick on touch devices.
state.isOverTarget = false;
state.activePointerId = null;
state.pointerType = null;
removeAllGlobalListeners();
if (!allowTextSelectionOnPress) {
restoreTextSelection(state.target);
}
// Prevent subsequent touchend event from triggering onClick on unrelated elements on Android. See below.
// Both 'touch' and 'pen' pointerTypes trigger onTouchEnd, but 'mouse' does not.
if ('ontouchend' in state.target && e.pointerType !== 'mouse') {
addGlobalListener(state.target, 'touchend', onTouchEnd, {once: true});
}
}
};
// This is a workaround for an Android Chrome/Firefox issue where click events are fired on an incorrect element
// if the original target is removed during onPointerUp (before onClick).
// https://github.com/adobe/react-spectrum/issues/1513
// https://issues.chromium.org/issues/40732224
// Note: this event must be registered directly on the element, not via React props in order to work.
// https://github.com/facebook/react/issues/9809
let onTouchEnd = (e: TouchEvent) => {
// Don't preventDefault if we actually want the default (e.g. submit/link click).
if (shouldPreventDefaultUp(e.currentTarget as Element)) {
e.preventDefault();
}
};
let onPointerCancel = (e: PointerEvent) => {

@@ -563,3 +572,3 @@ cancel(e);

pressProps.onDragStart = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -572,14 +581,11 @@ }

} else {
// NOTE: this fallback branch is almost entirely used by unit tests.
// All browsers now support pointer events, but JSDOM still does not.
pressProps.onMouseDown = (e) => {
// Only handle left clicks
if (e.button !== 0 || !e.currentTarget.contains(e.target as Element)) {
if (e.button !== 0 || !nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;
}
// Due to browser inconsistencies, especially on mobile browsers, we prevent
// default on mouse down and handle focusing the pressable element ourselves.
if (shouldPreventDefaultDown(e.currentTarget)) {
e.preventDefault();
}
if (state.ignoreEmulatedMouseEvents) {

@@ -595,7 +601,4 @@ e.stopPropagation();

if (!isDisabled && !preventFocusOnPress) {
focusWithoutScrolling(e.currentTarget);
}
let shouldStopPropagation = triggerPressStart(e, state.pointerType);
// Flush sync so that focus moved during react re-renders occurs before we yield back to the browser.
let shouldStopPropagation = flushSync(() => triggerPressStart(e, state.pointerType!));
if (shouldStopPropagation) {

@@ -605,2 +608,9 @@ e.stopPropagation();

if (preventFocusOnPress) {
let dispose = preventFocus(e.target as FocusableElement);
if (dispose) {
state.disposables.push(dispose);
}
}
addGlobalListener(getOwnerDocument(e.currentTarget), 'mouseup', onMouseUp, false);

@@ -610,3 +620,3 @@ };

pressProps.onMouseEnter = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -627,3 +637,3 @@ }

pressProps.onMouseLeave = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -645,3 +655,3 @@ }

pressProps.onMouseUp = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -661,5 +671,2 @@ }

state.isPressed = false;
removeAllGlobalListeners();
if (state.ignoreEmulatedMouseEvents) {

@@ -670,6 +677,7 @@ state.ignoreEmulatedMouseEvents = false;

if (state.target && isOverTarget(e, state.target) && state.pointerType != null) {
triggerPressEnd(createEvent(state.target, e), state.pointerType);
} else if (state.target && state.isOverTarget && state.pointerType != null) {
triggerPressEnd(createEvent(state.target, e), state.pointerType, false);
if (state.target && state.target.contains(e.target as Element) && state.pointerType != null) {
// Wait for onClick to fire onPress. This avoids browser issues when the DOM
// is mutated between onMouseUp and onClick, and is more compatible with third party libraries.
} else {
cancel(e);
}

@@ -681,3 +689,3 @@

pressProps.onTouchStart = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -697,8 +705,2 @@ }

// Due to browser inconsistencies, especially on mobile browsers, we prevent default
// on the emulated mouse event and handle focusing the pressable element ourselves.
if (!isDisabled && !preventFocusOnPress) {
focusWithoutScrolling(e.currentTarget);
}
if (!allowTextSelectionOnPress) {

@@ -717,3 +719,3 @@ disableTextSelection(state.target);

pressProps.onTouchMove = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -746,3 +748,3 @@ }

pressProps.onTouchEnd = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -780,3 +782,3 @@ }

pressProps.onTouchCancel = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -792,3 +794,3 @@ }

let onScroll = (e: Event) => {
if (state.isPressed && (e.target as Element).contains(state.target)) {
if (state.isPressed && nodeContains(getEventTarget(e), state.target)) {
cancel({

@@ -805,3 +807,3 @@ currentTarget: state.target,

pressProps.onDragStart = (e) => {
if (!e.currentTarget.contains(e.target as Element)) {
if (!nodeContains(e.currentTarget, getEventTarget(e.nativeEvent))) {
return;

@@ -831,7 +833,12 @@ }

useEffect(() => {
let state = ref.current;
return () => {
if (!allowTextSelectionOnPress) {
// eslint-disable-next-line react-hooks/exhaustive-deps
restoreTextSelection(ref.current.target ?? undefined);
restoreTextSelection(state.target ?? undefined);
}
for (let dispose of state.disposables) {
dispose();
}
state.disposables = [];
};

@@ -976,7 +983,2 @@ }, [allowTextSelectionOnPress]);

function shouldPreventDefaultDown(target: Element) {
// We cannot prevent default if the target is a draggable element.
return !(target instanceof HTMLElement) || !target.hasAttribute('draggable');
}
function shouldPreventDefaultUp(target: Element) {

@@ -983,0 +985,0 @@ if (target instanceof HTMLInputElement) {

@@ -13,4 +13,5 @@ /*

import {FocusableElement} from '@react-types/shared';
import {focusWithoutScrolling, getOwnerWindow, isFocusable, useEffectEvent, useLayoutEffect} from '@react-aria/utils';
import {FocusEvent as ReactFocusEvent, useCallback, useRef} from 'react';
import {useEffectEvent, useLayoutEffect} from '@react-aria/utils';

@@ -132,1 +133,79 @@ export class SyntheticFocusEvent<Target = Element> implements ReactFocusEvent<Target> {

}
export let ignoreFocusEvent = false;
/**
* This function prevents the next focus event fired on `target`, without using `event.preventDefault()`.
* It works by waiting for the series of focus events to occur, and reverts focus back to where it was before.
* It also makes these events mostly non-observable by using a capturing listener on the window and stopping propagation.
*/
export function preventFocus(target: FocusableElement | null) {
// The browser will focus the nearest focusable ancestor of our target.
while (target && !isFocusable(target)) {
target = target.parentElement;
}
let window = getOwnerWindow(target);
let activeElement = window.document.activeElement as FocusableElement | null;
if (!activeElement || activeElement === target) {
return;
}
ignoreFocusEvent = true;
let isRefocusing = false;
let onBlur = (e: FocusEvent) => {
if (e.target === activeElement || isRefocusing) {
e.stopImmediatePropagation();
}
};
let onFocusOut = (e: FocusEvent) => {
if (e.target === activeElement || isRefocusing) {
e.stopImmediatePropagation();
// If there was no focusable ancestor, we don't expect a focus event.
// Re-focus the original active element here.
if (!target && !isRefocusing) {
isRefocusing = true;
focusWithoutScrolling(activeElement);
cleanup();
}
}
};
let onFocus = (e: FocusEvent) => {
if (e.target === target || isRefocusing) {
e.stopImmediatePropagation();
}
};
let onFocusIn = (e: FocusEvent) => {
if (e.target === target || isRefocusing) {
e.stopImmediatePropagation();
if (!isRefocusing) {
isRefocusing = true;
focusWithoutScrolling(activeElement);
cleanup();
}
}
};
window.addEventListener('blur', onBlur, true);
window.addEventListener('focusout', onFocusOut, true);
window.addEventListener('focusin', onFocusIn, true);
window.addEventListener('focus', onFocus, true);
let cleanup = () => {
cancelAnimationFrame(raf);
window.removeEventListener('blur', onBlur, true);
window.removeEventListener('focusout', onFocusOut, true);
window.removeEventListener('focusin', onFocusIn, true);
window.removeEventListener('focus', onFocus, true);
ignoreFocusEvent = false;
isRefocusing = false;
};
let raf = requestAnimationFrame(cleanup);
return cleanup;
}

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

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

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

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

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

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

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

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc