@zag-js/interact-outside 1.7.0 → 1.8.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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +21 -14
- package/dist/index.mjs +22 -15
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -20,6 +20,7 @@ interface EventDetails<T> {
|
|
|
20
20
|
originalEvent: T;
|
|
21
21
|
contextmenu: boolean;
|
|
22
22
|
focusable: boolean;
|
|
23
|
+
target: EventTarget;
|
|
23
24
|
}
|
|
24
25
|
type PointerDownOutsideEvent = CustomEvent<EventDetails<PointerEvent>>;
|
|
25
26
|
type FocusOutsideEvent = CustomEvent<EventDetails<FocusEvent>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ interface EventDetails<T> {
|
|
|
20
20
|
originalEvent: T;
|
|
21
21
|
contextmenu: boolean;
|
|
22
22
|
focusable: boolean;
|
|
23
|
+
target: EventTarget;
|
|
23
24
|
}
|
|
24
25
|
type PointerDownOutsideEvent = CustomEvent<EventDetails<PointerEvent>>;
|
|
25
26
|
type FocusOutsideEvent = CustomEvent<EventDetails<FocusEvent>>;
|
package/dist/index.js
CHANGED
|
@@ -108,8 +108,7 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
108
108
|
const win = domQuery.getWindow(node);
|
|
109
109
|
const frames = getWindowFrames(win);
|
|
110
110
|
const parentWin = getParentWindow(win);
|
|
111
|
-
function isEventOutside(event) {
|
|
112
|
-
const target = domQuery.getEventTarget(event);
|
|
111
|
+
function isEventOutside(event, target) {
|
|
113
112
|
if (!domQuery.isHTMLElement(target)) return false;
|
|
114
113
|
if (!target.isConnected) return false;
|
|
115
114
|
if (domQuery.contains(node, target)) return false;
|
|
@@ -124,12 +123,15 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
124
123
|
return !exclude?.(target);
|
|
125
124
|
}
|
|
126
125
|
const pointerdownCleanups = /* @__PURE__ */ new Set();
|
|
126
|
+
const isInShadowRoot = domQuery.isShadowRoot(node?.getRootNode());
|
|
127
127
|
function onPointerDown(event) {
|
|
128
|
-
function handler() {
|
|
129
|
-
const func = defer ? domQuery.raf : (v) => v();
|
|
130
|
-
const
|
|
128
|
+
function handler(clickEvent) {
|
|
129
|
+
const func = defer && !domQuery.isTouchDevice() ? domQuery.raf : (v) => v();
|
|
130
|
+
const evt = clickEvent ?? event;
|
|
131
|
+
const composedPath = evt?.composedPath?.() ?? [evt?.target];
|
|
131
132
|
func(() => {
|
|
132
|
-
|
|
133
|
+
const target = isInShadowRoot ? composedPath[0] : domQuery.getEventTarget(event);
|
|
134
|
+
if (!node || !isEventOutside(event, target)) return;
|
|
133
135
|
if (onPointerDownOutside || onInteractOutside) {
|
|
134
136
|
const handler2 = utils.callAll(onPointerDownOutside, onInteractOutside);
|
|
135
137
|
node.addEventListener(POINTER_OUTSIDE_EVENT, handler2, { once: true });
|
|
@@ -138,9 +140,10 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
138
140
|
bubbles: false,
|
|
139
141
|
cancelable: true,
|
|
140
142
|
detail: {
|
|
141
|
-
originalEvent:
|
|
142
|
-
contextmenu: domQuery.isContextMenuEvent(
|
|
143
|
-
focusable: isComposedPathFocusable(composedPath)
|
|
143
|
+
originalEvent: evt,
|
|
144
|
+
contextmenu: domQuery.isContextMenuEvent(evt),
|
|
145
|
+
focusable: isComposedPathFocusable(composedPath),
|
|
146
|
+
target
|
|
144
147
|
}
|
|
145
148
|
});
|
|
146
149
|
});
|
|
@@ -163,7 +166,8 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
163
166
|
function onFocusin(event) {
|
|
164
167
|
const func = defer ? domQuery.raf : (v) => v();
|
|
165
168
|
func(() => {
|
|
166
|
-
|
|
169
|
+
const target = domQuery.getEventTarget(event);
|
|
170
|
+
if (!node || !isEventOutside(event, target)) return;
|
|
167
171
|
if (onFocusOutside || onInteractOutside) {
|
|
168
172
|
const handler = utils.callAll(onFocusOutside, onInteractOutside);
|
|
169
173
|
node.addEventListener(FOCUS_OUTSIDE_EVENT, handler, { once: true });
|
|
@@ -174,14 +178,17 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
174
178
|
detail: {
|
|
175
179
|
originalEvent: event,
|
|
176
180
|
contextmenu: false,
|
|
177
|
-
focusable: domQuery.isFocusable(
|
|
181
|
+
focusable: domQuery.isFocusable(target),
|
|
182
|
+
target
|
|
178
183
|
}
|
|
179
184
|
});
|
|
180
185
|
});
|
|
181
186
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
if (!domQuery.isTouchDevice()) {
|
|
188
|
+
cleanups.add(domQuery.addDomEvent(doc, "focusin", onFocusin, true));
|
|
189
|
+
cleanups.add(parentWin.addEventListener("focusin", onFocusin, true));
|
|
190
|
+
cleanups.add(frames.addEventListener("focusin", onFocusin, true));
|
|
191
|
+
}
|
|
185
192
|
return () => {
|
|
186
193
|
clearTimeout(timer);
|
|
187
194
|
pointerdownCleanups.forEach((fn) => fn());
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { raf, getDocument, getWindow, addDomEvent,
|
|
1
|
+
import { raf, getDocument, getWindow, isShadowRoot, addDomEvent, isTouchDevice, getEventTarget, isFocusable, isContextMenuEvent, isHTMLElement, contains, getNearestOverflowAncestor } from '@zag-js/dom-query';
|
|
2
2
|
import { callAll } from '@zag-js/utils';
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
@@ -106,8 +106,7 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
106
106
|
const win = getWindow(node);
|
|
107
107
|
const frames = getWindowFrames(win);
|
|
108
108
|
const parentWin = getParentWindow(win);
|
|
109
|
-
function isEventOutside(event) {
|
|
110
|
-
const target = getEventTarget(event);
|
|
109
|
+
function isEventOutside(event, target) {
|
|
111
110
|
if (!isHTMLElement(target)) return false;
|
|
112
111
|
if (!target.isConnected) return false;
|
|
113
112
|
if (contains(node, target)) return false;
|
|
@@ -122,12 +121,15 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
122
121
|
return !exclude?.(target);
|
|
123
122
|
}
|
|
124
123
|
const pointerdownCleanups = /* @__PURE__ */ new Set();
|
|
124
|
+
const isInShadowRoot = isShadowRoot(node?.getRootNode());
|
|
125
125
|
function onPointerDown(event) {
|
|
126
|
-
function handler() {
|
|
127
|
-
const func = defer ? raf : (v) => v();
|
|
128
|
-
const
|
|
126
|
+
function handler(clickEvent) {
|
|
127
|
+
const func = defer && !isTouchDevice() ? raf : (v) => v();
|
|
128
|
+
const evt = clickEvent ?? event;
|
|
129
|
+
const composedPath = evt?.composedPath?.() ?? [evt?.target];
|
|
129
130
|
func(() => {
|
|
130
|
-
|
|
131
|
+
const target = isInShadowRoot ? composedPath[0] : getEventTarget(event);
|
|
132
|
+
if (!node || !isEventOutside(event, target)) return;
|
|
131
133
|
if (onPointerDownOutside || onInteractOutside) {
|
|
132
134
|
const handler2 = callAll(onPointerDownOutside, onInteractOutside);
|
|
133
135
|
node.addEventListener(POINTER_OUTSIDE_EVENT, handler2, { once: true });
|
|
@@ -136,9 +138,10 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
136
138
|
bubbles: false,
|
|
137
139
|
cancelable: true,
|
|
138
140
|
detail: {
|
|
139
|
-
originalEvent:
|
|
140
|
-
contextmenu: isContextMenuEvent(
|
|
141
|
-
focusable: isComposedPathFocusable(composedPath)
|
|
141
|
+
originalEvent: evt,
|
|
142
|
+
contextmenu: isContextMenuEvent(evt),
|
|
143
|
+
focusable: isComposedPathFocusable(composedPath),
|
|
144
|
+
target
|
|
142
145
|
}
|
|
143
146
|
});
|
|
144
147
|
});
|
|
@@ -161,7 +164,8 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
161
164
|
function onFocusin(event) {
|
|
162
165
|
const func = defer ? raf : (v) => v();
|
|
163
166
|
func(() => {
|
|
164
|
-
|
|
167
|
+
const target = getEventTarget(event);
|
|
168
|
+
if (!node || !isEventOutside(event, target)) return;
|
|
165
169
|
if (onFocusOutside || onInteractOutside) {
|
|
166
170
|
const handler = callAll(onFocusOutside, onInteractOutside);
|
|
167
171
|
node.addEventListener(FOCUS_OUTSIDE_EVENT, handler, { once: true });
|
|
@@ -172,14 +176,17 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
172
176
|
detail: {
|
|
173
177
|
originalEvent: event,
|
|
174
178
|
contextmenu: false,
|
|
175
|
-
focusable: isFocusable(
|
|
179
|
+
focusable: isFocusable(target),
|
|
180
|
+
target
|
|
176
181
|
}
|
|
177
182
|
});
|
|
178
183
|
});
|
|
179
184
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
185
|
+
if (!isTouchDevice()) {
|
|
186
|
+
cleanups.add(addDomEvent(doc, "focusin", onFocusin, true));
|
|
187
|
+
cleanups.add(parentWin.addEventListener("focusin", onFocusin, true));
|
|
188
|
+
cleanups.add(frames.addEventListener("focusin", onFocusin, true));
|
|
189
|
+
}
|
|
183
190
|
return () => {
|
|
184
191
|
clearTimeout(timer);
|
|
185
192
|
pointerdownCleanups.forEach((fn) => fn());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/interact-outside",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Track interactions or focus outside an element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@zag-js/dom-query": "1.
|
|
20
|
-
"@zag-js/utils": "1.
|
|
19
|
+
"@zag-js/dom-query": "1.8.0",
|
|
20
|
+
"@zag-js/utils": "1.8.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"clean-package": "2.2.0"
|