@zag-js/dismissable 2.0.0-next.0 → 2.0.0-next.2

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.
@@ -1,6 +1,6 @@
1
1
  import { InteractOutsideHandlers } from '@zag-js/interact-outside';
2
- import { MaybeFunction } from '@zag-js/utils';
3
- import { LayerDismissEvent, LayerStyleTarget, LayerType } from './layer-stack.mjs';
2
+ import { MaybeFunction, TeardownReason } from '@zag-js/utils';
3
+ import { LayerDismissEvent, LayerSnapshot, LayerType } from './layer-stack.mjs';
4
4
 
5
5
  type MaybeElement = HTMLElement | null;
6
6
  type Container = MaybeElement | Array<MaybeElement>;
@@ -25,11 +25,9 @@ interface PersistentElementOptions {
25
25
  }
26
26
  interface DismissableElementOptions extends DismissableElementHandlers, PersistentElementOptions {
27
27
  /**
28
- * Extra elements that receive the same layer stack CSS vars, `data-*`, and `--z-index`
29
- * (from the primary node's computed `z-index`) as the dismissable node
30
- * (e.g. dialog backdrop + positioner when the node is content).
28
+ * Function called when the layer's position or nesting state changes.
31
29
  */
32
- layerStyleTargets?: LayerStyleTarget[] | undefined;
30
+ onLayerChange: (snapshot: LayerSnapshot) => void;
33
31
  /**
34
32
  * Whether to log debug information
35
33
  */
@@ -37,7 +35,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
37
35
  /**
38
36
  * Whether to block pointer events outside the dismissable element
39
37
  */
40
- pointerBlocking?: boolean | undefined;
38
+ pointerBlocking?: boolean | (() => boolean) | undefined;
41
39
  /**
42
40
  * Function called when the dismissable element is dismissed
43
41
  */
@@ -59,7 +57,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
59
57
  */
60
58
  type?: LayerType | undefined;
61
59
  }
62
- declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): () => void;
60
+ declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): (args_0?: TeardownReason | undefined) => void;
63
61
  declare function trackDismissableBranch(nodeOrFn: NodeOrFn, options?: {
64
62
  defer?: boolean | undefined;
65
63
  }): () => void;
@@ -1,6 +1,6 @@
1
1
  import { InteractOutsideHandlers } from '@zag-js/interact-outside';
2
- import { MaybeFunction } from '@zag-js/utils';
3
- import { LayerDismissEvent, LayerStyleTarget, LayerType } from './layer-stack.js';
2
+ import { MaybeFunction, TeardownReason } from '@zag-js/utils';
3
+ import { LayerDismissEvent, LayerSnapshot, LayerType } from './layer-stack.js';
4
4
 
5
5
  type MaybeElement = HTMLElement | null;
6
6
  type Container = MaybeElement | Array<MaybeElement>;
@@ -25,11 +25,9 @@ interface PersistentElementOptions {
25
25
  }
26
26
  interface DismissableElementOptions extends DismissableElementHandlers, PersistentElementOptions {
27
27
  /**
28
- * Extra elements that receive the same layer stack CSS vars, `data-*`, and `--z-index`
29
- * (from the primary node's computed `z-index`) as the dismissable node
30
- * (e.g. dialog backdrop + positioner when the node is content).
28
+ * Function called when the layer's position or nesting state changes.
31
29
  */
32
- layerStyleTargets?: LayerStyleTarget[] | undefined;
30
+ onLayerChange: (snapshot: LayerSnapshot) => void;
33
31
  /**
34
32
  * Whether to log debug information
35
33
  */
@@ -37,7 +35,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
37
35
  /**
38
36
  * Whether to block pointer events outside the dismissable element
39
37
  */
40
- pointerBlocking?: boolean | undefined;
38
+ pointerBlocking?: boolean | (() => boolean) | undefined;
41
39
  /**
42
40
  * Function called when the dismissable element is dismissed
43
41
  */
@@ -59,7 +57,7 @@ interface DismissableElementOptions extends DismissableElementHandlers, Persiste
59
57
  */
60
58
  type?: LayerType | undefined;
61
59
  }
