@zag-js/aria-hidden 2.0.0-next.2 → 2.0.0-next.4

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,3 @@
1
- declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
2
- declare const inertOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
3
- declare const suppressOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
4
-
5
- export { hideOthers, inertOthers, suppressOthers };
1
+ export declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
2
+ export declare const inertOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
3
+ export declare const suppressOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
@@ -1,5 +1,3 @@
1
- declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
2
- declare const inertOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
3
- declare const suppressOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
4
-
5
- export { hideOthers, inertOthers, suppressOthers };
1
+ export declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
2
+ export declare const inertOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement | null, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
3
+ export declare const suppressOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string, followControlledElements?: boolean) => VoidFunction | undefined;
@@ -1,63 +1,34 @@
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/aria-hidden.ts
21
- var aria_hidden_exports = {};
22
- __export(aria_hidden_exports, {
23
- hideOthers: () => hideOthers,
24
- inertOthers: () => inertOthers,
25
- suppressOthers: () => suppressOthers
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
26
4
  });
27
- module.exports = __toCommonJS(aria_hidden_exports);
28
- var import_walk_tree_outside = require("./walk-tree-outside.js");
29
- var getParentNode = (originalTarget) => {
30
- const target = Array.isArray(originalTarget) ? originalTarget[0] : originalTarget;
31
- return target.ownerDocument.body;
5
+ const require_walk_tree_outside = require("./walk-tree-outside.js");
6
+ // src/aria-hidden.ts
7
+ const getParentNode = (originalTarget) => {
8
+ return (Array.isArray(originalTarget) ? originalTarget[0] : originalTarget).ownerDocument.body;
32
9
  };
33
- var hideOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-aria-hidden", followControlledElements = true) => {
34
- if (!parentNode) return;
35
- return (0, import_walk_tree_outside.walkTreeOutside)(originalTarget, {
36
- parentNode,
37
- markerName,
38
- controlAttribute: "aria-hidden",
39
- explicitBooleanValue: true,
40
- followControlledElements
41
- });
10
+ const hideOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-aria-hidden", followControlledElements = true) => {
11
+ if (!parentNode) return;
12
+ return require_walk_tree_outside.walkTreeOutside(originalTarget, {
13
+ parentNode,
14
+ markerName,
15
+ attribute: "aria-hidden",
16
+ followControlledElements
17
+ });
42
18
  };
43
- var inertOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-inerted", followControlledElements = true) => {
44
- if (!parentNode) return;
45
- return (0, import_walk_tree_outside.walkTreeOutside)(originalTarget, {
46
- parentNode,
47
- markerName,
48
- controlAttribute: "inert",
49
- explicitBooleanValue: false,
50
- followControlledElements
51
- });
19
+ const inertOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-inerted", followControlledElements = true) => {
20
+ if (!parentNode) return;
21
+ return require_walk_tree_outside.walkTreeOutside(originalTarget, {
22
+ parentNode,
23
+ markerName,
24
+ attribute: "inert",
25
+ followControlledElements
26
+ });
52
27
  };
53
- var supportsInert = () => typeof HTMLElement !== "undefined" && HTMLElement.prototype.hasOwnProperty("inert");
54
- var suppressOthers = (originalTarget, parentNode, markerName = "data-suppressed", followControlledElements = true) => {
55
- const fn = supportsInert() ? inertOthers : hideOthers;
56
- return fn(originalTarget, parentNode, markerName, followControlledElements);
28
+ const supportsInert = () => typeof HTMLElement !== "undefined" && HTMLElement.prototype.hasOwnProperty("inert");
29
+ const suppressOthers = (originalTarget, parentNode, markerName = "data-suppressed", followControlledElements = true) => {
30
+ return (supportsInert() ? inertOthers : hideOthers)(originalTarget, parentNode, markerName, followControlledElements);
57
31
  };
58
- // Annotate the CommonJS export names for ESM import in node:
59
- 0 && (module.exports = {
60
- hideOthers,
61
- inertOthers,
62
- suppressOthers
63
- });
32
+ exports.hideOthers = hideOthers;
33
+ exports.inertOthers = inertOthers;
34
+ exports.suppressOthers = suppressOthers;
@@ -1,36 +1,28 @@
1
- // src/aria-hidden.ts
2
1
  import { walkTreeOutside } from "./walk-tree-outside.mjs";
3
- var getParentNode = (originalTarget) => {
4
- const target = Array.isArray(originalTarget) ? originalTarget[0] : originalTarget;
5
- return target.ownerDocument.body;
6
- };
7
- var hideOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-aria-hidden", followControlledElements = true) => {
8
- if (!parentNode) return;
9
- return walkTreeOutside(originalTarget, {
10
- parentNode,
11
- markerName,
12
- controlAttribute: "aria-hidden",
13
- explicitBooleanValue: true,
14
- followControlledElements
15
- });
2
+ // src/aria-hidden.ts
3
+ const getParentNode = (originalTarget) => {
4
+ return (Array.isArray(originalTarget) ? originalTarget[0] : originalTarget).ownerDocument.body;
16
5
  };
17
- var inertOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-inerted", followControlledElements = true) => {
18
- if (!parentNode) return;
19
- return walkTreeOutside(originalTarget, {
20
- parentNode,
21
- markerName,
22
- controlAttribute: "inert",
23
- explicitBooleanValue: false,
24
- followControlledElements
25
- });
6
+ const hideOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-aria-hidden", followControlledElements = true) => {
7
+ if (!parentNode) return;
8
+ return walkTreeOutside(originalTarget, {
9
+ parentNode,
10
+ markerName,
11
+ attribute: "aria-hidden",
12
+ followControlledElements
13
+ });
26
14
  };
