UNPKG

@zag-js/splitter

Version:

Core logic for the splitter widget implemented as a state machine

77 lines (75 loc) 2.87 kB
import "../chunk-QZ7TP4HQ.mjs"; // src/utils/stacking-order.ts import { getAncestorElements, getComputedStyle, getParentElement } from "@zag-js/dom-query"; import { ensure, hasProp } from "@zag-js/utils"; function compareStackingOrder(a, b) { if (a === b) throw new Error("Cannot compare node with itself"); const ancestors = { a: getAncestorElements(a), b: getAncestorElements(b) }; let commonAncestor = null; while (ancestors.a.at(-1) === ancestors.b.at(-1)) { const currentA = ancestors.a.pop(); ancestors.b.pop(); commonAncestor = currentA; } ensure( commonAncestor, () => "[stacking-order] Stacking order can only be calculated for elements with a common ancestor" ); const zIndexes = { a: getZIndex(findStackingContext(ancestors.a)), b: getZIndex(findStackingContext(ancestors.b)) }; if (zIndexes.a === zIndexes.b) { const children = commonAncestor.childNodes; const furthestAncestors = { a: ancestors.a.at(-1), b: ancestors.b.at(-1) }; let i = children.length; while (i--) { const child = children[i]; if (child === furthestAncestors.a) return 1; if (child === furthestAncestors.b) return -1; } } return Math.sign(zIndexes.a - zIndexes.b); } var STACKING_PROPS_REGEX = /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/; function isFlexItem(node) { const parent = getParentElement(node); const display = getComputedStyle(parent ?? node).display; return display === "flex" || display === "inline-flex"; } function createsStackingContext(node) { const style = getComputedStyle(node); if (style.position === "fixed") return true; if (style.zIndex !== "auto" && (style.position !== "static" || isFlexItem(node))) return true; if (+style.opacity < 1) return true; if (hasProp(style, "transform") && style.transform !== "none") return true; if (hasProp(style, "webkitTransform") && style.webkitTransform !== "none") return true; if (hasProp(style, "mixBlendMode") && style.mixBlendMode !== "normal") return true; if (hasProp(style, "filter") && style.filter !== "none") return true; if (hasProp(style, "webkitFilter") && style.webkitFilter !== "none") return true; if (hasProp(style, "isolation") && style.isolation === "isolate") return true; if (STACKING_PROPS_REGEX.test(style.willChange)) return true; if (style.webkitOverflowScrolling === "touch") return true; return false; } function findStackingContext(nodes) { let i = nodes.length; while (i--) { const node = nodes[i]; ensure(node, () => "[stacking-order] missing node in findStackingContext"); if (createsStackingContext(node)) return node; } return null; } var getZIndex = (node) => { return node && Number(getComputedStyle(node).zIndex) || 0; }; export { compareStackingOrder };