UNPKG

@react-aria/interactions

Version:
932 lines (904 loc) • 90.4 kB
import {useObjectRef as $bx7SL$useObjectRef, mergeProps as $bx7SL$mergeProps, useSyncRef as $bx7SL$useSyncRef, useGlobalListeners as $bx7SL$useGlobalListeners, useEffectEvent as $bx7SL$useEffectEvent, getOwnerDocument as $bx7SL$getOwnerDocument, isMac as $bx7SL$isMac, openLink as $bx7SL$openLink, isVirtualClick as $bx7SL$isVirtualClick, focusWithoutScrolling as $bx7SL$focusWithoutScrolling, isVirtualPointerEvent as $bx7SL$isVirtualPointerEvent, getOwnerWindow as $bx7SL$getOwnerWindow, isIOS as $bx7SL$isIOS, runAfterTransition as $bx7SL$runAfterTransition, useLayoutEffect as $bx7SL$useLayoutEffect, useEvent as $bx7SL$useEvent, useDescription as $bx7SL$useDescription} from "@react-aria/utils"; import $bx7SL$react, {useContext as $bx7SL$useContext, useState as $bx7SL$useState, useRef as $bx7SL$useRef, useMemo as $bx7SL$useMemo, useEffect as $bx7SL$useEffect, useCallback as $bx7SL$useCallback} from "react"; import {_ as $bx7SL$_} from "@swc/helpers/_/_class_private_field_get"; import {_ as $bx7SL$_1} from "@swc/helpers/_/_class_private_field_init"; import {_ as $bx7SL$_2} from "@swc/helpers/_/_class_private_field_set"; import {useIsSSR as $bx7SL$useIsSSR} from "@react-aria/ssr"; /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ // Portions of the code in this file are based on code from react. // Original licensing for the following can be found in the // NOTICE file in the root directory of this source tree. // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ // Note that state only matters here for iOS. Non-iOS gets user-select: none applied to the target element // rather than at the document level so we just need to apply/remove user-select: none for each pressed element individually let $14c0b72509d70225$var$state = "default"; let $14c0b72509d70225$var$savedUserSelect = ""; let $14c0b72509d70225$var$modifiedElementMap = new WeakMap(); function $14c0b72509d70225$export$16a4697467175487(target) { if ((0, $bx7SL$isIOS)()) { if ($14c0b72509d70225$var$state === "default") { // eslint-disable-next-line no-restricted-globals const documentObject = (0, $bx7SL$getOwnerDocument)(target); $14c0b72509d70225$var$savedUserSelect = documentObject.documentElement.style.webkitUserSelect; documentObject.documentElement.style.webkitUserSelect = "none"; } $14c0b72509d70225$var$state = "disabled"; } else if (target instanceof HTMLElement || target instanceof SVGElement) { // If not iOS, store the target's original user-select and change to user-select: none // Ignore state since it doesn't apply for non iOS $14c0b72509d70225$var$modifiedElementMap.set(target, target.style.userSelect); target.style.userSelect = "none"; } } function $14c0b72509d70225$export$b0d6fa1ab32e3295(target) { if ((0, $bx7SL$isIOS)()) { // If the state is already default, there's nothing to do. // If it is restoring, then there's no need to queue a second restore. if ($14c0b72509d70225$var$state !== "disabled") return; $14c0b72509d70225$var$state = "restoring"; // There appears to be a delay on iOS where selection still might occur // after pointer up, so wait a bit before removing user-select. setTimeout(()=>{ // Wait for any CSS transitions to complete so we don't recompute style // for the whole page in the middle of the animation and cause jank. (0, $bx7SL$runAfterTransition)(()=>{ // Avoid race conditions if ($14c0b72509d70225$var$state === "restoring") { // eslint-disable-next-line no-restricted-globals const documentObject = (0, $bx7SL$getOwnerDocument)(target); if (documentObject.documentElement.style.webkitUserSelect === "none") documentObject.documentElement.style.webkitUserSelect = $14c0b72509d70225$var$savedUserSelect || ""; $14c0b72509d70225$var$savedUserSelect = ""; $14c0b72509d70225$var$state = "default"; } }); }, 300); } else if (target instanceof HTMLElement || target instanceof SVGElement) // If not iOS, restore the target's original user-select if any // Ignore state since it doesn't apply for non iOS { if (target && $14c0b72509d70225$var$modifiedElementMap.has(target)) { let targetOldUserSelect = $14c0b72509d70225$var$modifiedElementMap.get(target); if (target.style.userSelect === "none" && targetOldUserSelect) target.style.userSelect = targetOldUserSelect; if (target.getAttribute("style") === "") target.removeAttribute("style"); $14c0b72509d70225$var$modifiedElementMap.delete(target); } } } /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ const $ae1eeba8b9eafd08$export$5165eccb35aaadb5 = (0, $bx7SL$react).createContext({ register: ()=>{} }); $ae1eeba8b9eafd08$export$5165eccb35aaadb5.displayName = "PressResponderContext"; function $f6c31cce2adf654f$var$usePressResponderContext(props) { // Consume context from <PressResponder> and merge with props. let context = (0, $bx7SL$useContext)((0, $ae1eeba8b9eafd08$export$5165eccb35aaadb5)); if (context) { let { register: register, ...contextProps } = context; props = (0, $bx7SL$mergeProps)(contextProps, props); register(); } (0, $bx7SL$useSyncRef)(context, props.ref); return props; } var $f6c31cce2adf654f$var$_shouldStopPropagation = /*#__PURE__*/ new WeakMap(); class $f6c31cce2adf654f$var$PressEvent { continuePropagation() { (0, $bx7SL$_2)(this, $f6c31cce2adf654f$var$_shouldStopPropagation, false); } get shouldStopPropagation() { return (0, $bx7SL$_)(this, $f6c31cce2adf654f$var$_shouldStopPropagation); } constructor(type, pointerType, originalEvent){ (0, $bx7SL$_1)(this, $f6c31cce2adf654f$var$_shouldStopPropagation, { writable: true, value: void 0 }); (0, $bx7SL$_2)(this, $f6c31cce2adf654f$var$_shouldStopPropagation, true); this.type = type; this.pointerType = pointerType; this.target = originalEvent.currentTarget; this.shiftKey = originalEvent.shiftKey; this.metaKey = originalEvent.metaKey; this.ctrlKey = originalEvent.ctrlKey; this.altKey = originalEvent.altKey; } } const $f6c31cce2adf654f$var$LINK_CLICKED = Symbol("linkClicked"); function $f6c31cce2adf654f$export$45712eceda6fad21(props) { let { onPress: onPress, onPressChange: onPressChange, onPressStart: onPressStart, onPressEnd: onPressEnd, onPressUp: onPressUp, isDisabled: isDisabled, isPressed: isPressedProp, preventFocusOnPress: preventFocusOnPress, shouldCancelOnPointerExit: shouldCancelOnPointerExit, allowTextSelectionOnPress: allowTextSelectionOnPress, // eslint-disable-next-line @typescript-eslint/no-unused-vars ref: _, ...domProps } = $f6c31cce2adf654f$var$usePressResponderContext(props); let [isPressed, setPressed] = (0, $bx7SL$useState)(false); let ref = (0, $bx7SL$useRef)({ isPressed: false, ignoreEmulatedMouseEvents: false, ignoreClickAfterPress: false, didFirePressStart: false, isTriggeringEvent: false, activePointerId: null, target: null, isOverTarget: false, pointerType: null }); let { addGlobalListener: addGlobalListener, removeAllGlobalListeners: removeAllGlobalListeners } = (0, $bx7SL$useGlobalListeners)(); let triggerPressStart = (0, $bx7SL$useEffectEvent)((originalEvent, pointerType)=>{ let state = ref.current; if (isDisabled || state.didFirePressStart) return false; let shouldStopPropagation = true; state.isTriggeringEvent = true; if (onPressStart) { let event = new $f6c31cce2adf654f$var$PressEvent("pressstart", pointerType, originalEvent); onPressStart(event); shouldStopPropagation = event.shouldStopPropagation; } if (onPressChange) onPressChange(true); state.isTriggeringEvent = false; state.didFirePressStart = true; setPressed(true); return shouldStopPropagation; }); let triggerPressEnd = (0, $bx7SL$useEffectEvent)((originalEvent, pointerType, wasPressed = true)=>{ let state = ref.current; if (!state.didFirePressStart) return false; state.ignoreClickAfterPress = true; state.didFirePressStart = false; state.isTriggeringEvent = true; let shouldStopPropagation = true; if (onPressEnd) { let event = new $f6c31cce2adf654f$var$PressEvent("pressend", pointerType, originalEvent); onPressEnd(event); shouldStopPropagation = event.shouldStopPropagation; } if (onPressChange) onPressChange(false); setPressed(false); if (onPress && wasPressed && !isDisabled) { let event = new $f6c31cce2adf654f$var$PressEvent("press", pointerType, originalEvent); onPress(event); shouldStopPropagation && (shouldStopPropagation = event.shouldStopPropagation); } state.isTriggeringEvent = false; return shouldStopPropagation; }); let triggerPressUp = (0, $bx7SL$useEffectEvent)((originalEvent, pointerType)=>{ let state = ref.current; if (isDisabled) return false; if (onPressUp) { state.isTriggeringEvent = true; let event = new $f6c31cce2adf654f$var$PressEvent("pressup", pointerType, originalEvent); onPressUp(event); state.isTriggeringEvent = false; return event.shouldStopPropagation; } return true; }); let cancel = (0, $bx7SL$useEffectEvent)((e)=>{ let state = ref.current; if (state.isPressed && state.target) { if (state.isOverTarget && state.pointerType != null) triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false); state.isPressed = false; state.isOverTarget = false; state.activePointerId = null; state.pointerType = null; removeAllGlobalListeners(); if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)(state.target); } }); let cancelOnPointerExit = (0, $bx7SL$useEffectEvent)((e)=>{ if (shouldCancelOnPointerExit) cancel(e); }); let pressProps = (0, $bx7SL$useMemo)(()=>{ let state = ref.current; let pressProps = { onKeyDown (e) { if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && e.currentTarget.contains(e.target)) { var _state_metaKeyEvents; if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault(); // If the event is repeating, it may have started on a different element // after which focus moved to the current element. Ignore these events and // only handle the first key down event. let shouldStopPropagation = true; if (!state.isPressed && !e.repeat) { state.target = e.currentTarget; state.isPressed = true; shouldStopPropagation = triggerPressStart(e, "keyboard"); // Focus may move before the key up event, so register the event on the document // instead of the same element where the key down event occurred. addGlobalListener((0, $bx7SL$getOwnerDocument)(e.currentTarget), "keyup", onKeyUp, false); } if (shouldStopPropagation) e.stopPropagation(); // Keep track of the keydown events that occur while the Meta (e.g. Command) key is held. // macOS has a bug where keyup events are not fired while the Meta key is down. // When the Meta key itself is released we will get an event for that, and we'll act as if // all of these other keys were released as well. // https://bugs.chromium.org/p/chromium/issues/detail?id=1393524 // https://bugs.webkit.org/show_bug.cgi?id=55291 // https://bugzilla.mozilla.org/show_bug.cgi?id=1299553 if (e.metaKey && (0, $bx7SL$isMac)()) (_state_metaKeyEvents = state.metaKeyEvents) === null || _state_metaKeyEvents === void 0 ? void 0 : _state_metaKeyEvents.set(e.key, e.nativeEvent); } else if (e.key === "Meta") state.metaKeyEvents = new Map(); }, onKeyUp (e) { if ($f6c31cce2adf654f$var$isValidKeyboardEvent(e.nativeEvent, e.currentTarget) && !e.repeat && e.currentTarget.contains(e.target) && state.target) triggerPressUp($f6c31cce2adf654f$var$createEvent(state.target, e), "keyboard"); }, onClick (e) { if (e && !e.currentTarget.contains(e.target)) return; if (e && e.button === 0 && !state.isTriggeringEvent && !(0, $bx7SL$openLink).isOpening) { let shouldStopPropagation = true; if (isDisabled) e.preventDefault(); // 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" || (0, $bx7SL$isVirtualClick)(e.nativeEvent))) { // Ensure the element receives focus (VoiceOver on iOS does not do this) if (!isDisabled && !preventFocusOnPress) (0, $bx7SL$focusWithoutScrolling)(e.currentTarget); let stopPressStart = triggerPressStart(e, "virtual"); let stopPressUp = triggerPressUp(e, "virtual"); let stopPressEnd = triggerPressEnd(e, "virtual"); shouldStopPropagation = stopPressStart && stopPressUp && stopPressEnd; } state.ignoreEmulatedMouseEvents = false; state.ignoreClickAfterPress = false; if (shouldStopPropagation) e.stopPropagation(); } } }; let onKeyUp = (e)=>{ var _state_metaKeyEvents; if (state.isPressed && state.target && $f6c31cce2adf654f$var$isValidKeyboardEvent(e, state.target)) { var _state_metaKeyEvents1; if ($f6c31cce2adf654f$var$shouldPreventDefaultKeyboard(e.target, e.key)) e.preventDefault(); let target = e.target; let shouldStopPropagation = triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), "keyboard", state.target.contains(target)); removeAllGlobalListeners(); if (shouldStopPropagation) e.stopPropagation(); // If a link was triggered with a key other than Enter, open the URL ourselves. // This means the link has a role override, and the default browser behavior // 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]) { // Store a hidden property on the event so we only trigger link click once, // even if there are multiple usePress instances attached to the element. e[$f6c31cce2adf654f$var$LINK_CLICKED] = true; (0, $bx7SL$openLink)(state.target, e, false); } state.isPressed = false; (_state_metaKeyEvents1 = state.metaKeyEvents) === null || _state_metaKeyEvents1 === void 0 ? void 0 : _state_metaKeyEvents1.delete(e.key); } else if (e.key === "Meta" && ((_state_metaKeyEvents = state.metaKeyEvents) === null || _state_metaKeyEvents === void 0 ? void 0 : _state_metaKeyEvents.size)) { var _state_target; // If we recorded keydown events that occurred while the Meta key was pressed, // and those haven't received keyup events already, fire keyup events ourselves. // See comment above for more info about the macOS bug causing this. let events = state.metaKeyEvents; state.metaKeyEvents = undefined; for (let event of events.values())(_state_target = state.target) === null || _state_target === void 0 ? void 0 : _state_target.dispatchEvent(new KeyboardEvent("keyup", event)); } }; if (typeof PointerEvent !== "undefined") { pressProps.onPointerDown = (e)=>{ // Only handle left clicks, and ignore events that bubbled through portals. if (e.button !== 0 || !e.currentTarget.contains(e.target)) return; // iOS safari fires pointer events from VoiceOver with incorrect coordinates/target. // Ignore and let the onClick handler take care of it instead. // https://bugs.webkit.org/show_bug.cgi?id=222627 // https://bugs.webkit.org/show_bug.cgi?id=223202 if ((0, $bx7SL$isVirtualPointerEvent)(e.nativeEvent)) { state.pointerType = "virtual"; return; } // Due to browser inconsistencies, especially on mobile browsers, we prevent // default on pointer down and handle focusing the pressable element ourselves. if ($f6c31cce2adf654f$var$shouldPreventDefault(e.currentTarget)) e.preventDefault(); state.pointerType = e.pointerType; let shouldStopPropagation = true; if (!state.isPressed) { state.isPressed = true; state.isOverTarget = true; state.activePointerId = e.pointerId; state.target = e.currentTarget; if (!isDisabled && !preventFocusOnPress) (0, $bx7SL$focusWithoutScrolling)(e.currentTarget); if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$16a4697467175487)(state.target); shouldStopPropagation = triggerPressStart(e, state.pointerType); addGlobalListener((0, $bx7SL$getOwnerDocument)(e.currentTarget), "pointermove", onPointerMove, false); addGlobalListener((0, $bx7SL$getOwnerDocument)(e.currentTarget), "pointerup", onPointerUp, false); addGlobalListener((0, $bx7SL$getOwnerDocument)(e.currentTarget), "pointercancel", onPointerCancel, false); } if (shouldStopPropagation) e.stopPropagation(); }; pressProps.onMouseDown = (e)=>{ if (!e.currentTarget.contains(e.target)) 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$shouldPreventDefault(e.currentTarget)) e.preventDefault(); e.stopPropagation(); } }; pressProps.onPointerUp = (e)=>{ // 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; // Only handle left clicks // Safari on iOS sometimes fires pointerup events, even // when the touch isn't over the target, so double check. if (e.button === 0 && $f6c31cce2adf654f$var$isOverTarget(e, e.currentTarget)) triggerPressUp(e, state.pointerType || e.pointerType); }; // Safari on iOS < 13.2 does not implement pointerenter/pointerleave events correctly. // Use pointer move events instead to implement our own hit testing. // See https://bugs.webkit.org/show_bug.cgi?id=199803 let onPointerMove = (e)=>{ if (e.pointerId !== state.activePointerId) return; if (state.target && $f6c31cce2adf654f$var$isOverTarget(e, state.target)) { if (!state.isOverTarget && state.pointerType != null) { state.isOverTarget = true; triggerPressStart($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType); } } else if (state.target && state.isOverTarget && state.pointerType != null) { state.isOverTarget = false; triggerPressEnd($f6c31cce2adf654f$var$createEvent(state.target, e), state.pointerType, false); cancelOnPointerExit(e); } }; let onPointerUp = (e)=>{ if (e.pointerId === state.activePointerId && state.isPressed && e.button === 0 && state.target) { if ($f6c31cce2adf654f$var$isOverTarget(e, state.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; state.isOverTarget = false; state.activePointerId = null; state.pointerType = null; removeAllGlobalListeners(); if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)(state.target); } }; let onPointerCancel = (e)=>{ cancel(e); }; pressProps.onDragStart = (e)=>{ if (!e.currentTarget.contains(e.target)) return; // Safari does not call onPointerCancel when a drag starts, whereas Chrome and Firefox do. cancel(e); }; } else { 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$shouldPreventDefault(e.currentTarget)) e.preventDefault(); if (state.ignoreEmulatedMouseEvents) { e.stopPropagation(); return; } state.isPressed = true; state.isOverTarget = true; state.target = e.currentTarget; state.pointerType = (0, $bx7SL$isVirtualClick)(e.nativeEvent) ? "virtual" : "mouse"; if (!isDisabled && !preventFocusOnPress) (0, $bx7SL$focusWithoutScrolling)(e.currentTarget); let shouldStopPropagation = triggerPressStart(e, state.pointerType); if (shouldStopPropagation) e.stopPropagation(); addGlobalListener((0, $bx7SL$getOwnerDocument)(e.currentTarget), "mouseup", onMouseUp, false); }; pressProps.onMouseEnter = (e)=>{ if (!e.currentTarget.contains(e.target)) return; let shouldStopPropagation = true; if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) { state.isOverTarget = true; shouldStopPropagation = triggerPressStart(e, state.pointerType); } if (shouldStopPropagation) e.stopPropagation(); }; pressProps.onMouseLeave = (e)=>{ if (!e.currentTarget.contains(e.target)) return; let shouldStopPropagation = true; if (state.isPressed && !state.ignoreEmulatedMouseEvents && state.pointerType != null) { state.isOverTarget = false; shouldStopPropagation = triggerPressEnd(e, state.pointerType, false); cancelOnPointerExit(e); } if (shouldStopPropagation) e.stopPropagation(); }; pressProps.onMouseUp = (e)=>{ if (!e.currentTarget.contains(e.target)) return; if (!state.ignoreEmulatedMouseEvents && e.button === 0) triggerPressUp(e, state.pointerType || "mouse"); }; let onMouseUp = (e)=>{ // Only handle left clicks if (e.button !== 0) return; state.isPressed = false; removeAllGlobalListeners(); if (state.ignoreEmulatedMouseEvents) { state.ignoreEmulatedMouseEvents = false; return; } 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); state.isOverTarget = false; }; pressProps.onTouchStart = (e)=>{ if (!e.currentTarget.contains(e.target)) return; let touch = $f6c31cce2adf654f$var$getTouchFromEvent(e.nativeEvent); if (!touch) return; state.activePointerId = touch.identifier; state.ignoreEmulatedMouseEvents = true; state.isOverTarget = true; state.isPressed = true; 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. if (!isDisabled && !preventFocusOnPress) (0, $bx7SL$focusWithoutScrolling)(e.currentTarget); if (!allowTextSelectionOnPress) (0, $14c0b72509d70225$export$16a4697467175487)(state.target); let shouldStopPropagation = triggerPressStart(e, state.pointerType); if (shouldStopPropagation) e.stopPropagation(); addGlobalListener((0, $bx7SL$getOwnerWindow)(e.currentTarget), "scroll", onScroll, true); }; pressProps.onTouchMove = (e)=>{ if (!e.currentTarget.contains(e.target)) return; if (!state.isPressed) { e.stopPropagation(); return; } let touch = $f6c31cce2adf654f$var$getTouchById(e.nativeEvent, state.activePointerId); let shouldStopPropagation = true; if (touch && $f6c31cce2adf654f$var$isOverTarget(touch, e.currentTarget)) { if (!state.isOverTarget && state.pointerType != null) { state.isOverTarget = true; shouldStopPropagation = triggerPressStart(e, state.pointerType); } } else if (state.isOverTarget && state.pointerType != null) { state.isOverTarget = false; shouldStopPropagation = triggerPressEnd(e, state.pointerType, false); cancelOnPointerExit(e); } if (shouldStopPropagation) e.stopPropagation(); }; pressProps.onTouchEnd = (e)=>{ if (!e.currentTarget.contains(e.target)) return; if (!state.isPressed) { e.stopPropagation(); return; } let touch = $f6c31cce2adf654f$var$getTouchById(e.nativeEvent, state.activePointerId); let shouldStopPropagation = true; if (touch && $f6c31cce2adf654f$var$isOverTarget(touch, e.currentTarget) && state.pointerType != null) { triggerPressUp(e, state.pointerType); shouldStopPropagation = triggerPressEnd(e, state.pointerType); } else if (state.isOverTarget && state.pointerType != null) shouldStopPropagation = triggerPressEnd(e, state.pointerType, false); if (shouldStopPropagation) e.stopPropagation(); state.isPressed = false; state.activePointerId = null; state.isOverTarget = false; state.ignoreEmulatedMouseEvents = true; if (state.target && !allowTextSelectionOnPress) (0, $14c0b72509d70225$export$b0d6fa1ab32e3295)(state.target); removeAllGlobalListeners(); }; pressProps.onTouchCancel = (e)=>{ if (!e.currentTarget.contains(e.target)) return; e.stopPropagation(); if (state.isPressed) cancel(e); }; let onScroll = (e)=>{ if (state.isPressed && e.target.contains(state.target)) cancel({ currentTarget: state.target, shiftKey: false, ctrlKey: false, metaKey: false, altKey: false }); }; pressProps.onDragStart = (e)=>{ if (!e.currentTarget.contains(e.target)) return; cancel(e); }; } return pressProps; }, [ addGlobalListener, isDisabled, preventFocusOnPress, removeAllGlobalListeners, allowTextSelectionOnPress, cancel, cancelOnPointerExit, triggerPressEnd, triggerPressStart, triggerPressUp ]); // Remove user-select: none in case component unmounts immediately after pressStart // eslint-disable-next-line arrow-body-style (0, $bx7SL$useEffect)(()=>{ 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); }; }, [ allowTextSelectionOnPress ]); return { isPressed: isPressedProp || isPressed, pressProps: (0, $bx7SL$mergeProps)(domProps, pressProps) }; } function $f6c31cce2adf654f$var$isHTMLAnchorLink(target) { return target.tagName === "A" && target.hasAttribute("href"); } function $f6c31cce2adf654f$var$isValidKeyboardEvent(event, currentTarget) { const { key: key, code: code } = event; const element = currentTarget; const role = element.getAttribute("role"); // Accessibility for keyboards. Space and Enter only. // "Spacebar" is for IE 11 return (key === "Enter" || key === " " || key === "Spacebar" || code === "Space") && !(element instanceof (0, $bx7SL$getOwnerWindow)(element).HTMLInputElement && !$f6c31cce2adf654f$var$isValidInputKey(element, key) || element instanceof (0, $bx7SL$getOwnerWindow)(element).HTMLTextAreaElement || element.isContentEditable) && // Links should only trigger with Enter key !((role === "link" || !role && $f6c31cce2adf654f$var$isHTMLAnchorLink(element)) && key !== "Enter"); } function $f6c31cce2adf654f$var$getTouchFromEvent(event) { const { targetTouches: targetTouches } = event; if (targetTouches.length > 0) return targetTouches[0]; return null; } function $f6c31cce2adf654f$var$getTouchById(event, pointerId) { const changedTouches = event.changedTouches; for(let i = 0; i < changedTouches.length; i++){ const touch = changedTouches[i]; if (touch.identifier === pointerId) return touch; } return null; } function $f6c31cce2adf654f$var$createEvent(target, e) { return { currentTarget: target, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey }; } function $f6c31cce2adf654f$var$getPointClientRect(point) { let offsetX = 0; let offsetY = 0; if (point.width !== undefined) offsetX = point.width / 2; else if (point.radiusX !== undefined) offsetX = point.radiusX; if (point.height !== undefined) offsetY = point.height / 2; else if (point.radiusY !== undefined) offsetY = point.radiusY; return { top: point.clientY - offsetY, right: point.clientX + offsetX, bottom: point.clientY + offsetY, left: point.clientX - offsetX }; } function $f6c31cce2adf654f$var$areRectanglesOverlapping(a, b) { // check if they cannot overlap on x axis if (a.left > b.right || b.left > a.right) return false; // check if they cannot overlap on y axis if (a.top > b.bottom || b.top > a.bottom) return false; return true; } function $f6c31cce2adf654f$var$isOverTarget(point, target) { let rect = target.getBoundingClientRect(); let pointRect = $f6c31cce2adf654f$var$getPointClientRect(point); return $f6c31cce2adf654f$var$areRectanglesOverlapping(rect, pointRect); } function $f6c31cce2adf654f$var$shouldPreventDefault(target) { // We cannot prevent default if the target is a draggable element. return !(target instanceof HTMLElement) || !target.hasAttribute("draggable"); } function $f6c31cce2adf654f$var$shouldPreventDefaultKeyboard(target, key) { if (target instanceof HTMLInputElement) return !$f6c31cce2adf654f$var$isValidInputKey(target, key); if (target instanceof HTMLButtonElement) return target.type !== "submit" && target.type !== "reset"; if ($f6c31cce2adf654f$var$isHTMLAnchorLink(target)) return false; return true; } const $f6c31cce2adf654f$var$nonTextInputTypes = new Set([ "checkbox", "radio", "range", "color", "file", "image", "button", "submit", "reset" ]); function $f6c31cce2adf654f$var$isValidInputKey(target, key) { // Only space should toggle checkboxes and radios, not enter. return target.type === "checkbox" || target.type === "radio" ? key === " " : $f6c31cce2adf654f$var$nonTextInputTypes.has(target.type); } const $3b117e43dc0ca95d$export$27c701ed9e449e99 = /*#__PURE__*/ (0, $bx7SL$react).forwardRef(({ children: children, ...props }, ref)=>{ ref = (0, $bx7SL$useObjectRef)(ref); let { pressProps: pressProps } = (0, $f6c31cce2adf654f$export$45712eceda6fad21)({ ...props, ref: ref }); let child = (0, $bx7SL$react).Children.only(children); return /*#__PURE__*/ (0, $bx7SL$react).cloneElement(child, // @ts-ignore { ref: ref, ...(0, $bx7SL$mergeProps)(child.props, pressProps) }); }); /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ const $f1ab8c75478c6f73$export$3351871ee4b288b8 = /*#__PURE__*/ (0, $bx7SL$react).forwardRef(({ children: children, ...props }, ref)=>{ let isRegistered = (0, $bx7SL$useRef)(false); let prevContext = (0, $bx7SL$useContext)((0, $ae1eeba8b9eafd08$export$5165eccb35aaadb5)); ref = (0, $bx7SL$useObjectRef)(ref || (prevContext === null || prevContext === void 0 ? void 0 : prevContext.ref)); let context = (0, $bx7SL$mergeProps)(prevContext || {}, { ...props, ref: ref, register () { isRegistered.current = true; if (prevContext) prevContext.register(); } }); (0, $bx7SL$useSyncRef)(prevContext, ref); (0, $bx7SL$useEffect)(()=>{ if (!isRegistered.current) { console.warn("A PressResponder was rendered without a pressable child. Either call the usePress hook, or wrap your DOM node with <Pressable> component."); isRegistered.current = true; // only warn once in strict mode. } }, []); return /*#__PURE__*/ (0, $bx7SL$react).createElement((0, $ae1eeba8b9eafd08$export$5165eccb35aaadb5).Provider, { value: context }, children); }); function $f1ab8c75478c6f73$export$cf75428e0b9ed1ea({ children: children }) { let context = (0, $bx7SL$useMemo)(()=>({ register: ()=>{} }), []); return /*#__PURE__*/ (0, $bx7SL$react).createElement((0, $ae1eeba8b9eafd08$export$5165eccb35aaadb5).Provider, { value: context }, children); } /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ // Portions of the code in this file are based on code from react. // Original licensing for the following can be found in the // NOTICE file in the root directory of this source tree. // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ class $8a9cb279dc87e130$export$905e7fc544a71f36 { isDefaultPrevented() { return this.nativeEvent.defaultPrevented; } preventDefault() { this.defaultPrevented = true; this.nativeEvent.preventDefault(); } stopPropagation() { this.nativeEvent.stopPropagation(); this.isPropagationStopped = ()=>true; } isPropagationStopped() { return false; } persist() {} constructor(type, nativeEvent){ this.nativeEvent = nativeEvent; this.target = nativeEvent.target; this.currentTarget = nativeEvent.currentTarget; this.relatedTarget = nativeEvent.relatedTarget; this.bubbles = nativeEvent.bubbles; this.cancelable = nativeEvent.cancelable; this.defaultPrevented = nativeEvent.defaultPrevented; this.eventPhase = nativeEvent.eventPhase; this.isTrusted = nativeEvent.isTrusted; this.timeStamp = nativeEvent.timeStamp; this.type = type; } } function $8a9cb279dc87e130$export$715c682d09d639cc(onBlur) { let stateRef = (0, $bx7SL$useRef)({ isFocused: false, observer: null }); // Clean up MutationObserver on unmount. See below. // eslint-disable-next-line arrow-body-style (0, $bx7SL$useLayoutEffect)(()=>{ const state = stateRef.current; return ()=>{ if (state.observer) { state.observer.disconnect(); state.observer = null; } }; }, []); let dispatchBlur = (0, $bx7SL$useEffectEvent)((e)=>{ onBlur === null || onBlur === void 0 ? void 0 : onBlur(e); }); // This function is called during a React onFocus event. return (0, $bx7SL$useCallback)((e)=>{ // React does not fire onBlur when an element is disabled. https://github.com/facebook/react/issues/9142 // Most browsers fire a native focusout event in this case, except for Firefox. In that case, we use a // MutationObserver to watch for the disabled attribute, and dispatch these events ourselves. // For browsers that do, focusout fires before the MutationObserver, so onBlur should not fire twice. if (e.target instanceof HTMLButtonElement || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement) { stateRef.current.isFocused = true; let target = e.target; let onBlurHandler = (e)=>{ stateRef.current.isFocused = false; if (target.disabled) // For backward compatibility, dispatch a (fake) React synthetic event. dispatchBlur(new $8a9cb279dc87e130$export$905e7fc544a71f36("blur", e)); // We no longer need the MutationObserver once the target is blurred. if (stateRef.current.observer) { stateRef.current.observer.disconnect(); stateRef.current.observer = null; } }; target.addEventListener("focusout", onBlurHandler, { once: true }); stateRef.current.observer = new MutationObserver(()=>{ if (stateRef.current.isFocused && target.disabled) { var _stateRef_current_observer; (_stateRef_current_observer = stateRef.current.observer) === null || _stateRef_current_observer === void 0 ? void 0 : _stateRef_current_observer.disconnect(); let relatedTargetEl = target === document.activeElement ? null : document.activeElement; target.dispatchEvent(new FocusEvent("blur", { relatedTarget: relatedTargetEl })); target.dispatchEvent(new FocusEvent("focusout", { bubbles: true, relatedTarget: relatedTargetEl })); } }); stateRef.current.observer.observe(target, { attributes: true, attributeFilter: [ "disabled" ] }); } }, [ dispatchBlur ]); } function $a1ea59d68270f0dd$export$f8168d8dd8fd66e6(props) { let { isDisabled: isDisabled, onFocus: onFocusProp, onBlur: onBlurProp, onFocusChange: onFocusChange } = props; const onBlur = (0, $bx7SL$useCallback)((e)=>{ if (e.target === e.currentTarget) { if (onBlurProp) onBlurProp(e); if (onFocusChange) onFocusChange(false); return true; } }, [ onBlurProp, onFocusChange ]); const onSyntheticFocus = (0, $8a9cb279dc87e130$export$715c682d09d639cc)(onBlur); const onFocus = (0, $bx7SL$useCallback)((e)=>{ // Double check that document.activeElement actually matches e.target in case a previously chained // focus handler already moved focus somewhere else. if (e.target === e.currentTarget && document.activeElement === e.target) { if (onFocusProp) onFocusProp(e); if (onFocusChange) onFocusChange(true); onSyntheticFocus(e); } }, [ onFocusChange, onFocusProp, onSyntheticFocus ]); return { focusProps: { onFocus: !isDisabled && (onFocusProp || onFocusChange || onBlurProp) ? onFocus : undefined, onBlur: !isDisabled && (onBlurProp || onFocusChange) ? onBlur : undefined } }; } /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ // Portions of the code in this file are based on code from react. // Original licensing for the following can be found in the // NOTICE file in the root directory of this source tree. // See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions let $507fabe10e71c6fb$var$currentModality = null; let $507fabe10e71c6fb$var$changeHandlers = new Set(); let $507fabe10e71c6fb$var$hasSetupGlobalListeners = false; let $507fabe10e71c6fb$var$hasEventBeforeFocus = false; let $507fabe10e71c6fb$var$hasBlurredWindowRecently = false; // Only Tab or Esc keys will make focus visible on text input elements const $507fabe10e71c6fb$var$FOCUS_VISIBLE_INPUT_KEYS = { Tab: true, Escape: true }; function $507fabe10e71c6fb$var$triggerChangeHandlers(modality, e) { for (let handler of $507fabe10e71c6fb$var$changeHandlers)handler(modality, e); } /** * Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible. */ function $507fabe10e71c6fb$var$isValidKey(e) { // Control and Shift keys trigger when navigating back to the tab with keyboard. return !(e.metaKey || !(0, $bx7SL$isMac)() && e.altKey || e.ctrlKey || e.key === "Control" || e.key === "Shift" || e.key === "Meta"); } function $507fabe10e71c6fb$var$handleKeyboardEvent(e) { $507fabe10e71c6fb$var$hasEventBeforeFocus = true; if ($507fabe10e71c6fb$var$isValidKey(e)) { $507fabe10e71c6fb$var$currentModality = "keyboard"; $507fabe10e71c6fb$var$triggerChangeHandlers("keyboard", e); } } function $507fabe10e71c6fb$var$handlePointerEvent(e) { $507fabe10e71c6fb$var$currentModality = "poin