@zag-js/interact-outside 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +40 -10
- package/dist/index.mjs +164 -0
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
trackInteractOutside: () => trackInteractOutside
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// ../dom/dist/index.mjs
|
|
2
28
|
var runIfFn = (v, ...a) => {
|
|
3
29
|
const res = typeof v === "function" ? v(...a) : v;
|
|
4
|
-
return res
|
|
30
|
+
return res != null ? res : void 0;
|
|
5
31
|
};
|
|
6
32
|
var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
7
33
|
var isDom = () => typeof window !== "undefined";
|
|
8
34
|
function getPlatform() {
|
|
35
|
+
var _a;
|
|
9
36
|
const agent = navigator.userAgentData;
|
|
10
|
-
return (agent == null ? void 0 : agent.platform)
|
|
37
|
+
return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
|
|
11
38
|
}
|
|
12
39
|
var pt = (v) => isDom() && v.test(getPlatform());
|
|
13
40
|
var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints;
|
|
@@ -19,18 +46,20 @@ function isWindow(value) {
|
|
|
19
46
|
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
20
47
|
}
|
|
21
48
|
function getDocument(el) {
|
|
49
|
+
var _a;
|
|
22
50
|
if (isWindow(el))
|
|
23
51
|
return el.document;
|
|
24
52
|
if (isDocument(el))
|
|
25
53
|
return el;
|
|
26
|
-
return (el == null ? void 0 : el.ownerDocument)
|
|
54
|
+
return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
|
|
27
55
|
}
|
|
28
56
|
function getWindow(el) {
|
|
29
|
-
|
|
57
|
+
var _a;
|
|
58
|
+
return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
|
|
30
59
|
}
|
|
31
60
|
function getEventTarget(event) {
|
|
32
|
-
var _a;
|
|
33
|
-
return ((_a = event.composedPath) == null ? void 0 : _a.call(event)[0])
|
|
61
|
+
var _a, _b;
|
|
62
|
+
return (_b = (_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) != null ? _b : event.target;
|
|
34
63
|
}
|
|
35
64
|
function contains(parent, child) {
|
|
36
65
|
if (!parent)
|
|
@@ -71,7 +100,7 @@ function addDomEvent(target, eventName, handler, options) {
|
|
|
71
100
|
};
|
|
72
101
|
}
|
|
73
102
|
|
|
74
|
-
// ../core/dist/index.
|
|
103
|
+
// ../core/dist/index.mjs
|
|
75
104
|
var callAll = (...fns) => (...a) => {
|
|
76
105
|
fns.forEach(function(fn) {
|
|
77
106
|
fn == null ? void 0 : fn(...a);
|
|
@@ -156,6 +185,7 @@ function trackInteractOutside(node, options) {
|
|
|
156
185
|
cleanups.forEach((fn) => fn());
|
|
157
186
|
};
|
|
158
187
|
}
|
|
159
|
-
export
|
|
188
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
189
|
+
0 && (module.exports = {
|
|
160
190
|
trackInteractOutside
|
|
161
|
-
};
|
|
191
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// ../dom/dist/index.mjs
|
|
2
|
+
var runIfFn = (v, ...a) => {
|
|
3
|
+
const res = typeof v === "function" ? v(...a) : v;
|
|
4
|
+
return res != null ? res : void 0;
|
|
5
|
+
};
|
|
6
|
+
var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
7
|
+
var isDom = () => typeof window !== "undefined";
|
|
8
|
+
function getPlatform() {
|
|
9
|
+
var _a;
|
|
10
|
+
const agent = navigator.userAgentData;
|
|
11
|
+
return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
|
|
12
|
+
}
|
|
13
|
+
var pt = (v) => isDom() && v.test(getPlatform());
|
|
14
|
+
var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints;
|
|
15
|
+
var isMac = () => pt(/^Mac/) && !isTouchDevice;
|
|
16
|
+
function isDocument(el) {
|
|
17
|
+
return el.nodeType === Node.DOCUMENT_NODE;
|
|
18
|
+
}
|
|
19
|
+
function isWindow(value) {
|
|
20
|
+
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
21
|
+
}
|
|
22
|
+
function getDocument(el) {
|
|
23
|
+
var _a;
|
|
24
|
+
if (isWindow(el))
|
|
25
|
+
return el.document;
|
|
26
|
+
if (isDocument(el))
|
|
27
|
+
return el;
|
|
28
|
+
return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
|
|
29
|
+
}
|
|
30
|
+
function getWindow(el) {
|
|
31
|
+
var _a;
|
|
32
|
+
return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
|
|
33
|
+
}
|
|
34
|
+
function getEventTarget(event) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
return (_b = (_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) != null ? _b : event.target;
|
|
37
|
+
}
|
|
38
|
+
function contains(parent, child) {
|
|
39
|
+
if (!parent)
|
|
40
|
+
return false;
|
|
41
|
+
return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
|
|
42
|
+
}
|
|
43
|
+
function isHTMLElement(v) {
|
|
44
|
+
return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
|
|
45
|
+
}
|
|
46
|
+
function isVisible(el) {
|
|
47
|
+
if (!isHTMLElement(el))
|
|
48
|
+
return false;
|
|
49
|
+
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
|
|
50
|
+
}
|
|
51
|
+
var isContextMenuEvent = (e) => {
|
|
52
|
+
return e.button === 2 || isCtrlKey(e) && e.button === 0;
|
|
53
|
+
};
|
|
54
|
+
var isCtrlKey = (v) => isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey;
|
|
55
|
+
function fireCustomEvent(el, type, init) {
|
|
56
|
+
if (!el)
|
|
57
|
+
return;
|
|
58
|
+
const win = getWindow(el);
|
|
59
|
+
const event = new win.CustomEvent(type, init);
|
|
60
|
+
return el.dispatchEvent(event);
|
|
61
|
+
}
|
|
62
|
+
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";
|
|
63
|
+
function isFocusable(element) {
|
|
64
|
+
if (!element)
|
|
65
|
+
return false;
|
|
66
|
+
return element.matches(focusableSelector) && isVisible(element);
|
|
67
|
+
}
|
|
68
|
+
var isRef = (v) => hasProp(v, "current");
|
|
69
|
+
function addDomEvent(target, eventName, handler, options) {
|
|
70
|
+
const node = isRef(target) ? target.current : runIfFn(target);
|
|
71
|
+
node == null ? void 0 : node.addEventListener(eventName, handler, options);
|
|
72
|
+
return () => {
|
|
73
|
+
node == null ? void 0 : node.removeEventListener(eventName, handler, options);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ../core/dist/index.mjs
|
|
78
|
+
var callAll = (...fns) => (...a) => {
|
|
79
|
+
fns.forEach(function(fn) {
|
|
80
|
+
fn == null ? void 0 : fn(...a);
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// src/index.ts
|
|
85
|
+
var POINTER_OUTSIDE_EVENT = "pointerdown.outside";
|
|
86
|
+
var FOCUS_OUTSIDE_EVENT = "focus.outside";
|
|
87
|
+
function trackInteractOutside(node, options) {
|
|
88
|
+
const { exclude, onFocusOutside, onPointerDownOutside, onInteractOutside } = options;
|
|
89
|
+
if (!node)
|
|
90
|
+
return;
|
|
91
|
+
const doc = getDocument(node);
|
|
92
|
+
const win = getWindow(node);
|
|
93
|
+
function isEventOutside(event) {
|
|
94
|
+
const target = getEventTarget(event);
|
|
95
|
+
if (!(target instanceof win.HTMLElement)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (!contains(doc.documentElement, target)) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (contains(node, target)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return !(exclude == null ? void 0 : exclude(target));
|
|
105
|
+
}
|
|
106
|
+
let clickHandler;
|
|
107
|
+
function onPointerDown(event) {
|
|
108
|
+
function handler() {
|
|
109
|
+
if (!node || !isEventOutside(event))
|
|
110
|
+
return;
|
|
111
|
+
if (onPointerDownOutside || onInteractOutside) {
|
|
112
|
+
const handler2 = callAll(onPointerDownOutside, onInteractOutside);
|
|
113
|
+
node.addEventListener(POINTER_OUTSIDE_EVENT, handler2, { once: true });
|
|
114
|
+
}
|
|
115
|
+
fireCustomEvent(node, POINTER_OUTSIDE_EVENT, {
|
|
116
|
+
bubbles: false,
|
|
117
|
+
cancelable: true,
|
|
118
|
+
detail: {
|
|
119
|
+
originalEvent: event,
|
|
120
|
+
contextmenu: isContextMenuEvent(event),
|
|
121
|
+
focusable: isFocusable(getEventTarget(event))
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if (event.pointerType === "touch") {
|
|
126
|
+
doc.removeEventListener("click", handler);
|
|
127
|
+
clickHandler = handler;
|
|
128
|
+
doc.addEventListener("click", handler, { once: true });
|
|
129
|
+
} else {
|
|
130
|
+
handler();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
134
|
+
const timer = setTimeout(() => {
|
|
135
|
+
cleanups.add(addDomEvent(doc, "pointerdown", onPointerDown, true));
|
|
136
|
+
}, 0);
|
|
137
|
+
function onFocusin(event) {
|
|
138
|
+
if (!node || !isEventOutside(event))
|
|
139
|
+
return;
|
|
140
|
+
if (onFocusOutside || onInteractOutside) {
|
|
141
|
+
const handler = callAll(onFocusOutside, onInteractOutside);
|
|
142
|
+
node.addEventListener(FOCUS_OUTSIDE_EVENT, handler, { once: true });
|
|
143
|
+
}
|
|
144
|
+
fireCustomEvent(node, FOCUS_OUTSIDE_EVENT, {
|
|
145
|
+
bubbles: false,
|
|
146
|
+
cancelable: true,
|
|
147
|
+
detail: {
|
|
148
|
+
originalEvent: event,
|
|
149
|
+
contextmenu: false,
|
|
150
|
+
focusable: isFocusable(getEventTarget(event))
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
cleanups.add(addDomEvent(doc, "focusin", onFocusin, true));
|
|
155
|
+
return () => {
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
if (clickHandler)
|
|
158
|
+
doc.removeEventListener("click", clickHandler);
|
|
159
|
+
cleanups.forEach((fn) => fn());
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
export {
|
|
163
|
+
trackInteractOutside
|
|
164
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"type": "module",
|
|
3
2
|
"name": "@zag-js/interact-outside",
|
|
4
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
5
4
|
"description": "Track interations or focus outside an element",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
6
8
|
"keywords": [
|
|
7
9
|
"js",
|
|
8
10
|
"utils",
|
|
@@ -11,16 +13,14 @@
|
|
|
11
13
|
"author": "Segun Adebayo <sage@adebayosegun.com>",
|
|
12
14
|
"homepage": "https://github.com/chakra-ui/zag#readme",
|
|
13
15
|
"license": "MIT",
|
|
14
|
-
"main": "dist/index.js",
|
|
15
|
-
"types": "dist/index.d.ts",
|
|
16
16
|
"repository": "https://github.com/chakra-ui/zag/tree/main/packages/utilities/interact-outside",
|
|
17
17
|
"sideEffects": false,
|
|
18
18
|
"files": [
|
|
19
19
|
"dist/**/*"
|
|
20
20
|
],
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@zag-js/dom-utils": "0.
|
|
23
|
-
"@zag-js/utils": "0.
|
|
22
|
+
"@zag-js/dom-utils": "0.2.0",
|
|
23
|
+
"@zag-js/utils": "0.2.0"
|
|
24
24
|
},
|
|
25
25
|
"publishConfig": {
|
|
26
26
|
"access": "public"
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build-fast": "tsup src/index.ts --format=esm",
|
|
32
|
+
"build-fast": "tsup src/index.ts --format=esm,cjs",
|
|
33
33
|
"start": "pnpm build --watch",
|
|
34
|
-
"build": "tsup src/index.ts --format=esm --dts",
|
|
34
|
+
"build": "tsup src/index.ts --format=esm,cjs --dts",
|
|
35
35
|
"test": "jest --config ../../../jest.config.js --rootDir tests",
|
|
36
36
|
"lint": "eslint src --ext .ts,.tsx",
|
|
37
37
|
"test-ci": "pnpm test --ci --runInBand -u",
|