@zag-js/dismissable 2.0.0-next.1 → 2.0.0-next.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/dismissable-layer.d.mts +5 -3
- package/dist/dismissable-layer.d.ts +5 -3
- package/dist/dismissable-layer.js +20 -40
- package/dist/dismissable-layer.mjs +26 -43
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -0
- package/dist/index.mjs +4 -0
- package/dist/layer-props.js +7 -6
- package/dist/layer-props.mjs +7 -6
- package/dist/layer-stack.d.mts +24 -3
- package/dist/layer-stack.d.ts +24 -3
- package/dist/layer-stack.js +84 -17
- package/dist/layer-stack.mjs +83 -17
- package/dist/pointer-event-outside.d.mts +6 -1
- package/dist/pointer-event-outside.d.ts +6 -1
- package/dist/pointer-event-outside.js +32 -21
- package/dist/pointer-event-outside.mjs +30 -20
- package/package.json +5 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InteractOutsideHandlers } from '@zag-js/interact-outside';
|
|
2
|
-
import { MaybeFunction } from '@zag-js/utils';
|
|
2
|
+
import { MaybeFunction, TeardownReason } from '@zag-js/utils';
|
|
3
3
|
import { LayerDismissEvent, LayerSnapshot, LayerType } from './layer-stack.mjs';
|
|
4
4
|
|
|
5
5
|
type MaybeElement = HTMLElement | null;
|
|
@@ -35,7 +35,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
|
|
|
35
35
|
/**
|
|
36
36
|
* Whether to block pointer events outside the dismissable element
|
|
37
37
|
*/
|
|
38
|
-
pointerBlocking?: boolean | undefined;
|
|
38
|
+
pointerBlocking?: boolean | (() => boolean) | undefined;
|
|
39
39
|
/**
|
|
40
40
|
* Function called when the dismissable element is dismissed
|
|
41
41
|
*/
|
|
@@ -56,8 +56,10 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
|
|
|
56
56
|
* The type of layer being tracked
|
|
57
57
|
*/
|
|
58
58
|
type?: LayerType | undefined;
|
|
59
|
+
/** Groups this layer with its peers, so closing one does not dismiss the other. */
|
|
60
|
+
group?: string | undefined;
|
|
59
61
|
}
|
|
60
|
-
declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): () => void;
|
|
62
|
+
declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): (args_0?: TeardownReason | undefined) => void;
|
|
61
63
|
declare function trackDismissableBranch(nodeOrFn: NodeOrFn, options?: {
|
|
62
64
|
defer?: boolean | undefined;
|
|
63
65
|
}): () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InteractOutsideHandlers } from '@zag-js/interact-outside';
|
|
2
|
-
import { MaybeFunction } from '@zag-js/utils';
|
|
2
|
+
import { MaybeFunction, TeardownReason } from '@zag-js/utils';
|
|
3
3
|
import { LayerDismissEvent, LayerSnapshot, LayerType } from './layer-stack.js';
|
|
4
4
|
|
|
5
5
|
type MaybeElement = HTMLElement | null;
|
|
@@ -35,7 +35,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
|
|
|
35
35
|
/**
|
|
36
36
|
* Whether to block pointer events outside the dismissable element
|
|
37
37
|
*/
|
|
38
|
-
pointerBlocking?: boolean | undefined;
|
|
38
|
+
pointerBlocking?: boolean | (() => boolean) | undefined;
|
|
39
39
|
/**
|
|
40
40
|
* Function called when the dismissable element is dismissed
|
|
41
41
|
*/
|
|
@@ -56,8 +56,10 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
|
|
|
56
56
|
* The type of layer being tracked
|
|
57
57
|
*/
|
|
58
58
|
type?: LayerType | undefined;
|
|
59
|
+
/** Groups this layer with its peers, so closing one does not dismiss the other. */
|
|
60
|
+
group?: string | undefined;
|
|
59
61
|
}
|
|
60
|
-
declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): () => void;
|
|
62
|
+
declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): (args_0?: TeardownReason | undefined) => void;
|
|
61
63
|
declare function trackDismissableBranch(nodeOrFn: NodeOrFn, options?: {
|
|
62
64
|
defer?: boolean | undefined;
|
|
63
65
|
}): () => void;
|
|
@@ -31,14 +31,6 @@ var import_escape_keydown = require("./escape-keydown.js");
|
|
|
31
31
|
var import_layer_stack = require("./layer-stack.js");
|
|
32
32
|
var import_pointer_event_outside = require("./pointer-event-outside.js");
|
|
33
33
|
function trackDismissableElementImpl(node, options) {
|
|
34
|
-
const { warnOnMissingNode = true } = options;
|
|
35
|
-
if (warnOnMissingNode && !node) {
|
|
36
|
-
(0, import_utils.warn)("[@zag-js/dismissable] node is `null` or `undefined`");
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (!node) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
34
|
const {
|
|
43
35
|
onDismiss,
|
|
44
36
|
onRequestDismiss,
|
|
@@ -46,12 +38,14 @@ function trackDismissableElementImpl(node, options) {
|
|
|
46
38
|
exclude: excludeContainers,
|
|
47
39
|
debug,
|
|
48
40
|
type = "dialog",
|
|
41
|
+
group,
|
|
49
42
|
onLayerChange
|
|
50
43
|
} = options;
|
|
51
44
|
const layer = {
|
|
52
45
|
dismiss: onDismiss,
|
|
53
46
|
node,
|
|
54
47
|
type,
|
|
48
|
+
group,
|
|
55
49
|
pointerBlocking,
|
|
56
50
|
requestDismiss: onRequestDismiss,
|
|
57
51
|
onLayerChange
|
|
@@ -88,7 +82,6 @@ function trackDismissableElementImpl(node, options) {
|
|
|
88
82
|
}
|
|
89
83
|
}
|
|
90
84
|
function exclude(target) {
|
|
91
|
-
if (!node) return false;
|
|
92
85
|
const containers = typeof excludeContainers === "function" ? excludeContainers() : excludeContainers;
|
|
93
86
|
const _containers = Array.isArray(containers) ? containers : [containers];
|
|
94
87
|
const persistentElements = options.persistentElements?.map((fn) => fn()).filter(import_dom_query.isHTMLElement);
|
|
@@ -96,49 +89,36 @@ function trackDismissableElementImpl(node, options) {
|
|
|
96
89
|
return _containers.some((node2) => (0, import_dom_query.contains)(node2, target)) || import_layer_stack.layerStack.isInNestedLayer(node, target);
|
|
97
90
|
}
|
|
98
91
|
const cleanups = [
|
|
99
|
-
|
|
92
|
+
(0, import_layer_stack.isPointerBlocking)(layer) ? (0, import_pointer_event_outside.disablePointerEventsOutside)(node, options.persistentElements) : void 0,
|
|
100
93
|
(0, import_escape_keydown.trackEscapeKeydown)(node, onEscapeKeyDown),
|
|
101
94
|
(0, import_interact_outside.trackInteractOutside)(node, { exclude, onFocusOutside, onPointerDownOutside, defer: options.defer })
|
|
102
95
|
];
|
|
103
|
-
return () => {
|
|
104
|
-
import_layer_stack.layerStack.remove(node);
|
|
96
|
+
return (reason) => {
|
|
97
|
+
import_layer_stack.layerStack.remove(node, { reattach: reason === "restart" });
|
|
105
98
|
cleanups.forEach((fn) => fn?.());
|
|
106
99
|
};
|
|
107
100
|
}
|
|
108
101
|
function trackDismissableElement(nodeOrFn, options) {
|
|
109
|
-
const {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const node = (0, import_utils.isFunction)(nodeOrFn) ? nodeOrFn() : nodeOrFn;
|
|
115
|
-
cleanups.push(trackDismissableElementImpl(node, options));
|
|
116
|
-
})
|
|
117
|
-
);
|
|
118
|
-
return () => {
|
|
119
|
-
cleanups.forEach((fn) => fn?.());
|
|
120
|
-
};
|
|
102
|
+
const { warnOnMissingNode = true } = options;
|
|
103
|
+
return (0, import_dom_query.whenNode)(nodeOrFn, (node) => trackDismissableElementImpl(node, options), {
|
|
104
|
+
defer: options.defer,
|
|
105
|
+
onMissing: warnOnMissingNode ? () => (0, import_utils.warn)("[@zag-js/dismissable] node is `null` or `undefined`") : void 0
|
|
106
|
+
});
|
|
121
107
|
}
|
|
122
108
|
function trackDismissableBranch(nodeOrFn, options = {}) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
cleanups.push(
|
|
127
|
-
func(() => {
|
|
128
|
-
const node = (0, import_utils.isFunction)(nodeOrFn) ? nodeOrFn() : nodeOrFn;
|
|
129
|
-
if (!node) {
|
|
130
|
-
(0, import_utils.warn)("[@zag-js/dismissable] branch node is `null` or `undefined`");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
109
|
+
return (0, import_dom_query.whenNode)(
|
|
110
|
+
nodeOrFn,
|
|
111
|
+
(node) => {
|
|
133
112
|
import_layer_stack.layerStack.addBranch(node);
|
|
134
|
-
|
|
113
|
+
return () => {
|
|
135
114
|
import_layer_stack.layerStack.removeBranch(node);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
defer: options.defer,
|
|
119
|
+
onMissing: () => (0, import_utils.warn)("[@zag-js/dismissable] branch node is `null` or `undefined`")
|
|
120
|
+
}
|
|
138
121
|
);
|
|
139
|
-
return () => {
|
|
140
|
-
cleanups.forEach((fn) => fn?.());
|
|
141
|
-
};
|
|
142
122
|
}
|
|
143
123
|
// Annotate the CommonJS export names for ESM import in node:
|
|
144
124
|
0 && (module.exports = {
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
// src/dismissable-layer.ts
|
|
2
|
-
import { contains, getEventTarget, isHTMLElement,
|
|
2
|
+
import { contains, getEventTarget, isHTMLElement, whenNode } from "@zag-js/dom-query";
|
|
3
3
|
import {
|
|
4
4
|
trackInteractOutside
|
|
5
5
|
} from "@zag-js/interact-outside";
|
|
6
|
-
import {
|
|
6
|
+
import { warn } from "@zag-js/utils";
|
|
7
7
|
import { trackEscapeKeydown } from "./escape-keydown.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
isPointerBlocking,
|
|
10
|
+
layerStack
|
|
11
|
+
} from "./layer-stack.mjs";
|
|
9
12
|
import { disablePointerEventsOutside } from "./pointer-event-outside.mjs";
|
|
10
13
|
function trackDismissableElementImpl(node, options) {
|
|
11
|
-
const { warnOnMissingNode = true } = options;
|
|
12
|
-
if (warnOnMissingNode && !node) {
|
|
13
|
-
warn("[@zag-js/dismissable] node is `null` or `undefined`");
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
if (!node) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
14
|
const {
|
|
20
15
|
onDismiss,
|
|
21
16
|
onRequestDismiss,
|
|
@@ -23,12 +18,14 @@ function trackDismissableElementImpl(node, options) {
|
|
|
23
18
|
exclude: excludeContainers,
|
|
24
19
|
debug,
|
|
25
20
|
type = "dialog",
|
|
21
|
+
group,
|
|
26
22
|
onLayerChange
|
|
27
23
|
} = options;
|
|
28
24
|
const layer = {
|
|
29
25
|
dismiss: onDismiss,
|
|
30
26
|
node,
|
|
31
27
|
type,
|
|
28
|
+
group,
|
|
32
29
|
pointerBlocking,
|
|
33
30
|
requestDismiss: onRequestDismiss,
|
|
34
31
|
onLayerChange
|
|
@@ -65,7 +62,6 @@ function trackDismissableElementImpl(node, options) {
|
|
|
65
62
|
}
|
|
66
63
|
}
|
|
67
64
|
function exclude(target) {
|
|
68
|
-
if (!node) return false;
|
|
69
65
|
const containers = typeof excludeContainers === "function" ? excludeContainers() : excludeContainers;
|
|
70
66
|
const _containers = Array.isArray(containers) ? containers : [containers];
|
|
71
67
|
const persistentElements = options.persistentElements?.map((fn) => fn()).filter(isHTMLElement);
|
|
@@ -73,49 +69,36 @@ function trackDismissableElementImpl(node, options) {
|
|
|
73
69
|
return _containers.some((node2) => contains(node2, target)) || layerStack.isInNestedLayer(node, target);
|
|
74
70
|
}
|
|
75
71
|
const cleanups = [
|
|
76
|
-
|
|
72
|
+
isPointerBlocking(layer) ? disablePointerEventsOutside(node, options.persistentElements) : void 0,
|
|
77
73
|
trackEscapeKeydown(node, onEscapeKeyDown),
|
|
78
74
|
trackInteractOutside(node, { exclude, onFocusOutside, onPointerDownOutside, defer: options.defer })
|
|
79
75
|
];
|
|
80
|
-
return () => {
|
|
81
|
-
layerStack.remove(node);
|
|
76
|
+
return (reason) => {
|
|
77
|
+
layerStack.remove(node, { reattach: reason === "restart" });
|
|
82
78
|
cleanups.forEach((fn) => fn?.());
|
|
83
79
|
};
|
|
84
80
|
}
|
|
85
81
|
function trackDismissableElement(nodeOrFn, options) {
|
|
86
|
-
const {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const node = isFunction(nodeOrFn) ? nodeOrFn() : nodeOrFn;
|
|
92
|
-
cleanups.push(trackDismissableElementImpl(node, options));
|
|
93
|
-
})
|
|
94
|
-
);
|
|
95
|
-
return () => {
|
|
96
|
-
cleanups.forEach((fn) => fn?.());
|
|
97
|
-
};
|
|
82
|
+
const { warnOnMissingNode = true } = options;
|
|
83
|
+
return whenNode(nodeOrFn, (node) => trackDismissableElementImpl(node, options), {
|
|
84
|
+
defer: options.defer,
|
|
85
|
+
onMissing: warnOnMissingNode ? () => warn("[@zag-js/dismissable] node is `null` or `undefined`") : void 0
|
|
86
|
+
});
|
|
98
87
|
}
|
|
99
88
|
function trackDismissableBranch(nodeOrFn, options = {}) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
cleanups.push(
|
|
104
|
-
func(() => {
|
|
105
|
-
const node = isFunction(nodeOrFn) ? nodeOrFn() : nodeOrFn;
|
|
106
|
-
if (!node) {
|
|
107
|
-
warn("[@zag-js/dismissable] branch node is `null` or `undefined`");
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
89
|
+
return whenNode(
|
|
90
|
+
nodeOrFn,
|
|
91
|
+
(node) => {
|
|
110
92
|
layerStack.addBranch(node);
|
|
111
|
-
|
|
93
|
+
return () => {
|
|
112
94
|
layerStack.removeBranch(node);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
defer: options.defer,
|
|
99
|
+
onMissing: () => warn("[@zag-js/dismissable] branch node is `null` or `undefined`")
|
|
100
|
+
}
|
|
115
101
|
);
|
|
116
|
-
return () => {
|
|
117
|
-
cleanups.forEach((fn) => fn?.());
|
|
118
|
-
};
|
|
119
102
|
}
|
|
120
103
|
export {
|
|
121
104
|
trackDismissableBranch,
|
package/dist/index.d.mts
CHANGED
|
@@ -2,4 +2,5 @@ export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, Point
|
|
|
2
2
|
export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.mjs';
|
|
3
3
|
export { DismissableLayerStyle, DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle } from './layer-props.mjs';
|
|
4
4
|
export { LayerSnapshot, LayerType } from './layer-stack.mjs';
|
|
5
|
+
export { syncPointerEvents } from './pointer-event-outside.mjs';
|
|
5
6
|
import '@zag-js/utils';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, Point
|
|
|
2
2
|
export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.js';
|
|
3
3
|
export { DismissableLayerStyle, DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle } from './layer-props.js';
|
|
4
4
|
export { LayerSnapshot, LayerType } from './layer-stack.js';
|
|
5
|
+
export { syncPointerEvents } from './pointer-event-outside.js';
|
|
5
6
|
import '@zag-js/utils';
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
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
|
+
};
|
|
6
10
|
var __copyProps = (to, from, except, desc) => {
|
|
7
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
12
|
for (let key of __getOwnPropNames(from))
|
|
@@ -16,11 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
16
20
|
|
|
17
21
|
// src/index.ts
|
|
18
22
|
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
syncPointerEvents: () => import_pointer_event_outside.syncPointerEvents
|
|
25
|
+
});
|
|
19
26
|
module.exports = __toCommonJS(index_exports);
|
|
20
27
|
__reExport(index_exports, require("./dismissable-layer.js"), module.exports);
|
|
21
28
|
__reExport(index_exports, require("./layer-props.js"), module.exports);
|
|
29
|
+
var import_pointer_event_outside = require("./pointer-event-outside.js");
|
|
22
30
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23
31
|
0 && (module.exports = {
|
|
32
|
+
syncPointerEvents,
|
|
24
33
|
...require("./dismissable-layer.js"),
|
|
25
34
|
...require("./layer-props.js")
|
|
26
35
|
});
|
package/dist/index.mjs
CHANGED
package/dist/layer-props.js
CHANGED
|
@@ -26,18 +26,19 @@ __export(layer_props_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(layer_props_exports);
|
|
27
27
|
function getDismissableLayerAttrs(layer) {
|
|
28
28
|
return {
|
|
29
|
-
"data-nested": layer?.nested ? layer.type : void 0,
|
|
30
|
-
"data-has-nested": layer?.hasNested ? layer.type : void 0
|
|
29
|
+
"data-nested": layer?.active && layer.nested ? layer.type : void 0,
|
|
30
|
+
"data-has-nested": layer?.active && layer.hasNested ? layer.type : void 0
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function getDismissableLayerStyle(layer, options = {}) {
|
|
34
|
+
const active = layer?.active === true;
|
|
34
35
|
const style = {
|
|
35
|
-
"--layer-index":
|
|
36
|
-
"--nested-layer-count":
|
|
37
|
-
"--z-index": options.zIndex &&
|
|
36
|
+
"--layer-index": active ? `${layer.index}` : void 0,
|
|
37
|
+
"--nested-layer-count": active ? `${layer.nestedCount}` : void 0,
|
|
38
|
+
"--z-index": options.zIndex && active ? "var(--layer-index)" : void 0
|
|
38
39
|
};
|
|
39
40
|
if (options.pointerEvents) {
|
|
40
|
-
style.pointerEvents =
|
|
41
|
+
style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
|
|
41
42
|
}
|
|
42
43
|
return style;
|
|
43
44
|
}
|
package/dist/layer-props.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
// src/layer-props.ts
|
|
2
2
|
function getDismissableLayerAttrs(layer) {
|
|
3
3
|
return {
|
|
4
|
-
"data-nested": layer?.nested ? layer.type : void 0,
|
|
5
|
-
"data-has-nested": layer?.hasNested ? layer.type : void 0
|
|
4
|
+
"data-nested": layer?.active && layer.nested ? layer.type : void 0,
|
|
5
|
+
"data-has-nested": layer?.active && layer.hasNested ? layer.type : void 0
|
|
6
6
|
};
|
|
7
7
|
}
|
|
8
8
|
function getDismissableLayerStyle(layer, options = {}) {
|
|
9
|
+
const active = layer?.active === true;
|
|
9
10
|
const style = {
|
|
10
|
-
"--layer-index":
|
|
11
|
-
"--nested-layer-count":
|
|
12
|
-
"--z-index": options.zIndex &&
|
|
11
|
+
"--layer-index": active ? `${layer.index}` : void 0,
|
|
12
|
+
"--nested-layer-count": active ? `${layer.nestedCount}` : void 0,
|
|
13
|
+
"--z-index": options.zIndex && active ? "var(--layer-index)" : void 0
|
|
13
14
|
};
|
|
14
15
|
if (options.pointerEvents) {
|
|
15
|
-
style.pointerEvents =
|
|
16
|
+
style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
|
|
16
17
|
}
|
|
17
18
|
return style;
|
|
18
19
|
}
|
package/dist/layer-stack.d.mts
CHANGED
|
@@ -16,24 +16,43 @@ interface LayerSnapshot {
|
|
|
16
16
|
blocked: boolean;
|
|
17
17
|
}
|
|
18
18
|
interface Layer {
|
|
19
|
+
/** Assigned on first registration. */
|
|
20
|
+
id?: string | undefined;
|
|
21
|
+
/** The layer this one opened inside. Captured once and kept across re-registration. */
|
|
22
|
+
parentId?: string | undefined;
|
|
23
|
+
/** Layers sharing a group are peers, not ancestors. Used by menubar menus. */
|
|
24
|
+
group?: string | undefined;
|
|
19
25
|
dismiss: VoidFunction;
|
|
20
26
|
node: HTMLElement;
|
|
21
27
|
type: LayerType;
|
|
22
|
-
pointerBlocking?: boolean | undefined;
|
|
28
|
+
pointerBlocking?: boolean | (() => boolean) | undefined;
|
|
23
29
|
requestDismiss?: ((event: LayerDismissEvent) => void) | undefined;
|
|
24
30
|
onLayerChange?: ((snapshot: LayerSnapshot) => void) | undefined;
|
|
25
31
|
snapshot?: LayerSnapshot | undefined;
|
|
26
32
|
}
|
|
33
|
+
/** Resolved on read, so a layer's blocking can change without re-registering it. */
|
|
34
|
+
declare function isPointerBlocking(layer: Pick<Layer, "pointerBlocking">): boolean;
|
|
27
35
|
declare const layerStack: {
|
|
28
36
|
layers: Layer[];
|
|
29
37
|
branches: HTMLElement[];
|
|
30
38
|
recentlyRemoved: Set<HTMLElement>;
|
|
39
|
+
pendingReattach: Map<HTMLElement, {
|
|
40
|
+
id: string | undefined;
|
|
41
|
+
parentId: string | undefined;
|
|
42
|
+
index: number;
|
|
43
|
+
}>;
|
|
31
44
|
count(): number;
|
|
32
45
|
pointerBlockingLayers(): Layer[];
|
|
33
46
|
topMostPointerBlockingLayer(): Layer | undefined;
|
|
34
47
|
hasPointerBlockingLayer(): boolean;
|
|
35
48
|
isBelowPointerBlockingLayer(node: HTMLElement): boolean;
|
|
36
49
|
isTopMost(node: HTMLElement | null): boolean;
|
|
50
|
+
layerFor(node: HTMLElement | null): Layer | undefined;
|
|
51
|
+
/** The most recently added layer in the same group, if any. */
|
|
52
|
+
peerFor(group: string): Layer | undefined;
|
|
53
|
+
isDescendantOf(layer: Layer, ancestorId: string | undefined): boolean;
|
|
54
|
+
depthOf(layer: Layer): number;
|
|
55
|
+
/** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
|
|
37
56
|
getNestedLayers(node: HTMLElement): Layer[];
|
|
38
57
|
getLayersByType(type: LayerType): Layer[];
|
|
39
58
|
getNestedLayersByType(node: HTMLElement, type: LayerType): Layer[];
|
|
@@ -43,7 +62,9 @@ declare const layerStack: {
|
|
|
43
62
|
isInBranch(target: HTMLElement | EventTarget | null): boolean;
|
|
44
63
|
add(layer: Layer): void;
|
|
45
64
|
addBranch(node: HTMLElement): void;
|
|
46
|
-
remove(node: HTMLElement
|
|
65
|
+
remove(node: HTMLElement, options?: {
|
|
66
|
+
reattach?: boolean;
|
|
67
|
+
}): void;
|
|
47
68
|
removeBranch(node: HTMLElement): void;
|
|
48
69
|
syncLayers(): void;
|
|
49
70
|
indexOf(node: HTMLElement | undefined): number;
|
|
@@ -51,4 +72,4 @@ declare const layerStack: {
|
|
|
51
72
|
clear(): void;
|
|
52
73
|
};
|
|
53
74
|
|
|
54
|
-
export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, layerStack };
|
|
75
|
+
export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, isPointerBlocking, layerStack };
|
package/dist/layer-stack.d.ts
CHANGED
|
@@ -16,24 +16,43 @@ interface LayerSnapshot {
|
|
|
16
16
|
blocked: boolean;
|
|
17
17
|
}
|
|
18
18
|
interface Layer {
|
|
19
|
+
/** Assigned on first registration. */
|
|
20
|
+
id?: string | undefined;
|
|
21
|
+
/** The layer this one opened inside. Captured once and kept across re-registration. */
|
|
22
|
+
parentId?: string | undefined;
|
|
23
|
+
/** Layers sharing a group are peers, not ancestors. Used by menubar menus. */
|
|
24
|
+
group?: string | undefined;
|
|
19
25
|
dismiss: VoidFunction;
|
|
20
26
|
node: HTMLElement;
|
|
21
27
|
type: LayerType;
|
|
22
|
-
pointerBlocking?: boolean | undefined;
|
|
28
|
+
pointerBlocking?: boolean | (() => boolean) | undefined;
|
|
23
29
|
requestDismiss?: ((event: LayerDismissEvent) => void) | undefined;
|
|
24
30
|
onLayerChange?: ((snapshot: LayerSnapshot) => void) | undefined;
|
|
25
31
|
snapshot?: LayerSnapshot | undefined;
|
|
26
32
|
}
|
|
33
|
+
/** Resolved on read, so a layer's blocking can change without re-registering it. */
|
|
34
|
+
declare function isPointerBlocking(layer: Pick<Layer, "pointerBlocking">): boolean;
|
|
27
35
|
declare const layerStack: {
|
|
28
36
|
layers: Layer[];
|
|
29
37
|
branches: HTMLElement[];
|
|
30
38
|
recentlyRemoved: Set<HTMLElement>;
|
|
39
|
+
pendingReattach: Map<HTMLElement, {
|
|
40
|
+
id: string | undefined;
|
|
41
|
+
parentId: string | undefined;
|
|
42
|
+
index: number;
|
|
43
|
+
}>;
|
|
31
44
|
count(): number;
|
|
32
45
|
pointerBlockingLayers(): Layer[];
|
|
33
46
|
topMostPointerBlockingLayer(): Layer | undefined;
|
|
34
47
|
hasPointerBlockingLayer(): boolean;
|
|
35
48
|
isBelowPointerBlockingLayer(node: HTMLElement): boolean;
|
|
36
49
|
isTopMost(node: HTMLElement | null): boolean;
|
|
50
|
+
layerFor(node: HTMLElement | null): Layer | undefined;
|
|
51
|
+
/** The most recently added layer in the same group, if any. */
|
|
52
|
+
peerFor(group: string): Layer | undefined;
|
|
53
|
+
isDescendantOf(layer: Layer, ancestorId: string | undefined): boolean;
|
|
54
|
+
depthOf(layer: Layer): number;
|
|
55
|
+
/** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
|
|
37
56
|
getNestedLayers(node: HTMLElement): Layer[];
|
|
38
57
|
getLayersByType(type: LayerType): Layer[];
|
|
39
58
|
getNestedLayersByType(node: HTMLElement, type: LayerType): Layer[];
|
|
@@ -43,7 +62,9 @@ declare const layerStack: {
|
|
|
43
62
|
isInBranch(target: HTMLElement | EventTarget | null): boolean;
|
|
44
63
|
add(layer: Layer): void;
|
|
45
64
|
addBranch(node: HTMLElement): void;
|
|
46
|
-
remove(node: HTMLElement
|
|
65
|
+
remove(node: HTMLElement, options?: {
|
|
66
|
+
reattach?: boolean;
|
|
67
|
+
}): void;
|
|
47
68
|
removeBranch(node: HTMLElement): void;
|
|
48
69
|
syncLayers(): void;
|
|
49
70
|
indexOf(node: HTMLElement | undefined): number;
|
|
@@ -51,4 +72,4 @@ declare const layerStack: {
|
|
|
51
72
|
clear(): void;
|
|
52
73
|
};
|
|
53
74
|
|
|
54
|
-
export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, layerStack };
|
|
75
|
+
export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, isPointerBlocking, layerStack };
|
package/dist/layer-stack.js
CHANGED
|
@@ -20,21 +20,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/layer-stack.ts
|
|
21
21
|
var layer_stack_exports = {};
|
|
22
22
|
__export(layer_stack_exports, {
|
|
23
|
+
isPointerBlocking: () => isPointerBlocking,
|
|
23
24
|
layerStack: () => layerStack
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(layer_stack_exports);
|
|
26
27
|
var import_dom_query = require("@zag-js/dom-query");
|
|
27
28
|
var import_utils = require("@zag-js/utils");
|
|
28
29
|
var LAYER_REQUEST_DISMISS_EVENT = "layer:request-dismiss";
|
|
30
|
+
var layerId = 0;
|
|
31
|
+
function isPointerBlocking(layer) {
|
|
32
|
+
const value = layer.pointerBlocking;
|
|
33
|
+
return typeof value === "function" ? value() : !!value;
|
|
34
|
+
}
|
|
29
35
|
var layerStack = {
|
|
30
36
|
layers: [],
|
|
31
37
|
branches: [],
|
|
32
38
|
recentlyRemoved: /* @__PURE__ */ new Set(),
|
|
39
|
+
pendingReattach: /* @__PURE__ */ new Map(),
|
|
33
40
|
count() {
|
|
34
41
|
return this.layers.length;
|
|
35
42
|
},
|
|
36
43
|
pointerBlockingLayers() {
|
|
37
|
-
return this.layers.filter(
|
|
44
|
+
return this.layers.filter(isPointerBlocking);
|
|
38
45
|
},
|
|
39
46
|
topMostPointerBlockingLayer() {
|
|
40
47
|
return [...this.pointerBlockingLayers()].slice(-1)[0];
|
|
@@ -51,21 +58,61 @@ var layerStack = {
|
|
|
51
58
|
const layer = this.layers[this.count() - 1];
|
|
52
59
|
return layer?.node === node;
|
|
53
60
|
},
|
|
61
|
+
layerFor(node) {
|
|
62
|
+
return this.layers.find((layer) => layer.node === node);
|
|
63
|
+
},
|
|
64
|
+
/** The most recently added layer in the same group, if any. */
|
|
65
|
+
peerFor(group) {
|
|
66
|
+
for (let i = this.count() - 1; i >= 0; i--) {
|
|
67
|
+
if (this.layers[i].group === group) return this.layers[i];
|
|
68
|
+
}
|
|
69
|
+
return void 0;
|
|
70
|
+
},
|
|
71
|
+
isDescendantOf(layer, ancestorId) {
|
|
72
|
+
if (!ancestorId) return false;
|
|
73
|
+
const seen = /* @__PURE__ */ new Set();
|
|
74
|
+
let parentId = layer.parentId;
|
|
75
|
+
while (parentId && !seen.has(parentId)) {
|
|
76
|
+
if (parentId === ancestorId) return true;
|
|
77
|
+
seen.add(parentId);
|
|
78
|
+
parentId = this.layers.find((l) => l.id === parentId)?.parentId;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
},
|
|
82
|
+
depthOf(layer) {
|
|
83
|
+
const seen = /* @__PURE__ */ new Set();
|
|
84
|
+
let depth = 0;
|
|
85
|
+
let parentId = layer.parentId;
|
|
86
|
+
while (parentId && !seen.has(parentId)) {
|
|
87
|
+
depth++;
|
|
88
|
+
seen.add(parentId);
|
|
89
|
+
parentId = this.layers.find((l) => l.id === parentId)?.parentId;
|
|
90
|
+
}
|
|
91
|
+
return depth;
|
|
92
|
+
},
|
|
93
|
+
/** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
|
|
54
94
|
getNestedLayers(node) {
|
|
55
|
-
|
|
95
|
+
const id = this.layerFor(node)?.id;
|
|
96
|
+
if (!id) return [];
|
|
97
|
+
return this.layers.filter((layer) => this.isDescendantOf(layer, id)).sort((a, b) => this.depthOf(a) - this.depthOf(b));
|
|
56
98
|
},
|
|
57
99
|
getLayersByType(type) {
|
|
58
100
|
return this.layers.filter((layer) => layer.type === type);
|
|
59
101
|
},
|
|
60
102
|
getNestedLayersByType(node, type) {
|
|
61
|
-
|
|
62
|
-
if (index === -1) return [];
|
|
63
|
-
return this.layers.slice(index + 1).filter((layer) => layer.type === type);
|
|
103
|
+
return this.getNestedLayers(node).filter((layer) => layer.type === type);
|
|
64
104
|
},
|
|
65
105
|
getParentLayerOfType(node, type) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
106
|
+
const seen = /* @__PURE__ */ new Set();
|
|
107
|
+
let parentId = this.layerFor(node)?.parentId;
|
|
108
|
+
while (parentId && !seen.has(parentId)) {
|
|
109
|
+
const parent = this.layers.find((l) => l.id === parentId);
|
|
110
|
+
if (!parent) return void 0;
|
|
111
|
+
if (parent.type === type) return parent;
|
|
112
|
+
seen.add(parentId);
|
|
113
|
+
parentId = parent.parentId;
|
|
114
|
+
}
|
|
115
|
+
return void 0;
|
|
69
116
|
},
|
|
70
117
|
countNestedLayersOfType(node, type) {
|
|
71
118
|
return this.getNestedLayersByType(node, type).length;
|
|
@@ -81,29 +128,48 @@ var layerStack = {
|
|
|
81
128
|
},
|
|
82
129
|
add(layer) {
|
|
83
130
|
const existingIndex = this.indexOf(layer.node);
|
|
131
|
+
const existing = existingIndex !== -1 ? this.layers[existingIndex] : void 0;
|
|
132
|
+
const pending = this.pendingReattach.get(layer.node);
|
|
133
|
+
if (existing) {
|
|
134
|
+
layer.id ?? (layer.id = existing.id);
|
|
135
|
+
layer.parentId = existing.parentId;
|
|
136
|
+
} else if (pending) {
|
|
137
|
+
layer.id ?? (layer.id = pending.id);
|
|
138
|
+
layer.parentId = pending.parentId;
|
|
139
|
+
} else {
|
|
140
|
+
layer.id ?? (layer.id = `layer-${++layerId}`);
|
|
141
|
+
const peer = layer.group ? this.peerFor(layer.group) : void 0;
|
|
142
|
+
layer.parentId = peer ? peer.parentId : layer.parentId ?? this.layers[this.count() - 1]?.id;
|
|
143
|
+
}
|
|
84
144
|
if (existingIndex !== -1) {
|
|
85
145
|
this.layers.splice(existingIndex, 1);
|
|
86
146
|
}
|
|
87
|
-
|
|
147
|
+
if (pending) {
|
|
148
|
+
this.pendingReattach.delete(layer.node);
|
|
149
|
+
this.layers.splice(Math.min(pending.index, this.count()), 0, layer);
|
|
150
|
+
} else {
|
|
151
|
+
this.layers.push(layer);
|
|
152
|
+
}
|
|
88
153
|
this.syncLayers();
|
|
89
154
|
},
|
|
90
155
|
addBranch(node) {
|
|
91
156
|
this.branches.push(node);
|
|
92
157
|
},
|
|
93
|
-
remove(node) {
|
|
158
|
+
remove(node, options) {
|
|
94
159
|
const index = this.indexOf(node);
|
|
95
160
|
if (index < 0) return;
|
|
96
161
|
const layer = this.layers[index];
|
|
162
|
+
if (options?.reattach) {
|
|
163
|
+
this.pendingReattach.set(node, { id: layer.id, parentId: layer.parentId, index });
|
|
164
|
+
} else {
|
|
165
|
+
this.recentlyRemoved.add(node);
|
|
166
|
+
(0, import_dom_query.nextTick)(() => this.recentlyRemoved.delete(node));
|
|
167
|
+
this.getNestedLayers(node).forEach((nested) => layerStack.dismiss(nested.node, node));
|
|
168
|
+
}
|
|
169
|
+
this.layers.splice(index, 1);
|
|
97
170
|
if (layer.snapshot) {
|
|
98
171
|
publishSnapshot(layer, { ...layer.snapshot, active: false, blocked: false });
|
|
99
172
|
}
|
|
100
|
-
this.recentlyRemoved.add(node);
|
|
101
|
-
(0, import_dom_query.nextTick)(() => this.recentlyRemoved.delete(node));
|
|
102
|
-
if (index < this.count() - 1) {
|
|
103
|
-
const _layers = this.getNestedLayers(node);
|
|
104
|
-
_layers.forEach((layer2) => layerStack.dismiss(layer2.node, node));
|
|
105
|
-
}
|
|
106
|
-
this.layers.splice(index, 1);
|
|
107
173
|
this.syncLayers();
|
|
108
174
|
},
|
|
109
175
|
removeBranch(node) {
|
|
@@ -167,5 +233,6 @@ function addListenerOnce(el, type, callback) {
|
|
|
167
233
|
}
|
|
168
234
|
// Annotate the CommonJS export names for ESM import in node:
|
|
169
235
|
0 && (module.exports = {
|
|
236
|
+
isPointerBlocking,
|
|
170
237
|
layerStack
|
|
171
238
|
});
|
package/dist/layer-stack.mjs
CHANGED
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
import { contains, nextTick } from "@zag-js/dom-query";
|
|
3
3
|
import { isEqual } from "@zag-js/utils";
|
|
4
4
|
var LAYER_REQUEST_DISMISS_EVENT = "layer:request-dismiss";
|
|
5
|
+
var layerId = 0;
|
|
6
|
+
function isPointerBlocking(layer) {
|
|
7
|
+
const value = layer.pointerBlocking;
|
|
8
|
+
return typeof value === "function" ? value() : !!value;
|
|
9
|
+
}
|
|
5
10
|
var layerStack = {
|
|
6
11
|
layers: [],
|
|
7
12
|
branches: [],
|
|
8
13
|
recentlyRemoved: /* @__PURE__ */ new Set(),
|
|
14
|
+
pendingReattach: /* @__PURE__ */ new Map(),
|
|
9
15
|
count() {
|
|
10
16
|
return this.layers.length;
|
|
11
17
|
},
|
|
12
18
|
pointerBlockingLayers() {
|
|
13
|
-
return this.layers.filter(
|
|
19
|
+
return this.layers.filter(isPointerBlocking);
|
|
14
20
|
},
|
|
15
21
|
topMostPointerBlockingLayer() {
|
|
16
22
|
return [...this.pointerBlockingLayers()].slice(-1)[0];
|
|
@@ -27,21 +33,61 @@ var layerStack = {
|
|
|
27
33
|
const layer = this.layers[this.count() - 1];
|
|
28
34
|
return layer?.node === node;
|
|
29
35
|
},
|
|
36
|
+
layerFor(node) {
|
|
37
|
+
return this.layers.find((layer) => layer.node === node);
|
|
38
|
+
},
|
|
39
|
+
/** The most recently added layer in the same group, if any. */
|
|
40
|
+
peerFor(group) {
|
|
41
|
+
for (let i = this.count() - 1; i >= 0; i--) {
|
|
42
|
+
if (this.layers[i].group === group) return this.layers[i];
|
|
43
|
+
}
|
|
44
|
+
return void 0;
|
|
45
|
+
},
|
|
46
|
+
isDescendantOf(layer, ancestorId) {
|
|
47
|
+
if (!ancestorId) return false;
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
let parentId = layer.parentId;
|
|
50
|
+
while (parentId && !seen.has(parentId)) {
|
|
51
|
+
if (parentId === ancestorId) return true;
|
|
52
|
+
seen.add(parentId);
|
|
53
|
+
parentId = this.layers.find((l) => l.id === parentId)?.parentId;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
},
|
|
57
|
+
depthOf(layer) {
|
|
58
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59
|
+
let depth = 0;
|
|
60
|
+
let parentId = layer.parentId;
|
|
61
|
+
while (parentId && !seen.has(parentId)) {
|
|
62
|
+
depth++;
|
|
63
|
+
seen.add(parentId);
|
|
64
|
+
parentId = this.layers.find((l) => l.id === parentId)?.parentId;
|
|
65
|
+
}
|
|
66
|
+
return depth;
|
|
67
|
+
},
|
|
68
|
+
/** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
|
|
30
69
|
getNestedLayers(node) {
|
|
31
|
-
|
|
70
|
+
const id = this.layerFor(node)?.id;
|
|
71
|
+
if (!id) return [];
|
|
72
|
+
return this.layers.filter((layer) => this.isDescendantOf(layer, id)).sort((a, b) => this.depthOf(a) - this.depthOf(b));
|
|
32
73
|
},
|
|
33
74
|
getLayersByType(type) {
|
|
34
75
|
return this.layers.filter((layer) => layer.type === type);
|
|
35
76
|
},
|
|
36
77
|
getNestedLayersByType(node, type) {
|
|
37
|
-
|
|
38
|
-
if (index === -1) return [];
|
|
39
|
-
return this.layers.slice(index + 1).filter((layer) => layer.type === type);
|
|
78
|
+
return this.getNestedLayers(node).filter((layer) => layer.type === type);
|
|
40
79
|
},
|
|
41
80
|
getParentLayerOfType(node, type) {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
81
|
+
const seen = /* @__PURE__ */ new Set();
|
|
82
|
+
let parentId = this.layerFor(node)?.parentId;
|
|
83
|
+
while (parentId && !seen.has(parentId)) {
|
|
84
|
+
const parent = this.layers.find((l) => l.id === parentId);
|
|
85
|
+
if (!parent) return void 0;
|
|
86
|
+
if (parent.type === type) return parent;
|
|
87
|
+
seen.add(parentId);
|
|
88
|
+
parentId = parent.parentId;
|
|
89
|
+
}
|
|
90
|
+
return void 0;
|
|
45
91
|
},
|
|
46
92
|
countNestedLayersOfType(node, type) {
|
|
47
93
|
return this.getNestedLayersByType(node, type).length;
|
|
@@ -57,29 +103,48 @@ var layerStack = {
|
|
|
57
103
|
},
|
|
58
104
|
add(layer) {
|
|
59
105
|
const existingIndex = this.indexOf(layer.node);
|
|
106
|
+
const existing = existingIndex !== -1 ? this.layers[existingIndex] : void 0;
|
|
107
|
+
const pending = this.pendingReattach.get(layer.node);
|
|
108
|
+
if (existing) {
|
|
109
|
+
layer.id ?? (layer.id = existing.id);
|
|
110
|
+
layer.parentId = existing.parentId;
|
|
111
|
+
} else if (pending) {
|
|
112
|
+
layer.id ?? (layer.id = pending.id);
|
|
113
|
+
layer.parentId = pending.parentId;
|
|
114
|
+
} else {
|
|
115
|
+
layer.id ?? (layer.id = `layer-${++layerId}`);
|
|
116
|
+
const peer = layer.group ? this.peerFor(layer.group) : void 0;
|
|
117
|
+
layer.parentId = peer ? peer.parentId : layer.parentId ?? this.layers[this.count() - 1]?.id;
|
|
118
|
+
}
|
|
60
119
|
if (existingIndex !== -1) {
|
|
61
120
|
this.layers.splice(existingIndex, 1);
|
|
62
121
|
}
|
|
63
|
-
|
|
122
|
+
if (pending) {
|
|
123
|
+
this.pendingReattach.delete(layer.node);
|
|
124
|
+
this.layers.splice(Math.min(pending.index, this.count()), 0, layer);
|
|
125
|
+
} else {
|
|
126
|
+
this.layers.push(layer);
|
|
127
|
+
}
|
|
64
128
|
this.syncLayers();
|
|
65
129
|
},
|
|
66
130
|
addBranch(node) {
|
|
67
131
|
this.branches.push(node);
|
|
68
132
|
},
|
|
69
|
-
remove(node) {
|
|
133
|
+
remove(node, options) {
|
|
70
134
|
const index = this.indexOf(node);
|
|
71
135
|
if (index < 0) return;
|
|
72
136
|
const layer = this.layers[index];
|
|
137
|
+
if (options?.reattach) {
|
|
138
|
+
this.pendingReattach.set(node, { id: layer.id, parentId: layer.parentId, index });
|
|
139
|
+
} else {
|
|
140
|
+
this.recentlyRemoved.add(node);
|
|
141
|
+
nextTick(() => this.recentlyRemoved.delete(node));
|
|
142
|
+
this.getNestedLayers(node).forEach((nested) => layerStack.dismiss(nested.node, node));
|
|
143
|
+
}
|
|
144
|
+
this.layers.splice(index, 1);
|
|
73
145
|
if (layer.snapshot) {
|
|
74
146
|
publishSnapshot(layer, { ...layer.snapshot, active: false, blocked: false });
|
|
75
147
|
}
|
|
76
|
-
this.recentlyRemoved.add(node);
|
|
77
|
-
nextTick(() => this.recentlyRemoved.delete(node));
|
|
78
|
-
if (index < this.count() - 1) {
|
|
79
|
-
const _layers = this.getNestedLayers(node);
|
|
80
|
-
_layers.forEach((layer2) => layerStack.dismiss(layer2.node, node));
|
|
81
|
-
}
|
|
82
|
-
this.layers.splice(index, 1);
|
|
83
148
|
this.syncLayers();
|
|
84
149
|
},
|
|
85
150
|
removeBranch(node) {
|
|
@@ -142,5 +207,6 @@ function addListenerOnce(el, type, callback) {
|
|
|
142
207
|
el.addEventListener(type, callback, { once: true });
|
|
143
208
|
}
|
|
144
209
|
export {
|
|
210
|
+
isPointerBlocking,
|
|
145
211
|
layerStack
|
|
146
212
|
};
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-derives pointer blocking from the stack. Needed after a layer's `pointerBlocking` getter
|
|
3
|
+
* changes value, since nothing was added or removed to trigger the usual sync.
|
|
4
|
+
*/
|
|
5
|
+
declare function syncPointerEvents(node: HTMLElement): void;
|
|
1
6
|
declare function disablePointerEventsOutside(node: HTMLElement, persistentElements?: Array<() => Element | null>): () => void;
|
|
2
7
|
|
|
3
|
-
export { disablePointerEventsOutside };
|
|
8
|
+
export { disablePointerEventsOutside, syncPointerEvents };
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-derives pointer blocking from the stack. Needed after a layer's `pointerBlocking` getter
|
|
3
|
+
* changes value, since nothing was added or removed to trigger the usual sync.
|
|
4
|
+
*/
|
|
5
|
+
declare function syncPointerEvents(node: HTMLElement): void;
|
|
1
6
|
declare function disablePointerEventsOutside(node: HTMLElement, persistentElements?: Array<() => Element | null>): () => void;
|
|
2
7
|
|
|
3
|
-
export { disablePointerEventsOutside };
|
|
8
|
+
export { disablePointerEventsOutside, syncPointerEvents };
|
|
@@ -20,24 +20,45 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/pointer-event-outside.ts
|
|
21
21
|
var pointer_event_outside_exports = {};
|
|
22
22
|
__export(pointer_event_outside_exports, {
|
|
23
|
-
disablePointerEventsOutside: () => disablePointerEventsOutside
|
|
23
|
+
disablePointerEventsOutside: () => disablePointerEventsOutside,
|
|
24
|
+
syncPointerEvents: () => syncPointerEvents
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(pointer_event_outside_exports);
|
|
26
27
|
var import_dom_query = require("@zag-js/dom-query");
|
|
27
28
|
var import_layer_stack = require("./layer-stack.js");
|
|
28
29
|
var originalBodyPointerEvents = /* @__PURE__ */ new WeakMap();
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
function syncBodyPointerEvents(doc) {
|
|
31
|
+
const body = doc.body;
|
|
32
|
+
if (!body) return;
|
|
33
|
+
const shouldBlock = import_layer_stack.layerStack.hasPointerBlockingLayer();
|
|
34
|
+
if (shouldBlock === body.hasAttribute("data-inert")) return;
|
|
35
|
+
if (shouldBlock) {
|
|
36
|
+
originalBodyPointerEvents.set(body, body.style.pointerEvents);
|
|
34
37
|
queueMicrotask(() => {
|
|
35
|
-
|
|
36
|
-
if (!body) return;
|
|
38
|
+
if (!import_layer_stack.layerStack.hasPointerBlockingLayer()) return;
|
|
37
39
|
body.style.pointerEvents = "none";
|
|
38
40
|
body.setAttribute("data-inert", "");
|
|
39
41
|
});
|
|
42
|
+
return;
|
|
40
43
|
}
|
|
44
|
+
queueMicrotask(() => {
|
|
45
|
+
if (import_layer_stack.layerStack.hasPointerBlockingLayer()) return;
|
|
46
|
+
const original = originalBodyPointerEvents.get(body);
|
|
47
|
+
if (original !== void 0) {
|
|
48
|
+
body.style.pointerEvents = original;
|
|
49
|
+
originalBodyPointerEvents.delete(body);
|
|
50
|
+
}
|
|
51
|
+
body.removeAttribute("data-inert");
|
|
52
|
+
if (body.style.length === 0) body.removeAttribute("style");
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function syncPointerEvents(node) {
|
|
56
|
+
syncBodyPointerEvents((0, import_dom_query.getDocument)(node));
|
|
57
|
+
}
|
|
58
|
+
function disablePointerEventsOutside(node, persistentElements) {
|
|
59
|
+
const doc = (0, import_dom_query.getDocument)(node);
|
|
60
|
+
const cleanups = [];
|
|
61
|
+
syncBodyPointerEvents(doc);
|
|
41
62
|
persistentElements?.forEach((el) => {
|
|
42
63
|
const [promise, abort] = (0, import_dom_query.waitForElement)(
|
|
43
64
|
() => {
|
|
@@ -50,22 +71,12 @@ function disablePointerEventsOutside(node, persistentElements) {
|
|
|
50
71
|
cleanups.push(abort);
|
|
51
72
|
});
|
|
52
73
|
return () => {
|
|
53
|
-
|
|
54
|
-
queueMicrotask(() => {
|
|
55
|
-
const body = doc.body;
|
|
56
|
-
if (!body) return;
|
|
57
|
-
const original = originalBodyPointerEvents.get(body);
|
|
58
|
-
if (original !== void 0) {
|
|
59
|
-
body.style.pointerEvents = original;
|
|
60
|
-
originalBodyPointerEvents.delete(body);
|
|
61
|
-
}
|
|
62
|
-
body.removeAttribute("data-inert");
|
|
63
|
-
if (body.style.length === 0) body.removeAttribute("style");
|
|
64
|
-
});
|
|
74
|
+
syncBodyPointerEvents(doc);
|
|
65
75
|
cleanups.forEach((fn) => fn());
|
|
66
76
|
};
|
|
67
77
|
}
|
|
68
78
|
// Annotate the CommonJS export names for ESM import in node:
|
|
69
79
|
0 && (module.exports = {
|
|
70
|
-
disablePointerEventsOutside
|
|
80
|
+
disablePointerEventsOutside,
|
|
81
|
+
syncPointerEvents
|
|
71
82
|
});
|
|
@@ -2,18 +2,38 @@
|
|
|
2
2
|
import { getDocument, isHTMLElement, setStyle, waitForElement } from "@zag-js/dom-query";
|
|
3
3
|
import { layerStack } from "./layer-stack.mjs";
|
|
4
4
|
var originalBodyPointerEvents = /* @__PURE__ */ new WeakMap();
|
|
5
|
-
function
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
function syncBodyPointerEvents(doc) {
|
|
6
|
+
const body = doc.body;
|
|
7
|
+
if (!body) return;
|
|
8
|
+
const shouldBlock = layerStack.hasPointerBlockingLayer();
|
|
9
|
+
if (shouldBlock === body.hasAttribute("data-inert")) return;
|
|
10
|
+
if (shouldBlock) {
|
|
11
|
+
originalBodyPointerEvents.set(body, body.style.pointerEvents);
|
|
10
12
|
queueMicrotask(() => {
|
|
11
|
-
|
|
12
|
-
if (!body) return;
|
|
13
|
+
if (!layerStack.hasPointerBlockingLayer()) return;
|
|
13
14
|
body.style.pointerEvents = "none";
|
|
14
15
|
body.setAttribute("data-inert", "");
|
|
15
16
|
});
|
|
17
|
+
return;
|
|
16
18
|
}
|
|
19
|
+
queueMicrotask(() => {
|
|
20
|
+
if (layerStack.hasPointerBlockingLayer()) return;
|
|
21
|
+
const original = originalBodyPointerEvents.get(body);
|
|
22
|
+
if (original !== void 0) {
|
|
23
|
+
body.style.pointerEvents = original;
|
|
24
|
+
originalBodyPointerEvents.delete(body);
|
|
25
|
+
}
|
|
26
|
+
body.removeAttribute("data-inert");
|
|
27
|
+
if (body.style.length === 0) body.removeAttribute("style");
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function syncPointerEvents(node) {
|
|
31
|
+
syncBodyPointerEvents(getDocument(node));
|
|
32
|
+
}
|
|
33
|
+
function disablePointerEventsOutside(node, persistentElements) {
|
|
34
|
+
const doc = getDocument(node);
|
|
35
|
+
const cleanups = [];
|
|
36
|
+
syncBodyPointerEvents(doc);
|
|
17
37
|
persistentElements?.forEach((el) => {
|
|
18
38
|
const [promise, abort] = waitForElement(
|
|
19
39
|
() => {
|
|
@@ -26,21 +46,11 @@ function disablePointerEventsOutside(node, persistentElements) {
|
|
|
26
46
|
cleanups.push(abort);
|
|
27
47
|
});
|
|
28
48
|
return () => {
|
|
29
|
-
|
|
30
|
-
queueMicrotask(() => {
|
|
31
|
-
const body = doc.body;
|
|
32
|
-
if (!body) return;
|
|
33
|
-
const original = originalBodyPointerEvents.get(body);
|
|
34
|
-
if (original !== void 0) {
|
|
35
|
-
body.style.pointerEvents = original;
|
|
36
|
-
originalBodyPointerEvents.delete(body);
|
|
37
|
-
}
|
|
38
|
-
body.removeAttribute("data-inert");
|
|
39
|
-
if (body.style.length === 0) body.removeAttribute("style");
|
|
40
|
-
});
|
|
49
|
+
syncBodyPointerEvents(doc);
|
|
41
50
|
cleanups.forEach((fn) => fn());
|
|
42
51
|
};
|
|
43
52
|
}
|
|
44
53
|
export {
|
|
45
|
-
disablePointerEventsOutside
|
|
54
|
+
disablePointerEventsOutside,
|
|
55
|
+
syncPointerEvents
|
|
46
56
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/dismissable",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.3",
|
|
4
4
|
"description": "Dismissable layer utilities for the DOM",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@zag-js/
|
|
30
|
-
"@zag-js/
|
|
31
|
-
"@zag-js/
|
|
29
|
+
"@zag-js/interact-outside": "2.0.0-next.3",
|
|
30
|
+
"@zag-js/dom-query": "2.0.0-next.3",
|
|
31
|
+
"@zag-js/utils": "2.0.0-next.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"clean-package": "2.2.0"
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "tsup",
|
|
58
58
|
"test": "vitest",
|
|
59
|
-
"lint": "
|
|
59
|
+
"lint": "oxlint src",
|
|
60
60
|
"test-ci": "pnpm test --ci --runInBand -u",
|
|
61
61
|
"test-watch": "pnpm test --watchAll"
|
|
62
62
|
}
|