UNPKG

@zag-js/dismissable

Version:

Dismissable layer utilities for the DOM

157 lines (155 loc) 5.42 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/layer-stack.ts var layer_stack_exports = {}; __export(layer_stack_exports, { layerStack: () => layerStack }); module.exports = __toCommonJS(layer_stack_exports); var import_dom_query = require("@zag-js/dom-query"); var LAYER_REQUEST_DISMISS_EVENT = "layer:request-dismiss"; var layerStack = { layers: [], branches: [], recentlyRemoved: /* @__PURE__ */ new Set(), count() { return this.layers.length; }, pointerBlockingLayers() { return this.layers.filter((layer) => layer.pointerBlocking); }, topMostPointerBlockingLayer() { return [...this.pointerBlockingLayers()].slice(-1)[0]; }, hasPointerBlockingLayer() { return this.pointerBlockingLayers().length > 0; }, isBelowPointerBlockingLayer(node) { const index = this.indexOf(node); const highestBlockingIndex = this.topMostPointerBlockingLayer() ? this.indexOf(this.topMostPointerBlockingLayer()?.node) : -1; return index < highestBlockingIndex; }, isTopMost(node) { const layer = this.layers[this.count() - 1]; return layer?.node === node; }, getNestedLayers(node) { return Array.from(this.layers).slice(this.indexOf(node) + 1); }, getLayersByType(type) { return this.layers.filter((layer) => layer.type === type); }, getNestedLayersByType(node, type) { const index = this.indexOf(node); if (index === -1) return []; return this.layers.slice(index + 1).filter((layer) => layer.type === type); }, getParentLayerOfType(node, type) { const index = this.indexOf(node); if (index <= 0) return void 0; return this.layers.slice(0, index).reverse().find((layer) => layer.type === type); }, countNestedLayersOfType(node, type) { return this.getNestedLayersByType(node, type).length; }, isInNestedLayer(node, target) { const inNested = this.getNestedLayers(node).some((layer) => (0, import_dom_query.contains)(layer.node, target)); if (inNested) return true; if (this.recentlyRemoved.size > 0) return true; return false; }, isInBranch(target) { return Array.from(this.branches).some((branch) => (0, import_dom_query.contains)(branch, target)); }, add(layer) { this.layers.push(layer); this.syncLayers(); }, addBranch(node) { this.branches.push(node); }, remove(node) { const index = this.indexOf(node); if (index < 0) return; this.recentlyRemoved.add(node); (0, import_dom_query.nextTick)(() => this.recentlyRemoved.delete(node)); if (index < this.count() - 1) { const _layers = this.getNestedLayers(node); _layers.forEach((layer) => layerStack.dismiss(layer.node, node)); } this.layers.splice(index, 1); this.syncLayers(); }, removeBranch(node) { const index = this.branches.indexOf(node); if (index >= 0) this.branches.splice(index, 1); }, syncLayers() { this.layers.forEach((layer, index) => { layer.node.style.setProperty("--layer-index", `${index}`); layer.node.removeAttribute("data-nested"); layer.node.removeAttribute("data-has-nested"); const parentOfSameType = this.getParentLayerOfType(layer.node, layer.type); if (parentOfSameType) { layer.node.setAttribute("data-nested", layer.type); } const nestedCount = this.countNestedLayersOfType(layer.node, layer.type); if (nestedCount > 0) { layer.node.setAttribute("data-has-nested", layer.type); } layer.node.style.setProperty("--nested-layer-count", `${nestedCount}`); }); }, indexOf(node) { return this.layers.findIndex((layer) => layer.node === node); }, dismiss(node, parent) { const index = this.indexOf(node); if (index === -1) return; const layer = this.layers[index]; addListenerOnce(node, LAYER_REQUEST_DISMISS_EVENT, (event) => { layer.requestDismiss?.(event); if (!event.defaultPrevented) { layer?.dismiss(); } }); fireCustomEvent(node, LAYER_REQUEST_DISMISS_EVENT, { originalLayer: node, targetLayer: parent, originalIndex: index, targetIndex: parent ? this.indexOf(parent) : -1 }); this.syncLayers(); }, clear() { this.remove(this.layers[0].node); } }; function fireCustomEvent(el, type, detail) { const win = el.ownerDocument.defaultView || window; const event = new win.CustomEvent(type, { cancelable: true, bubbles: true, detail }); return el.dispatchEvent(event); } function addListenerOnce(el, type, callback) { el.addEventListener(type, callback, { once: true }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { layerStack });