62
- declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): () => void;
60
+ declare function trackDismissableElement(nodeOrFn: NodeOrFn, options: DismissableElementOptions): (args_0?: TeardownReason | undefined) => void;
63
61
  declare function trackDismissableBranch(nodeOrFn: NodeOrFn, options?: {
64
62
  defer?: boolean | undefined;
65
63
  }): () => 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,7 +38,7 @@ function trackDismissableElementImpl(node, options) {
46
38
  exclude: excludeContainers,
47
39
  debug,
48
40
  type = "dialog",
49
- layerStyleTargets
41
+ onLayerChange
50
42
  } = options;
51
43
  const layer = {
52
44
  dismiss: onDismiss,
@@ -54,10 +46,9 @@ function trackDismissableElementImpl(node, options) {
54
46
  type,
55
47
  pointerBlocking,
56
48
  requestDismiss: onRequestDismiss,
57
- styleTargets: layerStyleTargets
49
+ onLayerChange
58
50
  };
59
51
  import_layer_stack.layerStack.add(layer);
60
- (0, import_pointer_event_outside.assignPointerEventToLayers)();
61
52
  function onPointerDownOutside(event) {
62
53
  const target = (0, import_dom_query.getEventTarget)(event.detail.originalEvent);
63
54
  if (import_layer_stack.layerStack.isBelowPointerBlockingLayer(node) || import_layer_stack.layerStack.isInBranch(target)) return;
@@ -89,7 +80,6 @@ function trackDismissableElementImpl(node, options) {
89
80
  }
90
81
  }
91
82
  function exclude(target) {
92
- if (!node) return false;
93
83
  const containers = typeof excludeContainers === "function" ? excludeContainers() : excludeContainers;
94
84
  const _containers = Array.isArray(containers) ? containers : [containers];
95
85
  const persistentElements = options.persistentElements?.map((fn) => fn()).filter(import_dom_query.isHTMLElement);
@@ -97,51 +87,36 @@ function trackDismissableElementImpl(node, options) {
97
87
  return _containers.some((node2) => (0, import_dom_query.contains)(node2, target)) || import_layer_stack.layerStack.isInNestedLayer(node, target);
98
88
  }
99
89
  const cleanups = [
100
- pointerBlocking ? (0, import_pointer_event_outside.disablePointerEventsOutside)(node, options.persistentElements) : void 0,
90
+ (0, import_layer_stack.isPointerBlocking)(layer) ? (0, import_pointer_event_outside.disablePointerEventsOutside)(node, options.persistentElements) : void 0,
101
91
  (0, import_escape_keydown.trackEscapeKeydown)(node, onEscapeKeyDown),
102
92
  (0, import_interact_outside.trackInteractOutside)(node, { exclude, onFocusOutside, onPointerDownOutside, defer: options.defer })
103
93
  ];
104
- return () => {
105
- import_layer_stack.layerStack.remove(node);
106
- (0, import_pointer_event_outside.assignPointerEventToLayers)();
107
- (0, import_pointer_event_outside.clearPointerEvent)(node);
94
+ return (reason) => {
95
+ import_layer_stack.layerStack.remove(node, { reattach: reason === "restart" });
108
96
  cleanups.forEach((fn) => fn?.());
109
97
  };
110
98
  }
111
99
  function trackDismissableElement(nodeOrFn, options) {
112
- const { defer } = options;
113
- const func = defer ? import_dom_query.raf : (v) => v();
114
- const cleanups = [];
115
- cleanups.push(
116
- func(() => {
117
- const node = (0, import_utils.isFunction)(nodeOrFn) ? nodeOrFn() : nodeOrFn;
118
- cleanups.push(trackDismissableElementImpl(node, options));
119
- })
120
- );
121
- return () => {
122
- cleanups.forEach((fn) => fn?.());
123
- };
100
+ const { warnOnMissingNode = true } = options;
101
+ return (0, import_dom_query.whenNode)(nodeOrFn, (node) => trackDismissableElementImpl(node, options), {
102
+ defer: options.defer,
103
+ onMissing: warnOnMissingNode ? () => (0, import_utils.warn)("[@zag-js/dismissable] node is `null` or `undefined`") : void 0
104
+ });
124
105
  }
125
106
  function trackDismissableBranch(nodeOrFn, options = {}) {
126
- const { defer } = options;
127
- const func = defer ? import_dom_query.raf : (v) => v();
128
- const cleanups = [];
129
- cleanups.push(
130
- func(() => {
131
- const node = (0, import_utils.isFunction)(nodeOrFn) ? nodeOrFn() : nodeOrFn;
132
- if (!node) {
133
- (0, import_utils.warn)("[@zag-js/dismissable] branch node is `null` or `undefined`");
134
- return;
135
- }
107
+ return (0, import_dom_query.whenNode)(
108
+ nodeOrFn,
109
+ (node) => {
136
110
  import_layer_stack.layerStack.addBranch(node);
137
- cleanups.push(() => {
111
+ return () => {
138
112
  import_layer_stack.layerStack.removeBranch(node);
139
- });
140
- })
113
+ };
114
+ },
115
+ {
116
+ defer: options.defer,
117
+ onMissing: () => (0, import_utils.warn)("[@zag-js/dismissable] branch node is `null` or `undefined`")
118
+ }
141
119
  );
142
- return () => {
143
- cleanups.forEach((fn) => fn?.());
144
- };
145
120
  }
146
121
  // Annotate the CommonJS export names for ESM import in node:
147
122
  0 && (module.exports = {
@@ -1,21 +1,16 @@
1
1
  // src/dismissable-layer.ts
2
- import { contains, getEventTarget, isHTMLElement, raf } from "@zag-js/dom-query";
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 { isFunction, warn } from "@zag-js/utils";
6
+ import { warn } from "@zag-js/utils";
7
7
  import { trackEscapeKeydown } from "./escape-keydown.mjs";
8
- import { layerStack } from "./layer-stack.mjs";
9
- import { assignPointerEventToLayers, clearPointerEvent, disablePointerEventsOutside } from "./pointer-event-outside.mjs";
8
+ import {
9
+ isPointerBlocking,
10
+ layerStack
11
+ } from "./layer-stack.mjs";
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,7 +18,7 @@ function trackDismissableElementImpl(node, options) {
23
18
  exclude: excludeContainers,
24
19
  debug,
25
20
  type = "dialog",
26
- layerStyleTargets
21
+ onLayerChange
27
22
  } = options;
28
23
  const layer = {
29
24
  dismiss: onDismiss,
@@ -31,10 +26,9 @@ function trackDismissableElementImpl(node, options) {
31
26
  type,
32
27
  pointerBlocking,
33
28
  requestDismiss: onRequestDismiss,
34
- styleTargets: layerStyleTargets
29
+ onLayerChange
35
30
  };
36
31
  layerStack.add(layer);
37
- assignPointerEventToLayers();
38
32
  function onPointerDownOutside(event) {
39
33
  const target = getEventTarget(event.detail.originalEvent);
40
34
  if (layerStack.isBelowPointerBlockingLayer(node) || layerStack.isInBranch(target)) return;
@@ -66,7 +60,6 @@ function trackDismissableElementImpl(node, options) {
66
60
  }
67
61
  }
68
62
  function exclude(target) {
69
- if (!node) return false;
70
63
  const containers = typeof excludeContainers === "function" ? excludeContainers() : excludeContainers;
71
64
  const _containers = Array.isArray(containers) ? containers : [containers];
72
65
  const persistentElements = options.persistentElements?.map((fn) => fn()).filter(isHTMLElement);
@@ -74,51 +67,36 @@ function trackDismissableElementImpl(node, options) {
74
67
  return _containers.some((node2) => contains(node2, target)) || layerStack.isInNestedLayer(node, target);
75
68
  }
76
69
  const cleanups = [
77
- pointerBlocking ? disablePointerEventsOutside(node, options.persistentElements) : void 0,
70
+ isPointerBlocking(layer) ? disablePointerEventsOutside(node, options.persistentElements) : void 0,
78
71
  trackEscapeKeydown(node, onEscapeKeyDown),
79
72
  trackInteractOutside(node, { exclude, onFocusOutside, onPointerDownOutside, defer: options.defer })
80
73
  ];
81
- return () => {
82
- layerStack.remove(node);
83
- assignPointerEventToLayers();
84
- clearPointerEvent(node);
74
+ return (reason) => {
75
+ layerStack.remove(node, { reattach: reason === "restart" });
85
76
  cleanups.forEach((fn) => fn?.());
86
77
  };
87
78
  }
88
79
  function trackDismissableElement(nodeOrFn, options) {
89
- const { defer } = options;
90
- const func = defer ? raf : (v) => v();
91
- const cleanups = [];
92
- cleanups.push(
93
- func(() => {
94
- const node = isFunction(nodeOrFn) ? nodeOrFn() : nodeOrFn;
95
- cleanups.push(trackDismissableElementImpl(node, options));
96
- })
97
- );
98
- return () => {
99
- cleanups.forEach((fn) => fn?.());
100
- };
80
+ const { warnOnMissingNode = true } = options;
81
+ return whenNode(nodeOrFn, (node) => trackDismissableElementImpl(node, options), {
82
+ defer: options.defer,
83
+ onMissing: warnOnMissingNode ? () => warn("[@zag-js/dismissable] node is `null` or `undefined`") : void 0
84
+ });
101
85
  }
102
86
  function trackDismissableBranch(nodeOrFn, options = {}) {
103
- const { defer } = options;
104
- const func = defer ? raf : (v) => v();
105
- const cleanups = [];
106
- cleanups.push(
107
- func(() => {
108
- const node = isFunction(nodeOrFn) ? nodeOrFn() : nodeOrFn;
109
- if (!node) {
110
- warn("[@zag-js/dismissable] branch node is `null` or `undefined`");
111
- return;
112
- }
87
+ return whenNode(
88
+ nodeOrFn,
89
+ (node) => {
113
90
  layerStack.addBranch(node);
114
- cleanups.push(() => {
91
+ return () => {
115
92
  layerStack.removeBranch(node);
116
- });
117
- })
93
+ };
94
+ },
95
+ {
96
+ defer: options.defer,
97
+ onMissing: () => warn("[@zag-js/dismissable] branch node is `null` or `undefined`")
98
+ }
118
99
  );
119
- return () => {
120
- cleanups.forEach((fn) => fn?.());
121
- };
122
100
  }
123
101
  export {
124
102
  trackDismissableBranch,
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, PointerDownOutsideEvent } from '@zag-js/interact-outside';
2
2
  export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.mjs';
3
- export { LayerStyleTarget, LayerType } from './layer-stack.mjs';
3
+ export { DismissableLayerStyle, DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle } from './layer-props.mjs';
4
+ export { LayerSnapshot, LayerType } from './layer-stack.mjs';
5
+ export { syncPointerEvents } from './pointer-event-outside.mjs';
4
6
  import '@zag-js/utils';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, PointerDownOutsideEvent } from '@zag-js/interact-outside';
2
2
  export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.js';
3
- export { LayerStyleTarget, LayerType } from './layer-stack.js';
3
+ export { DismissableLayerStyle, DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle } from './layer-props.js';
4
+ export { LayerSnapshot, LayerType } from './layer-stack.js';
5
+ export { syncPointerEvents } from './pointer-event-outside.js';
4
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,9 +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);
28
+ __reExport(index_exports, require("./layer-props.js"), module.exports);
29
+ var import_pointer_event_outside = require("./pointer-event-outside.js");
21
30
  // Annotate the CommonJS export names for ESM import in node:
22
31
  0 && (module.exports = {
23
- ...require("./dismissable-layer.js")
32
+ syncPointerEvents,
33
+ ...require("./dismissable-layer.js"),
34
+ ...require("./layer-props.js")
24
35
  });
package/dist/index.mjs CHANGED
@@ -1,2 +1,7 @@
1
1
  // src/index.ts
2
2
  export * from "./dismissable-layer.mjs";
3
+ export * from "./layer-props.mjs";
4
+ import { syncPointerEvents } from "./pointer-event-outside.mjs";
5
+ export {
6
+ syncPointerEvents
7
+ };
@@ -0,0 +1,30 @@
1
+ import { LayerSnapshot, LayerType } from './layer-stack.mjs';
2
+
3
+ declare function getDismissableLayerAttrs(layer: LayerSnapshot | null | undefined): {
4
+ "data-nested": LayerType | undefined;
5
+ "data-has-nested": LayerType | undefined;
6
+ };
7
+ interface DismissableLayerStyleOptions {
8
+ /**
9
+ * Set `--z-index: var(--layer-index)` on the element that establishes the actual
10
+ * stacking context (backdrop / positioner). Content parts sit inside that stacking
11
+ * context already, so they don't need this.
12
+ */
13
+ zIndex?: boolean;
14
+ /**
15
+ * Set `pointer-events: none` while a pointer-blocking layer sits above this one.
16
+ * Omit for elements (like popper positioners) that already manage their own
17
+ * `pointer-events`.
18
+ */
19
+ pointerEvents?: boolean;
20
+ }
21
+ interface DismissableLayerStyle {
22
+ [key: string]: string | undefined;
23
+ "--layer-index"?: string | undefined;
24
+ "--nested-layer-count"?: string | undefined;
25
+ "--z-index"?: string | undefined;
26
+ pointerEvents?: "none" | "auto" | undefined;
27
+ }
28
+ declare function getDismissableLayerStyle(layer: LayerSnapshot | null | undefined, options?: DismissableLayerStyleOptions): DismissableLayerStyle;
29
+
30
+ export { type DismissableLayerStyle, type DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle };
@@ -0,0 +1,30 @@
1
+ import { LayerSnapshot, LayerType } from './layer-stack.js';
2
+
3
+ declare function getDismissableLayerAttrs(layer: LayerSnapshot | null | undefined): {
4
+ "data-nested": LayerType | undefined;
5
+ "data-has-nested": LayerType | undefined;
6
+ };
7
+ interface DismissableLayerStyleOptions {
8
+ /**
9
+ * Set `--z-index: var(--layer-index)` on the element that establishes the actual
10
+ * stacking context (backdrop / positioner). Content parts sit inside that stacking
11
+ * context already, so they don't need this.
12
+ */
13
+ zIndex?: boolean;
14
+ /**
15
+ * Set `pointer-events: none` while a pointer-blocking layer sits above this one.
16
+ * Omit for elements (like popper positioners) that already manage their own
17
+ * `pointer-events`.
18
+ */
19
+ pointerEvents?: boolean;
20
+ }
21
+ interface DismissableLayerStyle {
22
+ [key: string]: string | undefined;
23
+ "--layer-index"?: string | undefined;
24
+ "--nested-layer-count"?: string | undefined;
25
+ "--z-index"?: string | undefined;
26
+ pointerEvents?: "none" | "auto" | undefined;
27
+ }
28
+ declare function getDismissableLayerStyle(layer: LayerSnapshot | null | undefined, options?: DismissableLayerStyleOptions): DismissableLayerStyle;
29
+
30
+ export { type DismissableLayerStyle, type DismissableLayerStyleOptions, getDismissableLayerAttrs, getDismissableLayerStyle };
@@ -0,0 +1,49 @@
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/layer-props.ts
21
+ var layer_props_exports = {};
22
+ __export(layer_props_exports, {
23
+ getDismissableLayerAttrs: () => getDismissableLayerAttrs,
24
+ getDismissableLayerStyle: () => getDismissableLayerStyle
25
+ });
26
+ module.exports = __toCommonJS(layer_props_exports);
27
+ function getDismissableLayerAttrs(layer) {
28
+ return {
29
+ "data-nested": layer?.active && layer.nested ? layer.type : void 0,
30
+ "data-has-nested": layer?.active && layer.hasNested ? layer.type : void 0
31
+ };
32
+ }
33
+ function getDismissableLayerStyle(layer, options = {}) {
34
+ const active = layer?.active === true;
35
+ const style = {
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
39
+ };
40
+ if (options.pointerEvents) {
41
+ style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
42
+ }
43
+ return style;
44
+ }
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ getDismissableLayerAttrs,
48
+ getDismissableLayerStyle
49
+ });
@@ -0,0 +1,23 @@
1
+ // src/layer-props.ts
2
+ function getDismissableLayerAttrs(layer) {
3
+ return {
4
+ "data-nested": layer?.active && layer.nested ? layer.type : void 0,
5
+ "data-has-nested": layer?.active && layer.hasNested ? layer.type : void 0
6
+ };
7
+ }
8
+ function getDismissableLayerStyle(layer, options = {}) {
9
+ const active = layer?.active === true;
10
+ const style = {
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
14
+ };
15
+ if (options.pointerEvents) {
16
+ style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
17
+ }
18
+ return style;
19
+ }
20
+ export {
21
+ getDismissableLayerAttrs,
22
+ getDismissableLayerStyle
23
+ };
@@ -6,25 +6,49 @@ type LayerDismissEventDetail = {
6
6
  targetIndex: number;
7
7
  };
8
8
  type LayerDismissEvent = CustomEvent<LayerDismissEventDetail>;
9
- type LayerStyleTarget = () => HTMLElement | null;
9
+ interface LayerSnapshot {
10
+ active: boolean;
11
+ type: LayerType;
12
+ index: number;
13
+ nested: boolean;
14
+ hasNested: boolean;
15
+ nestedCount: number;
16
+ blocked: boolean;
17
+ }
10
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;
11
23
  dismiss: VoidFunction;
12
24
  node: HTMLElement;
13
25
  type: LayerType;
14
- pointerBlocking?: boolean | undefined;
26
+ pointerBlocking?: boolean | (() => boolean) | undefined;
15
27
  requestDismiss?: ((event: LayerDismissEvent) => void) | undefined;
16
- styleTargets?: LayerStyleTarget[] | undefined;
28
+ onLayerChange?: ((snapshot: LayerSnapshot) => void) | undefined;
29
+ snapshot?: LayerSnapshot | undefined;
17
30
  }
31
+ /** Resolved on read, so a layer's blocking can change without re-registering it. */
32
+ declare function isPointerBlocking(layer: Pick<Layer, "pointerBlocking">): boolean;
18
33
  declare const layerStack: {
19
34
  layers: Layer[];
20
35
  branches: HTMLElement[];
21
36
  recentlyRemoved: Set<HTMLElement>;
37
+ pendingReattach: Map<HTMLElement, {
38
+ id: string | undefined;
39
+ parentId: string | undefined;
40
+ index: number;
41
+ }>;
22
42
  count(): number;
23
43
  pointerBlockingLayers(): Layer[];
24
44
  topMostPointerBlockingLayer(): Layer | undefined;
25
45
  hasPointerBlockingLayer(): boolean;
26
46
  isBelowPointerBlockingLayer(node: HTMLElement): boolean;
27
47
  isTopMost(node: HTMLElement | null): boolean;
48
+ layerFor(node: HTMLElement | null): Layer | undefined;
49
+ isDescendantOf(layer: Layer, ancestorId: string | undefined): boolean;
50
+ depthOf(layer: Layer): number;
51
+ /** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
28
52
  getNestedLayers(node: HTMLElement): Layer[];
29
53
  getLayersByType(type: LayerType): Layer[];
30
54
  getNestedLayersByType(node: HTMLElement, type: LayerType): Layer[];
@@ -34,7 +58,9 @@ declare const layerStack: {
34
58
  isInBranch(target: HTMLElement | EventTarget | null): boolean;
35
59
  add(layer: Layer): void;
36
60
  addBranch(node: HTMLElement): void;
37
- remove(node: HTMLElement): void;
61
+ remove(node: HTMLElement, options?: {
62
+ reattach?: boolean;
63
+ }): void;
38
64
  removeBranch(node: HTMLElement): void;
39
65
  syncLayers(): void;
40
66
  indexOf(node: HTMLElement | undefined): number;
@@ -42,4 +68,4 @@ declare const layerStack: {
42
68
  clear(): void;
43
69
  };
44
70
 
45
- export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerStyleTarget, type LayerType, layerStack };
71
+ export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, isPointerBlocking, layerStack };
@@ -6,25 +6,49 @@ type LayerDismissEventDetail = {
6
6
  targetIndex: number;
7
7
  };
8
8
  type LayerDismissEvent = CustomEvent<LayerDismissEventDetail>;
9
- type LayerStyleTarget = () => HTMLElement | null;
9
+ interface LayerSnapshot {
10
+ active: boolean;
11
+ type: LayerType;
12
+ index: number;
13
+ nested: boolean;
14
+ hasNested: boolean;
15
+ nestedCount: number;
16
+ blocked: boolean;
17
+ }
10
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;
11
23
  dismiss: VoidFunction;
12
24
  node: HTMLElement;
13
25
  type: LayerType;
14
- pointerBlocking?: boolean | undefined;
26
+ pointerBlocking?: boolean | (() => boolean) | undefined;
15
27
  requestDismiss?: ((event: LayerDismissEvent) => void) | undefined;
16
- styleTargets?: LayerStyleTarget[] | undefined;
28
+ onLayerChange?: ((snapshot: LayerSnapshot) => void) | undefined;
29
+ snapshot?: LayerSnapshot | undefined;
17
30
  }
31
+ /** Resolved on read, so a layer's blocking can change without re-registering it. */
32
+ declare function isPointerBlocking(layer: Pick<Layer, "pointerBlocking">): boolean;
18
33
  declare const layerStack: {
19
34
  layers: Layer[];
20
35
  branches: HTMLElement[];
21
36
  recentlyRemoved: Set<HTMLElement>;
37
+ pendingReattach: Map<HTMLElement, {
38
+ id: string | undefined;
39
+ parentId: string | undefined;
40
+ index: number;
41
+ }>;
22
42
  count(): number;
23
43
  pointerBlockingLayers(): Layer[];
24
44
  topMostPointerBlockingLayer(): Layer | undefined;
25
45
  hasPointerBlockingLayer(): boolean;
26
46
  isBelowPointerBlockingLayer(node: HTMLElement): boolean;
27
47
  isTopMost(node: HTMLElement | null): boolean;
48
+ layerFor(node: HTMLElement | null): Layer | undefined;
49
+ isDescendantOf(layer: Layer, ancestorId: string | undefined): boolean;
50
+ depthOf(layer: Layer): number;
51
+ /** Descendants, shallowest first, so a cascade dismisses parents before their own children. */
28
52
  getNestedLayers(node: HTMLElement): Layer[];
29
53
  getLayersByType(type: LayerType): Layer[];
30
54
  getNestedLayersByType(node: HTMLElement, type: LayerType): Layer[];
@@ -34,7 +58,9 @@ declare const layerStack: {
34
58
  isInBranch(target: HTMLElement | EventTarget | null): boolean;
35
59
  add(layer: Layer): void;
36
60
  addBranch(node: HTMLElement): void;
37
- remove(node: HTMLElement): void;
61
+ remove(node: HTMLElement, options?: {
62
+ reattach?: boolean;
63
+ }): void;
38
64
  removeBranch(node: HTMLElement): void;
39
65
  syncLayers(): void;
40
66
  indexOf(node: HTMLElement | undefined): number;
@@ -42,4 +68,4 @@ declare const layerStack: {
42
68
  clear(): void;
43
69
  };
44
70
 
45
- export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerStyleTarget, type LayerType, layerStack };
71
+ export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerSnapshot, type LayerType, isPointerBlocking, layerStack };