UNPKG

4.93 kBJavaScriptView Raw
1import {useEffectEvent as $ispOf$useEffectEvent, getOwnerDocument as $ispOf$getOwnerDocument} from "@react-aria/utils";
2import {useRef as $ispOf$useRef, useEffect as $ispOf$useEffect} from "react";
3
4/*
5 * Copyright 2020 Adobe. All rights reserved.
6 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License. You may obtain a copy
8 * of the License at http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software distributed under
11 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
12 * OF ANY KIND, either express or implied. See the License for the specific language
13 * governing permissions and limitations under the License.
14 */ // Portions of the code in this file are based on code from react.
15// Original licensing for the following can be found in the
16// NOTICE file in the root directory of this source tree.
17// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
18
19
20function $e0b6e0b68ec7f50f$export$872b660ac5a1ff98(props) {
21 let { ref: ref, onInteractOutside: onInteractOutside, isDisabled: isDisabled, onInteractOutsideStart: onInteractOutsideStart } = props;
22 let stateRef = (0, $ispOf$useRef)({
23 isPointerDown: false,
24 ignoreEmulatedMouseEvents: false
25 });
26 let onPointerDown = (0, $ispOf$useEffectEvent)((e)=>{
27 if (onInteractOutside && $e0b6e0b68ec7f50f$var$isValidEvent(e, ref)) {
28 if (onInteractOutsideStart) onInteractOutsideStart(e);
29 stateRef.current.isPointerDown = true;
30 }
31 });
32 let triggerInteractOutside = (0, $ispOf$useEffectEvent)((e)=>{
33 if (onInteractOutside) onInteractOutside(e);
34 });
35 (0, $ispOf$useEffect)(()=>{
36 let state = stateRef.current;
37 if (isDisabled) return;
38 const element = ref.current;
39 const documentObject = (0, $ispOf$getOwnerDocument)(element);
40 // Use pointer events if available. Otherwise, fall back to mouse and touch events.
41 if (typeof PointerEvent !== 'undefined') {
42 let onPointerUp = (e)=>{
43 if (state.isPointerDown && $e0b6e0b68ec7f50f$var$isValidEvent(e, ref)) triggerInteractOutside(e);
44 state.isPointerDown = false;
45 };
46 // changing these to capture phase fixed combobox
47 documentObject.addEventListener('pointerdown', onPointerDown, true);
48 documentObject.addEventListener('pointerup', onPointerUp, true);
49 return ()=>{
50 documentObject.removeEventListener('pointerdown', onPointerDown, true);
51 documentObject.removeEventListener('pointerup', onPointerUp, true);
52 };
53 } else {
54 let onMouseUp = (e)=>{
55 if (state.ignoreEmulatedMouseEvents) state.ignoreEmulatedMouseEvents = false;
56 else if (state.isPointerDown && $e0b6e0b68ec7f50f$var$isValidEvent(e, ref)) triggerInteractOutside(e);
57 state.isPointerDown = false;
58 };
59 let onTouchEnd = (e)=>{
60 state.ignoreEmulatedMouseEvents = true;
61 if (state.isPointerDown && $e0b6e0b68ec7f50f$var$isValidEvent(e, ref)) triggerInteractOutside(e);
62 state.isPointerDown = false;
63 };
64 documentObject.addEventListener('mousedown', onPointerDown, true);
65 documentObject.addEventListener('mouseup', onMouseUp, true);
66 documentObject.addEventListener('touchstart', onPointerDown, true);
67 documentObject.addEventListener('touchend', onTouchEnd, true);
68 return ()=>{
69 documentObject.removeEventListener('mousedown', onPointerDown, true);
70 documentObject.removeEventListener('mouseup', onMouseUp, true);
71 documentObject.removeEventListener('touchstart', onPointerDown, true);
72 documentObject.removeEventListener('touchend', onTouchEnd, true);
73 };
74 }
75 }, [
76 ref,
77 isDisabled,
78 onPointerDown,
79 triggerInteractOutside
80 ]);
81}
82function $e0b6e0b68ec7f50f$var$isValidEvent(event, ref) {
83 if (event.button > 0) return false;
84 if (event.target) {
85 // if the event target is no longer in the document, ignore
86 const ownerDocument = event.target.ownerDocument;
87 if (!ownerDocument || !ownerDocument.documentElement.contains(event.target)) return false;
88 // If the target is within a top layer element (e.g. toasts), ignore.
89 if (event.target.closest('[data-react-aria-top-layer]')) return false;
90 }
91 return ref.current && !ref.current.contains(event.target);
92}
93
94
95export {$e0b6e0b68ec7f50f$export$872b660ac5a1ff98 as useInteractOutside};
96//# sourceMappingURL=useInteractOutside.module.js.map