27
- var supportsInert = () => typeof HTMLElement !== "undefined" && HTMLElement.prototype.hasOwnProperty("inert");
28
- var suppressOthers = (originalTarget, parentNode, markerName = "data-suppressed", followControlledElements = true) => {
29
- const fn = supportsInert() ? inertOthers : hideOthers;
30
- return fn(originalTarget, parentNode, markerName, followControlledElements);
15
+ const inertOthers = (originalTarget, parentNode = getParentNode(originalTarget), markerName = "data-inerted", followControlledElements = true) => {
16
+ if (!parentNode) return;
17
+ return walkTreeOutside(originalTarget, {
18
+ parentNode,
19
+ markerName,
20
+ attribute: "inert",
21
+ followControlledElements
22
+ });
31
23
  };
32
- export {
33
- hideOthers,
34
- inertOthers,
35
- suppressOthers
24
+ const supportsInert = () => typeof HTMLElement !== "undefined" && HTMLElement.prototype.hasOwnProperty("inert");
25
+ const suppressOthers = (originalTarget, parentNode, markerName = "data-suppressed", followControlledElements = true) => {
26
+ return (supportsInert() ? inertOthers : hideOthers)(originalTarget, parentNode, markerName, followControlledElements);
36
27
  };
28
+ export { hideOthers, inertOthers, suppressOthers };
package/dist/index.d.mts CHANGED
@@ -2,8 +2,7 @@ type MaybeElement = HTMLElement | null;
2
2
  type Targets = Array<MaybeElement>;
3
3
  type TargetsOrFn = Targets | (() => Targets);
4
4
  type Options = {
5
- defer?: boolean | undefined;
5
+ defer?: boolean | undefined;
6
6
  };
7
- declare function ariaHidden(targetsOrFn: TargetsOrFn, options?: Options): () => void;
8
-
9
- export { ariaHidden };
7
+ export declare function ariaHidden(targetsOrFn: TargetsOrFn, options?: Options): () => void;
8
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,8 +2,7 @@ type MaybeElement = HTMLElement | null;
2
2
  type Targets = Array<MaybeElement>;
3
3
  type TargetsOrFn = Targets | (() => Targets);
4
4
  type Options = {
5
- defer?: boolean | undefined;
5
+ defer?: boolean | undefined;
6
6
  };
7
- declare function ariaHidden(targetsOrFn: TargetsOrFn, options?: Options): () => void;
8
-
9
- export { ariaHidden };
7
+ export declare function ariaHidden(targetsOrFn: TargetsOrFn, options?: Options): () => void;
8
+ export {};
package/dist/index.js CHANGED
@@ -1,50 +1,24 @@
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/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- ariaHidden: () => ariaHidden
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
24
4
  });
