UNPKG

@clayui/shared

Version:
101 lines (100 loc) 3.3 kB
import { useEffect, useRef } from "react"; function useInteractOutside({ isDisabled = false, onInteract, onInteractStart, ref, triggerRef }) { const stateRef = useRef({ ignoreEmulatedMouseEvents: false, isPointerDown: false, onInteract }); const state = stateRef.current; state.onInteract = onInteract; useEffect(() => { if (isDisabled) { return; } const onPointerDown = (event) => { if (isValidEvent(event, ref, triggerRef) && state.onInteract) { if (onInteractStart) { onInteractStart(event); } state.isPointerDown = true; } }; const onBlur = (event) => { if (state.onInteract && event.view === void 0) { state.onInteract(event); } }; if (typeof PointerEvent !== "undefined") { const onPointerUp = (event) => { if (state.isPointerDown && state.onInteract && isValidEvent(event, ref, triggerRef)) { state.isPointerDown = false; state.onInteract(event); } }; document.addEventListener("pointerdown", onPointerDown, true); document.addEventListener("pointerup", onPointerUp, true); window.addEventListener("blur", onBlur, true); return () => { document.removeEventListener( "pointerdown", onPointerDown, true ); document.removeEventListener("pointerup", onPointerUp, true); window.removeEventListener("blur", onBlur, true); }; } else { const onMouseUp = (event) => { if (state.ignoreEmulatedMouseEvents) { state.ignoreEmulatedMouseEvents = false; } else if (state.isPointerDown && state.onInteract && isValidEvent(event, ref, triggerRef)) { state.isPointerDown = false; state.onInteract(event); } }; const onTouchEnd = (event) => { state.ignoreEmulatedMouseEvents = true; if (state.onInteract && state.isPointerDown && isValidEvent(event, ref, triggerRef)) { state.isPointerDown = false; state.onInteract(event); } }; document.addEventListener("mousedown", onPointerDown, true); document.addEventListener("mouseup", onMouseUp, true); document.addEventListener("touchstart", onPointerDown, true); document.addEventListener("touchend", onTouchEnd, true); window.addEventListener("blur", onBlur, true); return () => { document.removeEventListener("mousedown", onPointerDown, true); document.removeEventListener("mouseup", onMouseUp, true); document.removeEventListener("touchstart", onPointerDown, true); document.removeEventListener("touchend", onTouchEnd, true); window.removeEventListener("blur", onBlur, true); }; } }, [ref, state, isDisabled]); } function isValidEvent(event, ref, trigger) { if (event.button > 0) { return false; } if (event.target) { const ownerDocument = event.target.ownerDocument; if (!ownerDocument || !ownerDocument.documentElement.contains(event.target)) { return false; } } if (trigger.current && trigger.current.contains(event.target)) { return false; } return ref.current && !ref.current.contains(event.target); } export { useInteractOutside };