New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@zag-js/interact-outside

Package Overview
Dependencies
Maintainers
0
Versions
829
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zag-js/interact-outside - npm Package Compare versions

Comparing version 0.0.0-dev-20240723090825 to 0.0.0-v1-beta-20250220125322

10

dist/index.d.ts

@@ -5,15 +5,15 @@ interface InteractOutsideHandlers {

*/
onPointerDownOutside?: (event: PointerDownOutsideEvent) => void;
onPointerDownOutside?: ((event: PointerDownOutsideEvent) => void) | undefined;
/**
* Function called when the focus is moved outside the component
*/
onFocusOutside?: (event: FocusOutsideEvent) => void;
onFocusOutside?: ((event: FocusOutsideEvent) => void) | undefined;
/**
* Function called when an interaction happens outside the component
*/
onInteractOutside?: (event: InteractOutsideEvent) => void;
onInteractOutside?: ((event: InteractOutsideEvent) => void) | undefined;
}
interface InteractOutsideOptions extends InteractOutsideHandlers {
exclude?: (target: HTMLElement) => boolean;
defer?: boolean;
exclude?: ((target: HTMLElement) => boolean) | undefined;
defer?: boolean | undefined;
}

@@ -20,0 +20,0 @@ interface EventDetails<T> {

@@ -1,32 +0,9 @@

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
'use strict';
var domQuery = require('@zag-js/dom-query');
var utils = require('@zag-js/utils');
// src/index.ts
var src_exports = {};
__export(src_exports, {
trackInteractOutside: () => trackInteractOutside
});
module.exports = __toCommonJS(src_exports);
var import_dom_event2 = require("@zag-js/dom-event");
var import_dom_query = require("@zag-js/dom-query");
var import_utils = require("@zag-js/utils");
// src/get-window-frames.ts
var import_dom_event = require("@zag-js/dom-event");
// src/frame-utils.ts
function getWindowFrames(win) {

@@ -40,17 +17,2 @@ const frames = {

},
queueBeforeEvent(event, listener) {
const cleanup = /* @__PURE__ */ new Set();
frames.each((frame) => {
try {
cleanup.add((0, import_dom_event.queueBeforeEvent)(frame.document, event, listener));
} catch {
}
});
return () => {
try {
cleanup.forEach((fn) => fn());
} catch {
}
};
},
addEventListener(event, listener, options) {

@@ -81,2 +43,25 @@ frames.each((frame) => {

}
function getParentWindow(win) {
const parent = win.frameElement != null ? win.parent : null;
return {
addEventListener: (event, listener, options) => {
try {
parent?.addEventListener(event, listener, options);
} catch {
}
return () => {
try {
parent?.removeEventListener(event, listener, options);
} catch {
}
};
},
removeEventListener: (event, listener, options) => {
try {
parent?.removeEventListener(event, listener, options);
} catch {
}
}
};
}

@@ -88,3 +73,3 @@ // src/index.ts

for (const node of composedPath) {
if ((0, import_dom_query.isHTMLElement)(node) && (0, import_dom_query.isFocusable)(node)) return true;
if (domQuery.isHTMLElement(node) && domQuery.isFocusable(node)) return true;
}

@@ -100,9 +85,22 @@ return false;

}
function isEventWithinScrollbar(event) {
const target = (0, import_dom_query.getEventTarget)(event);
if (!target || !isPointerEvent(event)) return false;
const isScrollableY = target.scrollHeight > target.clientHeight;
const onScrollbarY = isScrollableY && event.clientX > target.clientWidth;
const isScrollableX = target.scrollWidth > target.clientWidth;
const onScrollbarX = isScrollableX && event.clientY > target.clientHeight;
function isPointInRect(rect, point) {
return rect.y <= point.y && point.y <= rect.y + rect.height && rect.x <= point.x && point.x <= rect.x + rect.width;
}
function isEventWithinScrollbar(event, ancestor) {
if (!ancestor || !isPointerEvent(event)) return false;
const isScrollableY = ancestor.scrollHeight > ancestor.clientHeight;
const onScrollbarY = isScrollableY && event.clientX > ancestor.offsetLeft + ancestor.clientWidth;
const isScrollableX = ancestor.scrollWidth > ancestor.clientWidth;
const onScrollbarX = isScrollableX && event.clientY > ancestor.offsetTop + ancestor.clientHeight;
const rect = {
x: ancestor.offsetLeft,
y: ancestor.offsetTop,
width: ancestor.clientWidth + (isScrollableY ? 16 : 0),
height: ancestor.clientHeight + (isScrollableX ? 16 : 0)
};
const point = {
x: event.clientX,
y: event.clientY
};
if (!isPointInRect(rect, point)) return false;
return onScrollbarY || onScrollbarX;

@@ -113,11 +111,19 @@ }

if (!node) return;
const doc = (0, import_dom_query.getDocument)(node);
const win = (0, import_dom_query.getWindow)(node);
const doc = domQuery.getDocument(node);
const win = domQuery.getWindow(node);
const frames = getWindowFrames(win);
const parentWin = getParentWindow(win);
function isEventOutside(event) {
const target = (0, import_dom_query.getEventTarget)(event);
if (!(0, import_dom_query.isHTMLElement)(target)) return false;
if ((0, import_dom_query.contains)(node, target)) return false;
const target = domQuery.getEventTarget(event);
if (!domQuery.isHTMLElement(target)) return false;
if (!target.isConnected) return false;
if (domQuery.contains(node, target)) return false;
if (isEventPointWithin(node, event)) return false;
if (isEventWithinScrollbar(event)) return false;
const triggerEl = doc.querySelector(`[aria-controls="${node.id}"]`);
if (triggerEl) {
const triggerAncestor = domQuery.getNearestOverflowAncestor(triggerEl);
if (isEventWithinScrollbar(event, triggerAncestor)) return false;
}
const nodeAncestor = domQuery.getNearestOverflowAncestor(node);
if (isEventWithinScrollbar(event, nodeAncestor)) return false;
return !exclude?.(target);

@@ -128,3 +134,3 @@ }

function handler() {
const func = defer ? import_dom_query.raf : (v) => v();
const func = defer ? domQuery.raf : (v) => v();
const composedPath = event.composedPath?.() ?? [event.target];

@@ -134,6 +140,6 @@ func(() => {

if (onPointerDownOutside || onInteractOutside) {
const handler2 = (0, import_utils.callAll)(onPointerDownOutside, onInteractOutside);
const handler2 = utils.callAll(onPointerDownOutside, onInteractOutside);
node.addEventListener(POINTER_OUTSIDE_EVENT, handler2, { once: true });
}
(0, import_dom_event2.fireCustomEvent)(node, POINTER_OUTSIDE_EVENT, {
fireCustomEvent(node, POINTER_OUTSIDE_EVENT, {
bubbles: false,

@@ -143,3 +149,3 @@ cancelable: true,

originalEvent: event,
contextmenu: (0, import_dom_event2.isContextMenuEvent)(event),
contextmenu: domQuery.isContextMenuEvent(event),
focusable: isComposedPathFocusable(composedPath)

@@ -152,4 +158,5 @@ }

pointerdownCleanups.forEach((fn) => fn());
pointerdownCleanups.add((0, import_dom_event2.queueBeforeEvent)(doc, "pointerup", handler));
pointerdownCleanups.add(frames.queueBeforeEvent("pointerup", handler));
pointerdownCleanups.add(domQuery.addDomEvent(doc, "click", handler, { once: true }));
pointerdownCleanups.add(parentWin.addEventListener("click", handler, { once: true }));
pointerdownCleanups.add(frames.addEventListener("click", handler, { once: true }));
} else {

@@ -161,14 +168,15 @@ handler();

const timer = setTimeout(() => {
cleanups.add(domQuery.addDomEvent(doc, "pointerdown", onPointerDown, true));
cleanups.add(parentWin.addEventListener("pointerdown", onPointerDown, true));
cleanups.add(frames.addEventListener("pointerdown", onPointerDown, true));
cleanups.add((0, import_dom_event2.addDomEvent)(doc, "pointerdown", onPointerDown, true));
}, 0);
function onFocusin(event) {
const func = defer ? import_dom_query.raf : (v) => v();
const func = defer ? domQuery.raf : (v) => v();
func(() => {
if (!node || !isEventOutside(event)) return;
if (onFocusOutside || onInteractOutside) {
const handler = (0, import_utils.callAll)(onFocusOutside, onInteractOutside);
const handler = utils.callAll(onFocusOutside, onInteractOutside);
node.addEventListener(FOCUS_OUTSIDE_EVENT, handler, { once: true });
}
(0, import_dom_event2.fireCustomEvent)(node, FOCUS_OUTSIDE_EVENT, {
fireCustomEvent(node, FOCUS_OUTSIDE_EVENT, {
bubbles: false,

@@ -179,3 +187,3 @@ cancelable: true,

contextmenu: false,
focusable: (0, import_dom_query.isFocusable)((0, import_dom_query.getEventTarget)(event))
focusable: domQuery.isFocusable(domQuery.getEventTarget(event))
}

@@ -185,3 +193,4 @@ });

}
cleanups.add((0, import_dom_event2.addDomEvent)(doc, "focusin", onFocusin, true));
cleanups.add(domQuery.addDomEvent(doc, "focusin", onFocusin, true));
cleanups.add(parentWin.addEventListener("focusin", onFocusin, true));
cleanups.add(frames.addEventListener("focusin", onFocusin, true));

@@ -196,3 +205,3 @@ return () => {

const { defer } = options;
const func = defer ? import_dom_query.raf : (v) => v();
const func = defer ? domQuery.raf : (v) => v();
const cleanups = [];

@@ -209,6 +218,8 @@ cleanups.push(

}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
trackInteractOutside
});
//# sourceMappingURL=index.js.map
function fireCustomEvent(el, type, init) {
const win = el.ownerDocument.defaultView || window;
const event = new win.CustomEvent(type, init);
return el.dispatchEvent(event);
}
exports.trackInteractOutside = trackInteractOutside;
{
"name": "@zag-js/interact-outside",
"version": "0.0.0-dev-20240723090825",
"description": "Track interations or focus outside an element",
"version": "0.0.0-v1-beta-20250220125322",
"description": "Track interactions or focus outside an element",
"keywords": [

@@ -16,9 +16,7 @@ "js",

"files": [
"dist",
"src"
"dist"
],
"dependencies": {
"@zag-js/dom-query": "0.0.0-dev-20240723090825",
"@zag-js/dom-event": "0.0.0-dev-20240723090825",
"@zag-js/utils": "0.0.0-dev-20240723090825"
"@zag-js/dom-query": "0.0.0-v1-beta-20250220125322",
"@zag-js/utils": "0.0.0-v1-beta-20250220125322"
},

@@ -48,4 +46,4 @@ "devDependencies": {

"build": "tsup",
"test": "jest --config ../../../jest.config.js --rootDir tests",
"lint": "eslint src --ext .ts,.tsx",
"test": "vitest",
"lint": "eslint src",
"test-ci": "pnpm test --ci --runInBand -u",

@@ -52,0 +50,0 @@ "test-watch": "pnpm test --watchAll"

# @zag-js/interact-outside
Track interations or focus outside an element
Track interactions or focus outside an element

@@ -5,0 +5,0 @@ ## Installation

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc