@zag-js/splitter
Version:
Core logic for the splitter widget implemented as a state machine
77 lines (75 loc) • 2.87 kB
JavaScript
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
};