25
- module.exports = __toCommonJS(index_exports);
26
- var import_aria_hidden = require("./aria-hidden.js");
27
- var raf = (fn) => {
28
- const frameId = requestAnimationFrame(() => fn());
29
- return () => cancelAnimationFrame(frameId);
5
+ const require_aria_hidden = require("./aria-hidden.js");
6
+ // src/index.ts
7
+ const raf = (fn) => {
8
+ const frameId = requestAnimationFrame(() => fn());
9
+ return () => cancelAnimationFrame(frameId);
30
10
  };
31
11
  function ariaHidden(targetsOrFn, options = {}) {
32
- const { defer = true } = options;
33
- const func = defer ? raf : (v) => v();
34
- const cleanups = [];
35
- cleanups.push(
36
- func(() => {
37
- const targets = typeof targetsOrFn === "function" ? targetsOrFn() : targetsOrFn;
38
- const elements = targets.filter(Boolean);
39
- if (elements.length === 0) return;
40
- cleanups.push((0, import_aria_hidden.hideOthers)(elements));
41
- })
42
- );
43
- return () => {
44
- cleanups.forEach((fn) => fn?.());
45
- };
12
+ const { defer = true } = options;
13
+ const func = defer ? raf : (v) => v();
14
+ const cleanups = [];
15
+ cleanups.push(func(() => {
16
+ const elements = (typeof targetsOrFn === "function" ? targetsOrFn() : targetsOrFn).filter(Boolean);
17
+ if (elements.length === 0) return;
18
+ cleanups.push(require_aria_hidden.hideOthers(elements));
19
+ }));
20
+ return () => {
21
+ cleanups.forEach((fn) => fn?.());
22
+ };
46
23
  }
47
- // Annotate the CommonJS export names for ESM import in node:
48
- 0 && (module.exports = {
49
- ariaHidden
50
- });
24
+ exports.ariaHidden = ariaHidden;
package/dist/index.mjs CHANGED
@@ -1,25 +1,20 @@
1
- // src/index.ts
2
1
  import { hideOthers } from "./aria-hidden.mjs";
3
- var raf = (fn) => {
4
- const frameId = requestAnimationFrame(() => fn());
5
- return () => cancelAnimationFrame(frameId);
2
+ // src/index.ts
3
+ const raf = (fn) => {
4
+ const frameId = requestAnimationFrame(() => fn());
5
+ return () => cancelAnimationFrame(frameId);
6
6
  };
7
7
  function ariaHidden(targetsOrFn, options = {}) {
8
- const { defer = true } = options;
9
- const func = defer ? raf : (v) => v();
10
- const cleanups = [];
11
- cleanups.push(
12
- func(() => {
13
- const targets = typeof targetsOrFn === "function" ? targetsOrFn() : targetsOrFn;
14
- const elements = targets.filter(Boolean);
15
- if (elements.length === 0) return;
16
- cleanups.push(hideOthers(elements));
17
- })
18
- );
19
- return () => {
20
- cleanups.forEach((fn) => fn?.());
21
- };
8
+ const { defer = true } = options;
9
+ const func = defer ? raf : (v) => v();
10
+ const cleanups = [];
11
+ cleanups.push(func(() => {
12
+ const elements = (typeof targetsOrFn === "function" ? targetsOrFn() : targetsOrFn).filter(Boolean);
13
+ if (elements.length === 0) return;
14
+ cleanups.push(hideOthers(elements));
15
+ }));
16
+ return () => {
17
+ cleanups.forEach((fn) => fn?.());
18
+ };
22
19
  }
23
- export {
24
- ariaHidden
25
- };
20
+ export { ariaHidden };
@@ -1,10 +1,8 @@
1
1
  interface WalkTreeOutsideOptions {
2
- parentNode: HTMLElement;
3
- markerName: string;
4
- controlAttribute: string;
5
- explicitBooleanValue: boolean;
6
- followControlledElements?: boolean;
2
+ parentNode: HTMLElement;
3
+ markerName: string;
4
+ attribute: "aria-hidden" | "inert";
5
+ followControlledElements?: boolean;
7
6
  }
8
- declare const walkTreeOutside: (originalTarget: Element | Element[], props: WalkTreeOutsideOptions) => VoidFunction;
9
-
10
- export { walkTreeOutside };
7
+ export declare const walkTreeOutside: (originalTarget: Element | Element[], props: WalkTreeOutsideOptions) => VoidFunction;
8
+ export {};
@@ -1,10 +1,8 @@
1
1
  interface WalkTreeOutsideOptions {
2
- parentNode: HTMLElement;
3
- markerName: string;
4
- controlAttribute: string;
5
- explicitBooleanValue: boolean;
6
- followControlledElements?: boolean;
2
+ parentNode: HTMLElement;
3
+ markerName: string;
4
+ attribute: "aria-hidden" | "inert";
5
+ followControlledElements?: boolean;
7
6
  }
8
- declare const walkTreeOutside: (originalTarget: Element | Element[], props: WalkTreeOutsideOptions) => VoidFunction;
9
-
10
- export { walkTreeOutside };
7
+ export declare const walkTreeOutside: (originalTarget: Element | Element[], props: WalkTreeOutsideOptions) => VoidFunction;
8
+ export {};
@@ -1,132 +1,159 @@
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/walk-tree-outside.ts
21
- var walk_tree_outside_exports = {};
22
- __export(walk_tree_outside_exports, {
23
- walkTreeOutside: () => walkTreeOutside
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
24
4
  });
25
- module.exports = __toCommonJS(walk_tree_outside_exports);
26
- var import_dom_query = require("@zag-js/dom-query");
27
- var counterMap = /* @__PURE__ */ new WeakMap();
28
- var uncontrolledNodes = /* @__PURE__ */ new WeakMap();
29
- var markerMap = {};
30
- var lockCount = 0;
31
- var unwrapHost = (node) => node && (node.host || unwrapHost(node.parentNode));
32
- var correctTargets = (parent, targets) => targets.map((target) => {
33
- if (parent.contains(target)) return target;
34
- const correctedTarget = unwrapHost(target);
35
- if (correctedTarget && parent.contains(correctedTarget)) {
36
- return correctedTarget;
37
- }
38
- console.error("[zag-js > ariaHidden] target", target, "in not contained inside", parent, ". Doing nothing");
39
- return null;
5
+ let _zag_js_dom_query = require("@zag-js/dom-query");
6
+ // src/walk-tree-outside.ts
7
+ let counterMap = /* @__PURE__ */ new WeakMap();
8
+ let uncontrolledNodes = /* @__PURE__ */ new WeakMap();
9
+ let markerMap = {};
10
+ let lockCount = 0;
11
+ const unwrapHost = (node) => node && (node.host || unwrapHost(node.parentNode));
12
+ const correctTargets = (parent, targets) => targets.map((target) => {
13
+ if (parent.contains(target)) return target;
14
+ const correctedTarget = unwrapHost(target);
15
+ if (correctedTarget && parent.contains(correctedTarget)) return correctedTarget;
16
+ console.error("[zag-js > ariaHidden] target", target, "in not contained inside", parent, ". Doing nothing");
17
+ return null;
40
18
  }).filter((x) => Boolean(x));
41
- var ignoreableNodes = /* @__PURE__ */ new Set(["script", "output", "status", "next-route-announcer"]);
42
- var isIgnoredNode = (node) => {
43
- if (ignoreableNodes.has(node.localName)) return true;
44
- if (node.role === "status") return true;
45
- if (node.hasAttribute("aria-live")) return true;
46
- return node.matches("[data-live-announcer]");
19
+ const LIVE_REGION_SELECTOR = "output, status, next-route-announcer, [role=\"status\"], [aria-live], [data-live-announcer]";
20
+ const isIgnoredNode = (node) => node.localName === "script" || node.matches(LIVE_REGION_SELECTOR);
21
+ const applyAttributeToOthers = (allTargets, props) => {
22
+ var _markerMap;
23
+ const { parentNode, markerName, attribute, followControlledElements = true } = props;
24
+ const attributeValue = attribute === "aria-hidden" ? "true" : "";
25
+ const targets = allTargets.filter((target) => parentNode.contains(target));
26
+ if (!targets.length) return () => {};
27
+ (_markerMap = markerMap)[markerName] || (_markerMap[markerName] = /* @__PURE__ */ new WeakMap());
28
+ const markerCounter = markerMap[markerName];
29
+ const hiddenNodes = [];
30
+ const elementsToKeep = /* @__PURE__ */ new Set();
31
+ const elementsToStop = new Set(targets);
32
+ const keep = (el) => {
33
+ if (!el || elementsToKeep.has(el)) return;
34
+ elementsToKeep.add(el);
35
+ keep(el.parentNode);
36
+ };
37
+ parentNode.querySelectorAll(LIVE_REGION_SELECTOR).forEach((region) => {
38
+ if (targets.some((target) => target.contains(region) || region.contains(target))) return;
39
+ keep(region);
40
+ elementsToStop.add(region);
41
+ });
42
+ targets.forEach((target) => {
43
+ keep(target);
44
+ if (followControlledElements && (0, _zag_js_dom_query.isHTMLElement)(target)) (0, _zag_js_dom_query.findControlledElements)(target, (controlledElement) => {
45
+ keep(controlledElement);
46
+ elementsToStop.add(controlledElement);
47
+ });
48
+ });
49
+ const deep = (parent) => {
50
+ if (!parent || elementsToStop.has(parent)) return;
51
+ Array.prototype.forEach.call(parent.children, (node) => {
52
+ if (elementsToKeep.has(node)) deep(node);
53
+ else try {
54
+ if (isIgnoredNode(node)) return;
55
+ const alreadyHidden = attribute === "aria-hidden" ? node.getAttribute(attribute) === "true" : node.hasAttribute(attribute);
56
+ const counterValue = (counterMap.get(node) || 0) + 1;
57
+ const markerValue = (markerCounter.get(node) || 0) + 1;
58
+ counterMap.set(node, counterValue);
59
+ markerCounter.set(node, markerValue);
60
+ hiddenNodes.push(node);
61
+ if (counterValue === 1 && alreadyHidden) uncontrolledNodes.set(node, true);
62
+ if (markerValue === 1) node.setAttribute(markerName, "");
63
+ if (!alreadyHidden) node.setAttribute(attribute, attributeValue);
64
+ } catch (e) {
65
+ console.error("[zag-js > ariaHidden] cannot operate on ", node, e);
66
+ }
67
+ });
68
+ };
69
+ deep(parentNode);
70
+ elementsToKeep.clear();
71
+ lockCount++;
72
+ return () => {
73
+ hiddenNodes.forEach((node) => {
74
+ const counterValue = counterMap.get(node) - 1;
75
+ const markerValue = markerCounter.get(node) - 1;
76
+ counterMap.set(node, counterValue);
77
+ markerCounter.set(node, markerValue);
78
+ if (!counterValue) {
79
+ if (!uncontrolledNodes.has(node)) node.removeAttribute(attribute);
80
+ uncontrolledNodes.delete(node);
81
+ }
82
+ if (!markerValue) node.removeAttribute(markerName);
83
+ });
84
+ lockCount--;
85
+ if (!lockCount) {
86
+ counterMap = /* @__PURE__ */ new WeakMap();
87
+ uncontrolledNodes = /* @__PURE__ */ new WeakMap();
88
+ markerMap = {};
89
+ }
90
+ };
47
91
  };
48
- var walkTreeOutside = (originalTarget, props) => {
49
- const { parentNode, markerName, controlAttribute, explicitBooleanValue, followControlledElements = true } = props;
50
- const targets = correctTargets(parentNode, Array.isArray(originalTarget) ? originalTarget : [originalTarget]);
51
- markerMap[markerName] || (markerMap[markerName] = /* @__PURE__ */ new WeakMap());
52
- const markerCounter = markerMap[markerName];
53
- const hiddenNodes = [];
54
- const elementsToKeep = /* @__PURE__ */ new Set();
55
- const elementsToStop = new Set(targets);
56
- const keep = (el) => {
57
- if (!el || elementsToKeep.has(el)) return;
58
- elementsToKeep.add(el);
59
- keep(el.parentNode);
60
- };
61
- targets.forEach((target) => {
62
- keep(target);
63
- if (followControlledElements && (0, import_dom_query.isHTMLElement)(target)) {
64
- (0, import_dom_query.findControlledElements)(target, (controlledElement) => {
65
- keep(controlledElement);
66
- });
67
- }
68
- });
69
- const deep = (parent) => {
70
- if (!parent || elementsToStop.has(parent)) {
71
- return;
72
- }
73
- Array.prototype.forEach.call(parent.children, (node) => {
74
- if (elementsToKeep.has(node)) {
75
- deep(node);
76
- } else {
77
- try {
78
- if (isIgnoredNode(node)) return;
79
- const attr = node.getAttribute(controlAttribute);
80
- const alreadyHidden = explicitBooleanValue ? attr === "true" : attr !== null && attr !== "false";
81
- const counterValue = (counterMap.get(node) || 0) + 1;
82
- const markerValue = (markerCounter.get(node) || 0) + 1;
83
- counterMap.set(node, counterValue);
84
- markerCounter.set(node, markerValue);
85
- hiddenNodes.push(node);
86
- if (counterValue === 1 && alreadyHidden) {
87
- uncontrolledNodes.set(node, true);
88
- }
89
- if (markerValue === 1) {
90
- node.setAttribute(markerName, "");
91
- }
92
- if (!alreadyHidden) {
93
- node.setAttribute(controlAttribute, explicitBooleanValue ? "true" : "");
94
- }
95
- } catch (e) {
96
- console.error("[zag-js > ariaHidden] cannot operate on ", node, e);
97
- }
98
- }
99
- });
100
- };
101
- deep(parentNode);
102
- elementsToKeep.clear();
103
- lockCount++;
104
- return () => {
105
- hiddenNodes.forEach((node) => {
106
- const counterValue = counterMap.get(node) - 1;
107
- const markerValue = markerCounter.get(node) - 1;
108
- counterMap.set(node, counterValue);
109
- markerCounter.set(node, markerValue);
110
- if (!counterValue) {
111
- if (!uncontrolledNodes.has(node)) {
112
- node.removeAttribute(controlAttribute);
113
- }
114
- uncontrolledNodes.delete(node);
115
- }
116
- if (!markerValue) {
117
- node.removeAttribute(markerName);
118
- }
119
- });
120
- lockCount--;
121
- if (!lockCount) {
122
- counterMap = /* @__PURE__ */ new WeakMap();
123
- counterMap = /* @__PURE__ */ new WeakMap();
124
- uncontrolledNodes = /* @__PURE__ */ new WeakMap();
125
- markerMap = {};
126
- }
127
- };
92
+ function createLockStack() {
93
+ const locks = [];
94
+ return {
95
+ add(lock) {
96
+ locks[locks.length - 1]?.pause();
97
+ locks.push(lock);
98
+ lock.resume();
99
+ },
100
+ remove(lock) {
101
+ const index = locks.indexOf(lock);
102
+ if (index === -1) return;
103
+ const isTop = index === locks.length - 1;
104
+ locks.splice(index, 1);
105
+ if (!isTop) return;
106
+ lock.pause();
107
+ locks[locks.length - 1]?.resume();
108
+ }
109
+ };
110
+ }
111
+ const lockStacks = /* @__PURE__ */ new WeakMap();
112
+ const getLockStack = (doc) => {
113
+ let stack = lockStacks.get(doc);
114
+ if (!stack) {
115
+ stack = createLockStack();
116
+ lockStacks.set(doc, stack);
117
+ }
118
+ return stack;
128
119
  };
129
- // Annotate the CommonJS export names for ESM import in node:
130
- 0 && (module.exports = {
131
- walkTreeOutside
132
- });
120
+ const walkTreeOutside = (originalTarget, props) => {
121
+ const { parentNode, attribute, followControlledElements = true } = props;
122
+ const targets = correctTargets(parentNode, Array.isArray(originalTarget) ? originalTarget : [originalTarget]);
123
+ if (!targets.length) return () => {};
124
+ const hiddenSelector = attribute === "aria-hidden" ? "[aria-hidden=\"true\"]" : "[inert]";
125
+ let undo;
126
+ let observer;
127
+ const apply = () => {
128
+ const prevUndo = undo;
129
+ undo = applyAttributeToOthers(targets, props);
130
+ prevUndo?.();
131
+ };
132
+ const release = () => {
133
+ undo?.();
134
+ undo = void 0;
135
+ };
136
+ const lock = {
137
+ pause() {
138
+ observer?.disconnect();
139
+ observer = void 0;
140
+ release();
141
+ },
142
+ resume() {
143
+ apply();
144
+ if (!followControlledElements) return;
145
+ observer = new ((0, _zag_js_dom_query.getWindow)(parentNode)).MutationObserver((records) => {
146
+ if (records.some(({ target }) => (0, _zag_js_dom_query.isElement)(target) && !target.closest(hiddenSelector))) apply();
147
+ });
148
+ observer.observe(parentNode, {
149
+ attributes: true,
150
+ attributeFilter: ["aria-expanded"],
151
+ subtree: true
152
+ });
153
+ }
154
+ };
155
+ const lockStack = getLockStack(parentNode.ownerDocument);
156
+ lockStack.add(lock);
157
+ return () => lockStack.remove(lock);
158
+ };
159
+ exports.walkTreeOutside = walkTreeOutside;
@@ -1,107 +1,155 @@
1
+ import { findControlledElements, getWindow, isElement, isHTMLElement } from "@zag-js/dom-query";
1
2
  // src/walk-tree-outside.ts
2
- import { findControlledElements, isHTMLElement } from "@zag-js/dom-query";
3
- var counterMap = /* @__PURE__ */ new WeakMap();
4
- var uncontrolledNodes = /* @__PURE__ */ new WeakMap();
5
- var markerMap = {};
6
- var lockCount = 0;
7
- var unwrapHost = (node) => node && (node.host || unwrapHost(node.parentNode));
8
- var correctTargets = (parent, targets) => targets.map((target) => {
9
- if (parent.contains(target)) return target;
10
- const correctedTarget = unwrapHost(target);
11
- if (correctedTarget && parent.contains(correctedTarget)) {
12
- return correctedTarget;
13
- }
14
- console.error("[zag-js > ariaHidden] target", target, "in not contained inside", parent, ". Doing nothing");
15
- return null;
3
+ let counterMap = /* @__PURE__ */ new WeakMap();
4
+ let uncontrolledNodes = /* @__PURE__ */ new WeakMap();
5
+ let markerMap = {};
6
+ let lockCount = 0;
7
+ const unwrapHost = (node) => node && (node.host || unwrapHost(node.parentNode));
8
+ const correctTargets = (parent, targets) => targets.map((target) => {
9
+ if (parent.contains(target)) return target;
10
+ const correctedTarget = unwrapHost(target);
11
+ if (correctedTarget && parent.contains(correctedTarget)) return correctedTarget;
12
+ console.error("[zag-js > ariaHidden] target", target, "in not contained inside", parent, ". Doing nothing");
13
+ return null;
16
14
  }).filter((x) => Boolean(x));
17
- var ignoreableNodes = /* @__PURE__ */ new Set(["script", "output", "status", "next-route-announcer"]);
18
- var isIgnoredNode = (node) => {
19
- if (ignoreableNodes.has(node.localName)) return true;
20
- if (node.role === "status") return true;
21
- if (node.hasAttribute("aria-live")) return true;
22
- return node.matches("[data-live-announcer]");
15
+ const LIVE_REGION_SELECTOR = "output, status, next-route-announcer, [role=\"status\"], [aria-live], [data-live-announcer]";
16
+ const isIgnoredNode = (node) => node.localName === "script" || node.matches(LIVE_REGION_SELECTOR);
17
+ const applyAttributeToOthers = (allTargets, props) => {
18
+ var _markerMap;
19
+ const { parentNode, markerName, attribute, followControlledElements = true } = props;
20
+ const attributeValue = attribute === "aria-hidden" ? "true" : "";
21
+ const targets = allTargets.filter((target) => parentNode.contains(target));
22
+ if (!targets.length) return () => {};
23
+ (_markerMap = markerMap)[markerName] || (_markerMap[markerName] = /* @__PURE__ */ new WeakMap());
24
+ const markerCounter = markerMap[markerName];
25
+ const hiddenNodes = [];
26
+ const elementsToKeep = /* @__PURE__ */ new Set();
27
+ const elementsToStop = new Set(targets);
28
+ const keep = (el) => {
29
+ if (!el || elementsToKeep.has(el)) return;
30
+ elementsToKeep.add(el);
31
+ keep(el.parentNode);
32
+ };
33
+ parentNode.querySelectorAll(LIVE_REGION_SELECTOR).forEach((region) => {
34
+ if (targets.some((target) => target.contains(region) || region.contains(target))) return;
35
+ keep(region);
36
+ elementsToStop.add(region);
37
+ });
38
+ targets.forEach((target) => {
39
+ keep(target);
40
+ if (followControlledElements && isHTMLElement(target)) findControlledElements(target, (controlledElement) => {
41
+ keep(controlledElement);
42
+ elementsToStop.add(controlledElement);
43
+ });
44
+ });
45
+ const deep = (parent) => {
46
+ if (!parent || elementsToStop.has(parent)) return;
47
+ Array.prototype.forEach.call(parent.children, (node) => {
48
+ if (elementsToKeep.has(node)) deep(node);
49
+ else try {
50
+ if (isIgnoredNode(node)) return;
51
+ const alreadyHidden = attribute === "aria-hidden" ? node.getAttribute(attribute) === "true" : node.hasAttribute(attribute);
52
+ const counterValue = (counterMap.get(node) || 0) + 1;
53
+ const markerValue = (markerCounter.get(node) || 0) + 1;
54
+ counterMap.set(node, counterValue);
55
+ markerCounter.set(node, markerValue);
56
+ hiddenNodes.push(node);
57
+ if (counterValue === 1 && alreadyHidden) uncontrolledNodes.set(node, true);
58
+ if (markerValue === 1) node.setAttribute(markerName, "");
59
+ if (!alreadyHidden) node.setAttribute(attribute, attributeValue);
60
+ } catch (e) {
61
+ console.error("[zag-js > ariaHidden] cannot operate on ", node, e);
62
+ }
63
+ });
64
+ };
65
+ deep(parentNode);
66
+ elementsToKeep.clear();
67
+ lockCount++;
68
+ return () => {
69
+ hiddenNodes.forEach((node) => {
70
+ const counterValue = counterMap.get(node) - 1;
71
+ const markerValue = markerCounter.get(node) - 1;
72
+ counterMap.set(node, counterValue);
73
+ markerCounter.set(node, markerValue);
74
+ if (!counterValue) {
75
+ if (!uncontrolledNodes.has(node)) node.removeAttribute(attribute);
76
+ uncontrolledNodes.delete(node);
77
+ }
78
+ if (!markerValue) node.removeAttribute(markerName);
79
+ });
80
+ lockCount--;
81
+ if (!lockCount) {
82
+ counterMap = /* @__PURE__ */ new WeakMap();
83
+ uncontrolledNodes = /* @__PURE__ */ new WeakMap();
84
+ markerMap = {};
85
+ }
86
+ };
23
87
  };
24
- var walkTreeOutside = (originalTarget, props) => {
25
- const { parentNode, markerName, controlAttribute, explicitBooleanValue, followControlledElements = true } = props;
26
- const targets = correctTargets(parentNode, Array.isArray(originalTarget) ? originalTarget : [originalTarget]);
27
- markerMap[markerName] || (markerMap[markerName] = /* @__PURE__ */ new WeakMap());
28
- const markerCounter = markerMap[markerName];
29
- const hiddenNodes = [];
30
- const elementsToKeep = /* @__PURE__ */ new Set();
31
- const elementsToStop = new Set(targets);
32
- const keep = (el) => {
33
- if (!el || elementsToKeep.has(el)) return;
34
- elementsToKeep.add(el);
35
- keep(el.parentNode);
36
- };
37
- targets.forEach((target) => {
38
- keep(target);
39
- if (followControlledElements && isHTMLElement(target)) {
40
- findControlledElements(target, (controlledElement) => {
41
- keep(controlledElement);
42
- });
43
- }
44
- });
45
- const deep = (parent) => {
46
- if (!parent || elementsToStop.has(parent)) {
47
- return;
48
- }
49
- Array.prototype.forEach.call(parent.children, (node) => {
50
- if (elementsToKeep.has(node)) {
51
- deep(node);
52
- } else {
53
- try {
54
- if (isIgnoredNode(node)) return;
55
- const attr = node.getAttribute(controlAttribute);
56
- const alreadyHidden = explicitBooleanValue ? attr === "true" : attr !== null && attr !== "false";
57
- const counterValue = (counterMap.get(node) || 0) + 1;
58
- const markerValue = (markerCounter.get(node) || 0) + 1;
59
- counterMap.set(node, counterValue);
60
- markerCounter.set(node, markerValue);
61
- hiddenNodes.push(node);
62
- if (counterValue === 1 && alreadyHidden) {
63
- uncontrolledNodes.set(node, true);
64
- }
65
- if (markerValue === 1) {
66
- node.setAttribute(markerName, "");
67
- }
68
- if (!alreadyHidden) {
69
- node.setAttribute(controlAttribute, explicitBooleanValue ? "true" : "");
70
- }
71
- } catch (e) {
72
- console.error("[zag-js > ariaHidden] cannot operate on ", node, e);
73
- }
74
- }
75
- });
76
- };
77
- deep(parentNode);
78
- elementsToKeep.clear();
79
- lockCount++;
80
- return () => {
81
- hiddenNodes.forEach((node) => {
82
- const counterValue = counterMap.get(node) - 1;
83
- const markerValue = markerCounter.get(node) - 1;
84
- counterMap.set(node, counterValue);
85
- markerCounter.set(node, markerValue);
86
- if (!counterValue) {
87
- if (!uncontrolledNodes.has(node)) {
88
- node.removeAttribute(controlAttribute);
89
- }
90
- uncontrolledNodes.delete(node);
91
- }
92
- if (!markerValue) {
93
- node.removeAttribute(markerName);
94
- }
95
- });
96
- lockCount--;
97
- if (!lockCount) {
98
- counterMap = /* @__PURE__ */ new WeakMap();
99
- counterMap = /* @__PURE__ */ new WeakMap();
100
- uncontrolledNodes = /* @__PURE__ */ new WeakMap();
101
- markerMap = {};
102
- }
103
- };
88
+ function createLockStack() {
89
+ const locks = [];
90
+ return {
91
+ add(lock) {
92
+ locks[locks.length - 1]?.pause();
93
+ locks.push(lock);
94
+ lock.resume();
95
+ },
96
+ remove(lock) {
97
+ const index = locks.indexOf(lock);
98
+ if (index === -1) return;
99
+ const isTop = index === locks.length - 1;
100
+ locks.splice(index, 1);
101
+ if (!isTop) return;
102
+ lock.pause();
103
+ locks[locks.length - 1]?.resume();
104
+ }
105
+ };
106
+ }
107
+ const lockStacks = /* @__PURE__ */ new WeakMap();
108
+ const getLockStack = (doc) => {
109
+ let stack = lockStacks.get(doc);
110
+ if (!stack) {
111
+ stack = createLockStack();
112
+ lockStacks.set(doc, stack);
113
+ }
114
+ return stack;
104
115
  };
105
- export {
106
- walkTreeOutside
116
+ const walkTreeOutside = (originalTarget, props) => {
117
+ const { parentNode, attribute, followControlledElements = true } = props;
118
+ const targets = correctTargets(parentNode, Array.isArray(originalTarget) ? originalTarget : [originalTarget]);
119
+ if (!targets.length) return () => {};
120
+ const hiddenSelector = attribute === "aria-hidden" ? "[aria-hidden=\"true\"]" : "[inert]";
121
+ let undo;
122
+ let observer;
123
+ const apply = () => {
124
+ const prevUndo = undo;
125
+ undo = applyAttributeToOthers(targets, props);
126
+ prevUndo?.();
127
+ };
128
+ const release = () => {
129
+ undo?.();
130
+ undo = void 0;
131
+ };
132
+ const lock = {
133
+ pause() {
134
+ observer?.disconnect();
135
+ observer = void 0;
136
+ release();
137
+ },
138
+ resume() {
139
+ apply();
140
+ if (!followControlledElements) return;
141
+ observer = new (getWindow(parentNode)).MutationObserver((records) => {
142
+ if (records.some(({ target }) => isElement(target) && !target.closest(hiddenSelector))) apply();
143
+ });
144
+ observer.observe(parentNode, {
145
+ attributes: true,
146
+ attributeFilter: ["aria-expanded"],
147
+ subtree: true
148
+ });
149
+ }
150
+ };
151
+ const lockStack = getLockStack(parentNode.ownerDocument);
152
+ lockStack.add(lock);
153
+ return () => lockStack.remove(lock);
107
154
  };
155
+ export { walkTreeOutside };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/aria-hidden",
3
- "version": "2.0.0-next.2",
3
+ "version": "2.0.0-next.4",
4
4
  "description": "Hide targets from screen readers",
5
5
  "keywords": [
6
6
  "js",
@@ -27,7 +27,7 @@
27
27
  "clean-package": "../../../clean-package.config.json",
28
28
  "main": "dist/index.js",
29
29
  "dependencies": {
30
- "@zag-js/dom-query": "2.0.0-next.2"
30
+ "@zag-js/dom-query": "2.0.0-next.4"
31
31
  },
32
32
  "devDependencies": {
33
33
  "clean-package": "2.2.0"
@@ -48,7 +48,7 @@
48
48
  "./package.json": "./package.json"
49
49
  },
50
50
  "scripts": {
51
- "build": "tsup",
51
+ "build": "tsdown",
52
52
  "test": "vitest",
53
53
  "lint": "oxlint src",
54
54
  "test-ci": "pnpm test --ci --runInBand -u",