UNPKG

@zag-js/dom-query

Version:

The dom helper library for zag.js machines

100 lines (98 loc) 4.04 kB
import "./chunk-QZ7TP4HQ.mjs"; // src/controller.ts import { getRootNode } from "./node.mjs"; var INTERACTIVE_CONTAINER_ROLE = /* @__PURE__ */ new Set(["menu", "listbox", "dialog", "grid", "tree", "region", "application"]); var isInteractiveContainerRole = (role) => INTERACTIVE_CONTAINER_ROLE.has(role); var getAriaControls = (element) => element.getAttribute("aria-controls")?.split(" ") || []; function isControlledElement(container, element) { const visitedIds = /* @__PURE__ */ new Set(); const rootNode = getRootNode(container); const checkElement = (searchRoot) => { const controllingElements = searchRoot.querySelectorAll("[aria-controls]"); for (const controller of controllingElements) { if (controller.getAttribute("aria-expanded") !== "true") continue; const controlledIds = getAriaControls(controller); for (const id of controlledIds) { if (!id || visitedIds.has(id)) continue; visitedIds.add(id); const controlledElement = rootNode.getElementById(id); if (controlledElement) { const role = controlledElement.getAttribute("role"); const modal = controlledElement.getAttribute("aria-modal") === "true"; if (role && isInteractiveContainerRole(role) && !modal) { if (controlledElement === element || controlledElement.contains(element)) { return true; } if (checkElement(controlledElement)) { return true; } } } } } return false; }; return checkElement(container); } function findControlledElements(searchRoot, callback) { const rootNode = getRootNode(searchRoot); const visitedIds = /* @__PURE__ */ new Set(); const findRecursive = (root) => { const controllingElements = root.querySelectorAll("[aria-controls]"); for (const controller of controllingElements) { if (controller.getAttribute("aria-expanded") !== "true") continue; const controlledIds = getAriaControls(controller); for (const id of controlledIds) { if (!id || visitedIds.has(id)) continue; visitedIds.add(id); const controlledElement = rootNode.getElementById(id); if (controlledElement) { const role = controlledElement.getAttribute("role"); const modal = controlledElement.getAttribute("aria-modal") === "true"; if (role && INTERACTIVE_CONTAINER_ROLE.has(role) && !modal) { callback(controlledElement); findRecursive(controlledElement); } } } } }; findRecursive(searchRoot); } function getControlledElements(container) { const controlledElements = /* @__PURE__ */ new Set(); findControlledElements(container, (controlledElement) => { if (!container.contains(controlledElement)) { controlledElements.add(controlledElement); } }); return Array.from(controlledElements); } function isInteractiveContainerElement(element) { const role = element.getAttribute("role"); return Boolean(role && INTERACTIVE_CONTAINER_ROLE.has(role)); } function isControllerElement(element) { return element.hasAttribute("aria-controls") && element.getAttribute("aria-expanded") === "true"; } function hasControllerElements(element) { if (isControllerElement(element)) return true; return Boolean(element.querySelector?.('[aria-controls][aria-expanded="true"]')); } function isControlledByExpandedController(element) { if (!element.id) return false; const rootNode = getRootNode(element); const escapedId = CSS.escape(element.id); const selector = `[aria-controls~="${escapedId}"][aria-expanded="true"], [aria-controls="${escapedId}"][aria-expanded="true"]`; const controller = rootNode.querySelector(selector); return Boolean(controller && isInteractiveContainerElement(element)); } export { findControlledElements, getControlledElements, hasControllerElements, isControlledByExpandedController, isControlledElement, isControllerElement, isInteractiveContainerElement };