@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.
@@ -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
- pointerBlocking ? (0, import_pointer_event_outside.disablePointerEventsOutside)(node, options.persistentElements) : void 0,
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 { defer } = options;
110
- const func = defer ? import_dom_query.raf : (v) => v();
111
- const cleanups = [];
112
- cleanups.push(
113
- func(() => {
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
- const { defer } = options;
124
- const func = defer ? import_dom_query.raf : (v) => v();
125
- const cleanups = [];
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
- cleanups.push(() => {
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, 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";
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
- pointerBlocking ? disablePointerEventsOutside(node, options.persistentElements) : void 0,
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 { defer } = options;
87
- const func = defer ? raf : (v) => v();
88
- const cleanups = [];
89
- cleanups.push(
90
- func(() => {
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
- const { defer } = options;
101
- const func = defer ? raf : (v) => v();
102
- const cleanups = [];
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
- cleanups.push(() => {
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
@@ -1,3 +1,7 @@
1
1
  // src/index.ts
2
2
  export * from "./dismissable-layer.mjs";
3
3
  export * from "./layer-props.mjs";
4
+ import { syncPointerEvents } from "./pointer-event-outside.mjs";
5
+ export {
6
+ syncPointerEvents
7
+ };
@@ -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": layer ? `${layer.index}` : void 0,
36
- "--nested-layer-count": layer ? `${layer.nestedCount}` : void 0,
37
- "--z-index": options.zIndex && layer ? "var(--layer-index)" : void 0
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 = layer?.active ? layer.blocked ? "none" : "auto" : void 0;
41
+ style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
41
42
  }
42
43
  return style;
43
44
  }
@@ -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": layer ? `${layer.index}` : void 0,
11
- "--nested-layer-count": layer ? `${layer.nestedCount}` : void 0,
12
- "--z-index": options.zIndex && layer ? "var(--layer-index)" : void 0
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 = layer?.active ? layer.blocked ? "none" : "auto" : void 0;
16
+ style.pointerEvents = active ? layer.blocked ? "none" : "auto" : void 0;
16
17
  }
17
18
  return style;
18
19
  }
@@ -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): void;
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 };
@@ -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): void;
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 };
@@ -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((layer) => layer.pointerBlocking);
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
- return Array.from(this.layers).slice(this.indexOf(node) + 1);
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
- const index = this.indexOf(node);
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 index = this.indexOf(node);
67
- if (index <= 0) return void 0;
68
- return this.layers.slice(0, index).reverse().find((layer) => layer.type === type);
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
- this.layers.push(layer);
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
  });
@@ -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((layer) => layer.pointerBlocking);
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
- return Array.from(this.layers).slice(this.indexOf(node) + 1);
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
- const index = this.indexOf(node);
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 index = this.indexOf(node);
43
- if (index <= 0) return void 0;
44
- return this.layers.slice(0, index).reverse().find((layer) => layer.type === type);
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
- this.layers.push(layer);
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 disablePointerEventsOutside(node, persistentElements) {
30
- const doc = (0, import_dom_query.getDocument)(node);
31
- const cleanups = [];
32
- if (import_layer_stack.layerStack.hasPointerBlockingLayer() && !doc.body.hasAttribute("data-inert")) {
33
- originalBodyPointerEvents.set(doc.body, doc.body.style.pointerEvents);
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
- const body = doc.body;
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
- if (import_layer_stack.layerStack.hasPointerBlockingLayer()) return;
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 disablePointerEventsOutside(node, persistentElements) {
6
- const doc = getDocument(node);
7
- const cleanups = [];
8
- if (layerStack.hasPointerBlockingLayer() && !doc.body.hasAttribute("data-inert")) {
9
- originalBodyPointerEvents.set(doc.body, doc.body.style.pointerEvents);
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
- const body = doc.body;
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
- if (layerStack.hasPointerBlockingLayer()) return;
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.1",
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/dom-query": "2.0.0-next.1",
30
- "@zag-js/utils": "2.0.0-next.1",
31
- "@zag-js/interact-outside": "2.0.0-next.1"
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": "eslint src",
59
+ "lint": "oxlint src",
60
60
  "test-ci": "pnpm test --ci --runInBand -u",
61
61
  "test-watch": "pnpm test --watchAll"
62
62
  }