@zag-js/interact-outside
Advanced tools
Comparing version 0.0.0-dev-20220628115342 to 0.0.0-dev-20220703123907
@@ -1,6 +0,17 @@ | ||
export declare type InteractOutsideOptions = { | ||
export declare type InteractOutsideHandlers = { | ||
onPointerDownOutside?: (event: PointerDownOutsideEvent) => void; | ||
onFocusOutside?: (event: FocusOutsideEvent) => void; | ||
}; | ||
export declare type InteractOutsideOptions = InteractOutsideHandlers & { | ||
exclude?: (target: HTMLElement) => boolean; | ||
onPointerDownOutside?: (event: Event) => void; | ||
onFocusOutside?: (event: Event) => void; | ||
}; | ||
declare type EventDetails<T> = { | ||
originalEvent: T; | ||
contextmenu: boolean; | ||
focusable: boolean; | ||
}; | ||
export declare type PointerDownOutsideEvent = CustomEvent<EventDetails<PointerEvent>>; | ||
export declare type FocusOutsideEvent = CustomEvent<EventDetails<FocusEvent>>; | ||
export declare type InteractOutsideEvent = PointerDownOutsideEvent | FocusOutsideEvent; | ||
export declare function trackInteractOutside(node: HTMLElement | null, options: InteractOutsideOptions): () => void; | ||
export {}; |
@@ -44,3 +44,3 @@ "use strict"; | ||
} | ||
function getOwnerDocument(el) { | ||
function getDocument(el) { | ||
var _a; | ||
@@ -51,3 +51,3 @@ if (isWindow(el)) | ||
} | ||
function getOwnerWindow(el) { | ||
function getWindow(el) { | ||
var _a; | ||
@@ -68,10 +68,44 @@ return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window; | ||
} | ||
function isVisible(el) { | ||
if (!isHTMLElement(el)) | ||
return false; | ||
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0; | ||
} | ||
function fireCustomEvent(el, type, init) { | ||
if (!el) | ||
return; | ||
const event = new CustomEvent(type, init); | ||
return el.dispatchEvent(event); | ||
} | ||
var focusableSelector = "input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], button:not([disabled]), [tabindex], iframe, object, embed, area[href], audio[controls], video[controls], [contenteditable]:not([contenteditable='false']), details > summary:first-of-type"; | ||
function isFocusable(element) { | ||
if (!element) | ||
return false; | ||
return element.matches(focusableSelector) && isVisible(element); | ||
} | ||
// ../core/dist/index.mjs | ||
var isDom = () => typeof window !== "undefined"; | ||
function getPlatform() { | ||
var _a; | ||
const agent = navigator.userAgentData; | ||
return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform; | ||
} | ||
var pt = (v) => isDom() && v.test(getPlatform()); | ||
var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints; | ||
var isMac = () => pt(/^Mac/) && !isTouchDevice; | ||
var isContextMenuEvent = (e) => { | ||
return e.button === 2 || isCtrlKey(e) && e.button === 0; | ||
}; | ||
var isCtrlKey = (v) => isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey; | ||
// src/index.ts | ||
var POINTER_OUTSIDE_EVENT = "pointerdown.outside"; | ||
var FOCUS_OUTSIDE_EVENT = "focus.outside"; | ||
function trackInteractOutside(node, options) { | ||
const { exclude, onPointerDownOutside, onFocusOutside } = options; | ||
const { exclude, onFocusOutside, onPointerDownOutside } = options; | ||
if (!node) | ||
return; | ||
const doc = getOwnerDocument(node); | ||
const win = getOwnerWindow(node); | ||
const doc = getDocument(node); | ||
const win = getWindow(node); | ||
function isEventOutside(event) { | ||
@@ -82,4 +116,3 @@ const target = getEventTarget(event); | ||
} | ||
const doc2 = target.ownerDocument; | ||
if (!contains(doc2.documentElement, target)) { | ||
if (!contains(doc.documentElement, target)) { | ||
return false; | ||
@@ -92,6 +125,27 @@ } | ||
} | ||
let clickHandler; | ||
function onPointerDown(event) { | ||
if (isEventOutside(event)) { | ||
onPointerDownOutside == null ? void 0 : onPointerDownOutside(event); | ||
function handler() { | ||
if (!node || !isEventOutside(event)) | ||
return; | ||
if (onPointerDownOutside) { | ||
node.addEventListener(POINTER_OUTSIDE_EVENT, onPointerDownOutside, { once: true }); | ||
} | ||
fireCustomEvent(node, POINTER_OUTSIDE_EVENT, { | ||
bubbles: false, | ||
cancelable: true, | ||
detail: { | ||
originalEvent: event, | ||
contextmenu: isContextMenuEvent(event), | ||
focusable: isFocusable(getEventTarget(event)) | ||
} | ||
}); | ||
} | ||
if (event.pointerType === "touch") { | ||
doc.removeEventListener("click", handler); | ||
clickHandler = handler; | ||
doc.addEventListener("click", handler, { once: true }); | ||
} else { | ||
handler(); | ||
} | ||
} | ||
@@ -101,7 +155,18 @@ const cleanups = /* @__PURE__ */ new Set(); | ||
cleanups.add(addDomEvent(doc, "pointerdown", onPointerDown, true)); | ||
}); | ||
}, 0); | ||
function onFocusin(event) { | ||
if (isEventOutside(event)) { | ||
onFocusOutside == null ? void 0 : onFocusOutside(event); | ||
if (!node || !isEventOutside(event)) | ||
return; | ||
if (onFocusOutside) { | ||
node.addEventListener(FOCUS_OUTSIDE_EVENT, onFocusOutside, { once: true }); | ||
} | ||
fireCustomEvent(node, FOCUS_OUTSIDE_EVENT, { | ||
bubbles: false, | ||
cancelable: true, | ||
detail: { | ||
originalEvent: event, | ||
contextmenu: false, | ||
focusable: isFocusable(getEventTarget(event)) | ||
} | ||
}); | ||
} | ||
@@ -111,4 +176,6 @@ cleanups.add(addDomEvent(doc, "focusin", onFocusin, true)); | ||
clearTimeout(timer); | ||
if (clickHandler) | ||
doc.removeEventListener("click", clickHandler); | ||
cleanups.forEach((fn) => fn()); | ||
}; | ||
} |
{ | ||
"name": "@zag-js/interact-outside", | ||
"version": "0.0.0-dev-20220628115342", | ||
"version": "0.0.0-dev-20220703123907", | ||
"description": "Track interations or focus outside an element", | ||
@@ -31,3 +31,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@zag-js/dom-utils": "0.0.0-dev-20220628115342" | ||
"@zag-js/dom-utils": "0.0.0-dev-20220703123907" | ||
}, | ||
@@ -34,0 +34,0 @@ "publishConfig": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13560
339
+ Added@zag-js/dom-utils@0.0.0-dev-20220703123907(transitive)
+ Added@zag-js/types@0.0.0-dev-20220703123907(transitive)
- Removed@zag-js/dom-utils@0.0.0-dev-20220628115342(transitive)
- Removed@zag-js/types@0.0.0-dev-20220628115342(transitive)