UNPKG

web-ui-pack

Version:
48 lines (47 loc) 1.61 kB
import onEvent from "./onEvent"; let isMouseDown = false; let rstEvent; let rstCnt = 0; const onMouseUp = []; function setEvent() { ++rstCnt; if (rstEvent) { return; } const r1 = onEvent(document, "mousedown", ({ button, defaultPrevented }) => (isMouseDown = !button && !defaultPrevented), { passive: true, capture: true }); const r2 = onEvent(document, "click", () => { onMouseUp.forEach((f) => f()); onMouseUp.length = 0; isMouseDown = false; }, { passive: true, capture: true }); rstEvent = () => { if (--rstCnt === 0) { onMouseUp.length = 0; isMouseDown = false; r1(); r2(); rstEvent = undefined; } }; } export default function onFocusLost(element, listener, options) { setEvent(); const remove = () => { element.removeEventListener("focusout", focusout); rstEvent?.call(element); }; const focusout = (e, isNext) => { if (!isNext && isMouseDown) { onMouseUp.push(() => setTimeout(() => focusout(e, true), options?.debounceMs || 100)); return; } const isFocused = (a) => a && (element === a || element.contains(a)); const isStillFocused = e.relatedTarget instanceof Node && isFocused(e.relatedTarget); if (!isStillFocused && !isFocused(document.activeElement)) { listener.call(element, e); options?.once && remove(); } }; element.addEventListener("focusout", focusout, { passive: true, ...options, once: false }); return remove; }