@destyler/interact-outside 0.2.11 → 0.2.12
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 +10 -11
- package/dist/index.mjs +61 -16
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region index.d.ts
|
|
2
|
-
interface InteractOutsideHandlers {
|
|
2
|
+
export interface InteractOutsideHandlers {
|
|
3
3
|
/**
|
|
4
4
|
* Function called when the pointer is pressed down outside the component
|
|
5
5
|
*/
|
|
@@ -13,20 +13,19 @@ interface InteractOutsideHandlers {
|
|
|
13
13
|
*/
|
|
14
14
|
onInteractOutside?: ((event: InteractOutsideEvent) => void) | undefined;
|
|
15
15
|
}
|
|
16
|
-
interface InteractOutsideOptions extends InteractOutsideHandlers {
|
|
16
|
+
export interface InteractOutsideOptions extends InteractOutsideHandlers {
|
|
17
17
|
exclude?: ((target: HTMLElement) => boolean) | undefined;
|
|
18
18
|
defer?: boolean | undefined;
|
|
19
19
|
}
|
|
20
|
-
interface EventDetails<T> {
|
|
20
|
+
export interface EventDetails<T> {
|
|
21
21
|
originalEvent: T;
|
|
22
22
|
contextmenu: boolean;
|
|
23
23
|
focusable: boolean;
|
|
24
24
|
}
|
|
25
|
-
type PointerDownOutsideEvent = CustomEvent<EventDetails<PointerEvent>>;
|
|
26
|
-
type FocusOutsideEvent = CustomEvent<EventDetails<FocusEvent>>;
|
|
27
|
-
type InteractOutsideEvent = PointerDownOutsideEvent | FocusOutsideEvent;
|
|
28
|
-
type MaybeElement = HTMLElement | null | undefined;
|
|
29
|
-
type NodeOrFn = MaybeElement | (() => MaybeElement);
|
|
30
|
-
declare function trackInteractOutside(nodeOrFn: NodeOrFn, options: InteractOutsideOptions): () => void;
|
|
31
|
-
//#endregion
|
|
32
|
-
export { EventDetails, FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, InteractOutsideOptions, MaybeElement, NodeOrFn, PointerDownOutsideEvent, trackInteractOutside };
|
|
25
|
+
export type PointerDownOutsideEvent = CustomEvent<EventDetails<PointerEvent>>;
|
|
26
|
+
export type FocusOutsideEvent = CustomEvent<EventDetails<FocusEvent>>;
|
|
27
|
+
export type InteractOutsideEvent = PointerDownOutsideEvent | FocusOutsideEvent;
|
|
28
|
+
export type MaybeElement = HTMLElement | null | undefined;
|
|
29
|
+
export type NodeOrFn = MaybeElement | (() => MaybeElement);
|
|
30
|
+
export declare function trackInteractOutside(nodeOrFn: NodeOrFn, options: InteractOutsideOptions): () => void;
|
|
31
|
+
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { addDomEvent, contains, getDocument, getEventTarget, getNearestOverflowAncestor, getWindow, isContextMenuEvent, isFocusable, isHTMLElement, raf } from "@destyler/dom";
|
|
2
2
|
import { callAll } from "@destyler/utils";
|
|
3
|
-
|
|
4
3
|
//#region src/frame-utils.ts
|
|
5
4
|
function getWindowFrames(win) {
|
|
6
5
|
const frames = {
|
|
@@ -11,15 +10,29 @@ function getWindowFrames(win) {
|
|
|
11
10
|
}
|
|
12
11
|
},
|
|
13
12
|
addEventListener(event, listener, options) {
|
|
13
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
14
14
|
frames.each((frame) => {
|
|
15
15
|
try {
|
|
16
|
-
frame.document
|
|
16
|
+
const doc = frame.document;
|
|
17
|
+
doc.addEventListener(event, listener, options);
|
|
18
|
+
cleanups.add(() => doc.removeEventListener(event, listener, options));
|
|
17
19
|
} catch {}
|
|
18
20
|
});
|
|
21
|
+
let cleaning = false;
|
|
19
22
|
return () => {
|
|
23
|
+
if (cleaning) return false;
|
|
24
|
+
cleaning = true;
|
|
20
25
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
cleanups.forEach((cleanup) => {
|
|
27
|
+
try {
|
|
28
|
+
cleanup();
|
|
29
|
+
cleanups.delete(cleanup);
|
|
30
|
+
} catch {}
|
|
31
|
+
});
|
|
32
|
+
if (cleanups.size > 0) return false;
|
|
33
|
+
} finally {
|
|
34
|
+
cleaning = false;
|
|
35
|
+
}
|
|
23
36
|
};
|
|
24
37
|
},
|
|
25
38
|
removeEventListener(event, listener, options) {
|
|
@@ -42,7 +55,9 @@ function getParentWindow(win) {
|
|
|
42
55
|
return () => {
|
|
43
56
|
try {
|
|
44
57
|
parent?.removeEventListener(event, listener, options);
|
|
45
|
-
} catch {
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
46
61
|
};
|
|
47
62
|
},
|
|
48
63
|
removeEventListener: (event, listener, options) => {
|
|
@@ -52,7 +67,6 @@ function getParentWindow(win) {
|
|
|
52
67
|
}
|
|
53
68
|
};
|
|
54
69
|
}
|
|
55
|
-
|
|
56
70
|
//#endregion
|
|
57
71
|
//#region index.ts
|
|
58
72
|
const POINTER_OUTSIDE_EVENT = "pointerdown.outside";
|
|
@@ -109,15 +123,31 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
109
123
|
return !exclude?.(target);
|
|
110
124
|
}
|
|
111
125
|
const pointerdownCleanups = /* @__PURE__ */ new Set();
|
|
126
|
+
const pendingFrames = /* @__PURE__ */ new Set();
|
|
127
|
+
let disposed = false;
|
|
128
|
+
let cleaning = false;
|
|
129
|
+
let cleaned = false;
|
|
130
|
+
function scheduleOutside(callback) {
|
|
131
|
+
if (disposed) return;
|
|
132
|
+
if (!defer) {
|
|
133
|
+
callback();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const cancel = raf(() => {
|
|
137
|
+
pendingFrames.delete(cancel);
|
|
138
|
+
if (!disposed) callback();
|
|
139
|
+
});
|
|
140
|
+
pendingFrames.add(cancel);
|
|
141
|
+
}
|
|
112
142
|
function onPointerDown(event) {
|
|
143
|
+
if (disposed) return;
|
|
113
144
|
function handler() {
|
|
114
|
-
const func = defer ? raf : (v) => v();
|
|
115
145
|
const composedPath = event.composedPath?.() ?? [event.target];
|
|
116
|
-
|
|
146
|
+
scheduleOutside(() => {
|
|
117
147
|
if (!node || !isEventOutside(event)) return;
|
|
118
148
|
if (onPointerDownOutside || onInteractOutside) {
|
|
119
|
-
const handler
|
|
120
|
-
node.addEventListener(POINTER_OUTSIDE_EVENT, handler
|
|
149
|
+
const handler = callAll(onPointerDownOutside, onInteractOutside);
|
|
150
|
+
node.addEventListener(POINTER_OUTSIDE_EVENT, handler, { once: true });
|
|
121
151
|
}
|
|
122
152
|
fireCustomEvent(node, POINTER_OUTSIDE_EVENT, {
|
|
123
153
|
bubbles: false,
|
|
@@ -144,7 +174,7 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
144
174
|
cleanups.add(frames.addEventListener("pointerdown", onPointerDown, true));
|
|
145
175
|
}, 0);
|
|
146
176
|
function onFocusin(event) {
|
|
147
|
-
(
|
|
177
|
+
scheduleOutside(() => {
|
|
148
178
|
if (!node || !isEventOutside(event)) return;
|
|
149
179
|
if (onFocusOutside || onInteractOutside) {
|
|
150
180
|
const handler = callAll(onFocusOutside, onInteractOutside);
|
|
@@ -165,9 +195,25 @@ function trackInteractOutsideImpl(node, options) {
|
|
|
165
195
|
cleanups.add(parentWin.addEventListener("focusin", onFocusin, true));
|
|
166
196
|
cleanups.add(frames.addEventListener("focusin", onFocusin, true));
|
|
167
197
|
return () => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
198
|
+
if (cleaning || cleaned) return;
|
|
199
|
+
disposed = true;
|
|
200
|
+
cleaning = true;
|
|
201
|
+
try {
|
|
202
|
+
pendingFrames.forEach((cancel) => {
|
|
203
|
+
cancel();
|
|
204
|
+
pendingFrames.delete(cancel);
|
|
205
|
+
});
|
|
206
|
+
clearTimeout(timer);
|
|
207
|
+
pointerdownCleanups.forEach((cleanup) => {
|
|
208
|
+
if (cleanup() !== false) pointerdownCleanups.delete(cleanup);
|
|
209
|
+
});
|
|
210
|
+
cleanups.forEach((cleanup) => {
|
|
211
|
+
if (cleanup() !== false) cleanups.delete(cleanup);
|
|
212
|
+
});
|
|
213
|
+
cleaned = pointerdownCleanups.size === 0 && cleanups.size === 0;
|
|
214
|
+
} finally {
|
|
215
|
+
cleaning = false;
|
|
216
|
+
}
|
|
171
217
|
};
|
|
172
218
|
}
|
|
173
219
|
function trackInteractOutside(nodeOrFn, options) {
|
|
@@ -186,6 +232,5 @@ function fireCustomEvent(el, type, init) {
|
|
|
186
232
|
const event = new (el.ownerDocument.defaultView || window).CustomEvent(type, init);
|
|
187
233
|
return el.dispatchEvent(event);
|
|
188
234
|
}
|
|
189
|
-
|
|
190
235
|
//#endregion
|
|
191
|
-
export { trackInteractOutside };
|
|
236
|
+
export { trackInteractOutside };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@destyler/interact-outside",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.12",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "Elone Hoo <elonehoo@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@destyler/dom": "0.2.
|
|
26
|
-
"@destyler/utils": "0.2.
|
|
25
|
+
"@destyler/dom": "0.2.12",
|
|
26
|
+
"@destyler/utils": "0.2.12"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|