@zag-js/interact-outside 0.2.1 → 0.2.3
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/chunk-XJMPFMOP.mjs +30 -0
- package/dist/get-window-frames.d.ts +7 -0
- package/dist/get-window-frames.js +54 -0
- package/dist/get-window-frames.mjs +6 -0
- package/dist/index.js +51 -111
- package/dist/index.mjs +17 -100
- package/package.json +8 -4
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/get-window-frames.ts
|
|
2
|
+
function getWindowFrames(win) {
|
|
3
|
+
const frames = {
|
|
4
|
+
each(cb) {
|
|
5
|
+
for (let i = 0; i < win.frames?.length; i += 1) {
|
|
6
|
+
const frame = win.frames[i];
|
|
7
|
+
if (frame)
|
|
8
|
+
cb(frame);
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
addEventListener(event, listener, options) {
|
|
12
|
+
frames.each((frame) => {
|
|
13
|
+
frame.document.addEventListener(event, listener, options);
|
|
14
|
+
});
|
|
15
|
+
return () => {
|
|
16
|
+
frames.removeEventListener(event, listener, options);
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
removeEventListener(event, listener, options) {
|
|
20
|
+
frames.each((frame) => {
|
|
21
|
+
frame.document.removeEventListener(event, listener, options);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return frames;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
getWindowFrames
|
|
30
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare function getWindowFrames(win: Window): {
|
|
2
|
+
each(cb: (win: Window) => void): void;
|
|
3
|
+
addEventListener(event: string, listener: any, options?: any): () => void;
|
|
4
|
+
removeEventListener(event: string, listener: any, options?: any): void;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export { getWindowFrames };
|
|
@@ -0,0 +1,54 @@
|
|
|
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/get-window-frames.ts
|
|
21
|
+
var get_window_frames_exports = {};
|
|
22
|
+
__export(get_window_frames_exports, {
|
|
23
|
+
getWindowFrames: () => getWindowFrames
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(get_window_frames_exports);
|
|
26
|
+
function getWindowFrames(win) {
|
|
27
|
+
const frames = {
|
|
28
|
+
each(cb) {
|
|
29
|
+
for (let i = 0; i < win.frames?.length; i += 1) {
|
|
30
|
+
const frame = win.frames[i];
|
|
31
|
+
if (frame)
|
|
32
|
+
cb(frame);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
addEventListener(event, listener, options) {
|
|
36
|
+
frames.each((frame) => {
|
|
37
|
+
frame.document.addEventListener(event, listener, options);
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
frames.removeEventListener(event, listener, options);
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
removeEventListener(event, listener, options) {
|
|
44
|
+
frames.each((frame) => {
|
|
45
|
+
frame.document.removeEventListener(event, listener, options);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return frames;
|
|
50
|
+
}
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
getWindowFrames
|
|
54
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -23,100 +23,36 @@ __export(src_exports, {
|
|
|
23
23
|
trackInteractOutside: () => trackInteractOutside
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
var import_dom_event = require("@zag-js/dom-event");
|
|
27
|
+
var import_dom_query = require("@zag-js/dom-query");
|
|
28
|
+
var import_tabbable = require("@zag-js/tabbable");
|
|
29
|
+
var import_utils = require("@zag-js/utils");
|
|
26
30
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
var isMac = () => pt(/^Mac/) && !isTouchDevice;
|
|
51
|
-
|
|
52
|
-
// ../dom/src/query.ts
|
|
53
|
-
function isDocument(el) {
|
|
54
|
-
return el.nodeType === Node.DOCUMENT_NODE;
|
|
55
|
-
}
|
|
56
|
-
function isWindow(value) {
|
|
57
|
-
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
58
|
-
}
|
|
59
|
-
function getDocument(el) {
|
|
60
|
-
var _a;
|
|
61
|
-
if (isWindow(el))
|
|
62
|
-
return el.document;
|
|
63
|
-
if (isDocument(el))
|
|
64
|
-
return el;
|
|
65
|
-
return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
|
|
66
|
-
}
|
|
67
|
-
function getWindow(el) {
|
|
68
|
-
var _a;
|
|
69
|
-
return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
|
|
70
|
-
}
|
|
71
|
-
function getEventTarget(event) {
|
|
72
|
-
var _a, _b;
|
|
73
|
-
return (_b = (_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) != null ? _b : event.target;
|
|
74
|
-
}
|
|
75
|
-
function contains(parent, child) {
|
|
76
|
-
if (!parent)
|
|
77
|
-
return false;
|
|
78
|
-
return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
|
|
79
|
-
}
|
|
80
|
-
function isHTMLElement(v) {
|
|
81
|
-
return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
|
|
82
|
-
}
|
|
83
|
-
function isVisible(el) {
|
|
84
|
-
if (!isHTMLElement(el))
|
|
85
|
-
return false;
|
|
86
|
-
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ../dom/src/event.ts
|
|
90
|
-
var isContextMenuEvent = (e) => {
|
|
91
|
-
return e.button === 2 || isCtrlKey(e) && e.button === 0;
|
|
92
|
-
};
|
|
93
|
-
var isCtrlKey = (v) => isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey;
|
|
94
|
-
|
|
95
|
-
// ../dom/src/fire-event.ts
|
|
96
|
-
function fireCustomEvent(el, type, init) {
|
|
97
|
-
if (!el)
|
|
98
|
-
return;
|
|
99
|
-
const win = getWindow(el);
|
|
100
|
-
const event = new win.CustomEvent(type, init);
|
|
101
|
-
return el.dispatchEvent(event);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ../dom/src/focusable.ts
|
|
105
|
-
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";
|
|
106
|
-
function isFocusable(element) {
|
|
107
|
-
if (!element)
|
|
108
|
-
return false;
|
|
109
|
-
return element.matches(focusableSelector) && isVisible(element);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// ../dom/src/listener.ts
|
|
113
|
-
var isRef = (v) => hasProp(v, "current");
|
|
114
|
-
function addDomEvent(target, eventName, handler, options) {
|
|
115
|
-
const node = isRef(target) ? target.current : runIfFn(target);
|
|
116
|
-
node == null ? void 0 : node.addEventListener(eventName, handler, options);
|
|
117
|
-
return () => {
|
|
118
|
-
node == null ? void 0 : node.removeEventListener(eventName, handler, options);
|
|
31
|
+
// src/get-window-frames.ts
|
|
32
|
+
function getWindowFrames(win) {
|
|
33
|
+
const frames = {
|
|
34
|
+
each(cb) {
|
|
35
|
+
for (let i = 0; i < win.frames?.length; i += 1) {
|
|
36
|
+
const frame = win.frames[i];
|
|
37
|
+
if (frame)
|
|
38
|
+
cb(frame);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
addEventListener(event, listener, options) {
|
|
42
|
+
frames.each((frame) => {
|
|
43
|
+
frame.document.addEventListener(event, listener, options);
|
|
44
|
+
});
|
|
45
|
+
return () => {
|
|
46
|
+
frames.removeEventListener(event, listener, options);
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
removeEventListener(event, listener, options) {
|
|
50
|
+
frames.each((frame) => {
|
|
51
|
+
frame.document.removeEventListener(event, listener, options);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
119
54
|
};
|
|
55
|
+
return frames;
|
|
120
56
|
}
|
|
121
57
|
|
|
122
58
|
// src/index.ts
|
|
@@ -126,20 +62,18 @@ function trackInteractOutside(node, options) {
|
|
|
126
62
|
const { exclude, onFocusOutside, onPointerDownOutside, onInteractOutside } = options;
|
|
127
63
|
if (!node)
|
|
128
64
|
return;
|
|
129
|
-
const doc = getDocument(node);
|
|
130
|
-
const win = getWindow(node);
|
|
65
|
+
const doc = (0, import_dom_query.getDocument)(node);
|
|
66
|
+
const win = (0, import_dom_query.getWindow)(node);
|
|
67
|
+
const frames = getWindowFrames(win);
|
|
131
68
|
function isEventOutside(event) {
|
|
132
|
-
const target = getEventTarget(event);
|
|
133
|
-
if (!(
|
|
69
|
+
const target = (0, import_dom_query.getEventTarget)(event);
|
|
70
|
+
if (!(0, import_dom_query.isHTMLElement)(target)) {
|
|
134
71
|
return false;
|
|
135
72
|
}
|
|
136
|
-
if (
|
|
73
|
+
if ((0, import_dom_query.contains)(node, target)) {
|
|
137
74
|
return false;
|
|
138
75
|
}
|
|
139
|
-
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
return !(exclude == null ? void 0 : exclude(target));
|
|
76
|
+
return !exclude?.(target);
|
|
143
77
|
}
|
|
144
78
|
let clickHandler;
|
|
145
79
|
function onPointerDown(event) {
|
|
@@ -147,53 +81,59 @@ function trackInteractOutside(node, options) {
|
|
|
147
81
|
if (!node || !isEventOutside(event))
|
|
148
82
|
return;
|
|
149
83
|
if (onPointerDownOutside || onInteractOutside) {
|
|
150
|
-
const handler2 = callAll(onPointerDownOutside, onInteractOutside);
|
|
84
|
+
const handler2 = (0, import_utils.callAll)(onPointerDownOutside, onInteractOutside);
|
|
151
85
|
node.addEventListener(POINTER_OUTSIDE_EVENT, handler2, { once: true });
|
|
152
86
|
}
|
|
153
|
-
fireCustomEvent(node, POINTER_OUTSIDE_EVENT, {
|
|
87
|
+
(0, import_dom_event.fireCustomEvent)(node, POINTER_OUTSIDE_EVENT, {
|
|
154
88
|
bubbles: false,
|
|
155
89
|
cancelable: true,
|
|
156
90
|
detail: {
|
|
157
91
|
originalEvent: event,
|
|
158
|
-
contextmenu: isContextMenuEvent(event),
|
|
159
|
-
focusable: isFocusable(getEventTarget(event))
|
|
92
|
+
contextmenu: (0, import_dom_event.isContextMenuEvent)(event),
|
|
93
|
+
focusable: (0, import_tabbable.isFocusable)((0, import_dom_query.getEventTarget)(event))
|
|
160
94
|
}
|
|
161
95
|
});
|
|
162
96
|
}
|
|
163
97
|
if (event.pointerType === "touch") {
|
|
98
|
+
frames.removeEventListener("click", handler);
|
|
164
99
|
doc.removeEventListener("click", handler);
|
|
165
100
|
clickHandler = handler;
|
|
166
101
|
doc.addEventListener("click", handler, { once: true });
|
|
102
|
+
frames.addEventListener("click", handler, { once: true });
|
|
167
103
|
} else {
|
|
168
104
|
handler();
|
|
169
105
|
}
|
|
170
106
|
}
|
|
171
107
|
const cleanups = /* @__PURE__ */ new Set();
|
|
172
108
|
const timer = setTimeout(() => {
|
|
173
|
-
cleanups.add(
|
|
109
|
+
cleanups.add(frames.addEventListener("pointerdown", onPointerDown, true));
|
|
110
|
+
cleanups.add((0, import_dom_event.addDomEvent)(doc, "pointerdown", onPointerDown, true));
|
|
174
111
|
}, 0);
|
|
175
112
|
function onFocusin(event) {
|
|
176
113
|
if (!node || !isEventOutside(event))
|
|
177
114
|
return;
|
|
178
115
|
if (onFocusOutside || onInteractOutside) {
|
|
179
|
-
const handler = callAll(onFocusOutside, onInteractOutside);
|
|
116
|
+
const handler = (0, import_utils.callAll)(onFocusOutside, onInteractOutside);
|
|
180
117
|
node.addEventListener(FOCUS_OUTSIDE_EVENT, handler, { once: true });
|
|
181
118
|
}
|
|
182
|
-
fireCustomEvent(node, FOCUS_OUTSIDE_EVENT, {
|
|
119
|
+
(0, import_dom_event.fireCustomEvent)(node, FOCUS_OUTSIDE_EVENT, {
|
|
183
120
|
bubbles: false,
|
|
184
121
|
cancelable: true,
|
|
185
122
|
detail: {
|
|
186
123
|
originalEvent: event,
|
|
187
124
|
contextmenu: false,
|
|
188
|
-
focusable: isFocusable(getEventTarget(event))
|
|
125
|
+
focusable: (0, import_tabbable.isFocusable)((0, import_dom_query.getEventTarget)(event))
|
|
189
126
|
}
|
|
190
127
|
});
|
|
191
128
|
}
|
|
192
|
-
cleanups.add(addDomEvent(doc, "focusin", onFocusin, true));
|
|
129
|
+
cleanups.add((0, import_dom_event.addDomEvent)(doc, "focusin", onFocusin, true));
|
|
130
|
+
cleanups.add(frames.addEventListener("focusin", onFocusin, true));
|
|
193
131
|
return () => {
|
|
194
132
|
clearTimeout(timer);
|
|
195
|
-
if (clickHandler)
|
|
133
|
+
if (clickHandler) {
|
|
134
|
+
frames.removeEventListener("click", clickHandler);
|
|
196
135
|
doc.removeEventListener("click", clickHandler);
|
|
136
|
+
}
|
|
197
137
|
cleanups.forEach((fn) => fn());
|
|
198
138
|
};
|
|
199
139
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,99 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return res != null ? res : void 0;
|
|
5
|
-
};
|
|
6
|
-
var callAll = (...fns) => (...a) => {
|
|
7
|
-
fns.forEach(function(fn) {
|
|
8
|
-
fn == null ? void 0 : fn(...a);
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// ../core/src/guard.ts
|
|
13
|
-
var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
14
|
-
|
|
15
|
-
// ../dom/src/platform.ts
|
|
16
|
-
var isDom = () => typeof window !== "undefined";
|
|
17
|
-
function getPlatform() {
|
|
18
|
-
var _a;
|
|
19
|
-
const agent = navigator.userAgentData;
|
|
20
|
-
return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
|
|
21
|
-
}
|
|
22
|
-
var pt = (v) => isDom() && v.test(getPlatform());
|
|
23
|
-
var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints;
|
|
24
|
-
var isMac = () => pt(/^Mac/) && !isTouchDevice;
|
|
25
|
-
|
|
26
|
-
// ../dom/src/query.ts
|
|
27
|
-
function isDocument(el) {
|
|
28
|
-
return el.nodeType === Node.DOCUMENT_NODE;
|
|
29
|
-
}
|
|
30
|
-
function isWindow(value) {
|
|
31
|
-
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
32
|
-
}
|
|
33
|
-
function getDocument(el) {
|
|
34
|
-
var _a;
|
|
35
|
-
if (isWindow(el))
|
|
36
|
-
return el.document;
|
|
37
|
-
if (isDocument(el))
|
|
38
|
-
return el;
|
|
39
|
-
return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
|
|
40
|
-
}
|
|
41
|
-
function getWindow(el) {
|
|
42
|
-
var _a;
|
|
43
|
-
return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
|
|
44
|
-
}
|
|
45
|
-
function getEventTarget(event) {
|
|
46
|
-
var _a, _b;
|
|
47
|
-
return (_b = (_a = event.composedPath) == null ? void 0 : _a.call(event)[0]) != null ? _b : event.target;
|
|
48
|
-
}
|
|
49
|
-
function contains(parent, child) {
|
|
50
|
-
if (!parent)
|
|
51
|
-
return false;
|
|
52
|
-
return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
|
|
53
|
-
}
|
|
54
|
-
function isHTMLElement(v) {
|
|
55
|
-
return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
|
|
56
|
-
}
|
|
57
|
-
function isVisible(el) {
|
|
58
|
-
if (!isHTMLElement(el))
|
|
59
|
-
return false;
|
|
60
|
-
return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ../dom/src/event.ts
|
|
64
|
-
var isContextMenuEvent = (e) => {
|
|
65
|
-
return e.button === 2 || isCtrlKey(e) && e.button === 0;
|
|
66
|
-
};
|
|
67
|
-
var isCtrlKey = (v) => isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey;
|
|
68
|
-
|
|
69
|
-
// ../dom/src/fire-event.ts
|
|
70
|
-
function fireCustomEvent(el, type, init) {
|
|
71
|
-
if (!el)
|
|
72
|
-
return;
|
|
73
|
-
const win = getWindow(el);
|
|
74
|
-
const event = new win.CustomEvent(type, init);
|
|
75
|
-
return el.dispatchEvent(event);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ../dom/src/focusable.ts
|
|
79
|
-
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";
|
|
80
|
-
function isFocusable(element) {
|
|
81
|
-
if (!element)
|
|
82
|
-
return false;
|
|
83
|
-
return element.matches(focusableSelector) && isVisible(element);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ../dom/src/listener.ts
|
|
87
|
-
var isRef = (v) => hasProp(v, "current");
|
|
88
|
-
function addDomEvent(target, eventName, handler, options) {
|
|
89
|
-
const node = isRef(target) ? target.current : runIfFn(target);
|
|
90
|
-
node == null ? void 0 : node.addEventListener(eventName, handler, options);
|
|
91
|
-
return () => {
|
|
92
|
-
node == null ? void 0 : node.removeEventListener(eventName, handler, options);
|
|
93
|
-
};
|
|
94
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
getWindowFrames
|
|
3
|
+
} from "./chunk-XJMPFMOP.mjs";
|
|
95
4
|
|
|
96
5
|
// src/index.ts
|
|
6
|
+
import { addDomEvent, fireCustomEvent, isContextMenuEvent } from "@zag-js/dom-event";
|
|
7
|
+
import { contains, getDocument, getEventTarget, getWindow, isHTMLElement } from "@zag-js/dom-query";
|
|
8
|
+
import { isFocusable } from "@zag-js/tabbable";
|
|
9
|
+
import { callAll } from "@zag-js/utils";
|
|
97
10
|
var POINTER_OUTSIDE_EVENT = "pointerdown.outside";
|
|
98
11
|
var FOCUS_OUTSIDE_EVENT = "focus.outside";
|
|
99
12
|
function trackInteractOutside(node, options) {
|
|
@@ -102,18 +15,16 @@ function trackInteractOutside(node, options) {
|
|
|
102
15
|
return;
|
|
103
16
|
const doc = getDocument(node);
|
|
104
17
|
const win = getWindow(node);
|
|
18
|
+
const frames = getWindowFrames(win);
|
|
105
19
|
function isEventOutside(event) {
|
|
106
20
|
const target = getEventTarget(event);
|
|
107
|
-
if (!(target
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
if (!contains(doc.documentElement, target)) {
|
|
21
|
+
if (!isHTMLElement(target)) {
|
|
111
22
|
return false;
|
|
112
23
|
}
|
|
113
24
|
if (contains(node, target)) {
|
|
114
25
|
return false;
|
|
115
26
|
}
|
|
116
|
-
return !
|
|
27
|
+
return !exclude?.(target);
|
|
117
28
|
}
|
|
118
29
|
let clickHandler;
|
|
119
30
|
function onPointerDown(event) {
|
|
@@ -135,15 +46,18 @@ function trackInteractOutside(node, options) {
|
|
|
135
46
|
});
|
|
136
47
|
}
|
|
137
48
|
if (event.pointerType === "touch") {
|
|
49
|
+
frames.removeEventListener("click", handler);
|
|
138
50
|
doc.removeEventListener("click", handler);
|
|
139
51
|
clickHandler = handler;
|
|
140
52
|
doc.addEventListener("click", handler, { once: true });
|
|
53
|
+
frames.addEventListener("click", handler, { once: true });
|
|
141
54
|
} else {
|
|
142
55
|
handler();
|
|
143
56
|
}
|
|
144
57
|
}
|
|
145
58
|
const cleanups = /* @__PURE__ */ new Set();
|
|
146
59
|
const timer = setTimeout(() => {
|
|
60
|
+
cleanups.add(frames.addEventListener("pointerdown", onPointerDown, true));
|
|
147
61
|
cleanups.add(addDomEvent(doc, "pointerdown", onPointerDown, true));
|
|
148
62
|
}, 0);
|
|
149
63
|
function onFocusin(event) {
|
|
@@ -164,10 +78,13 @@ function trackInteractOutside(node, options) {
|
|
|
164
78
|
});
|
|
165
79
|
}
|
|
166
80
|
cleanups.add(addDomEvent(doc, "focusin", onFocusin, true));
|
|
81
|
+
cleanups.add(frames.addEventListener("focusin", onFocusin, true));
|
|
167
82
|
return () => {
|
|
168
83
|
clearTimeout(timer);
|
|
169
|
-
if (clickHandler)
|
|
84
|
+
if (clickHandler) {
|
|
85
|
+
frames.removeEventListener("click", clickHandler);
|
|
170
86
|
doc.removeEventListener("click", clickHandler);
|
|
87
|
+
}
|
|
171
88
|
cleanups.forEach((fn) => fn());
|
|
172
89
|
};
|
|
173
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/interact-outside",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Track interations or focus outside an element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -15,10 +15,14 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"dist/**/*"
|
|
17
17
|
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@zag-js/dom-query": "0.1.3",
|
|
20
|
+
"@zag-js/dom-event": "0.0.1",
|
|
21
|
+
"@zag-js/utils": "0.3.3",
|
|
22
|
+
"@zag-js/tabbable": "0.0.1"
|
|
23
|
+
},
|
|
18
24
|
"devDependencies": {
|
|
19
|
-
"clean-package": "2.2.0"
|
|
20
|
-
"@zag-js/dom-utils": "0.2.2",
|
|
21
|
-
"@zag-js/utils": "0.3.2"
|
|
25
|
+
"clean-package": "2.2.0"
|
|
22
26
|
},
|
|
23
27
|
"publishConfig": {
|
|
24
28
|
"access": "public"
|