@zag-js/dismissable
Advanced tools
| import { InteractOutsideHandlers } from '@zag-js/interact-outside'; | ||
| import { MaybeFunction } from '@zag-js/utils'; | ||
| import { LayerDismissEvent, LayerType } from './layer-stack.mjs'; | ||
| import { LayerDismissEvent, LayerStyleTarget, LayerType } from './layer-stack.mjs'; | ||
@@ -28,2 +28,8 @@ type MaybeElement = HTMLElement | null; | ||
| /** | ||
| * Extra elements that receive the same layer stack CSS vars, `data-*`, and `--z-index` | ||
| * (from the primary node's computed `z-index`) as the dismissable node | ||
| * (e.g. dialog backdrop + positioner when the node is content). | ||
| */ | ||
| layerStyleTargets?: LayerStyleTarget[] | undefined; | ||
| /** | ||
| * Whether to log debug information | ||
@@ -30,0 +36,0 @@ */ |
| import { InteractOutsideHandlers } from '@zag-js/interact-outside'; | ||
| import { MaybeFunction } from '@zag-js/utils'; | ||
| import { LayerDismissEvent, LayerType } from './layer-stack.js'; | ||
| import { LayerDismissEvent, LayerStyleTarget, LayerType } from './layer-stack.js'; | ||
@@ -28,2 +28,8 @@ type MaybeElement = HTMLElement | null; | ||
| /** | ||
| * Extra elements that receive the same layer stack CSS vars, `data-*`, and `--z-index` | ||
| * (from the primary node's computed `z-index`) as the dismissable node | ||
| * (e.g. dialog backdrop + positioner when the node is content). | ||
| */ | ||
| layerStyleTargets?: LayerStyleTarget[] | undefined; | ||
| /** | ||
| * Whether to log debug information | ||
@@ -30,0 +36,0 @@ */ |
@@ -42,4 +42,19 @@ "use strict"; | ||
| } | ||
| const { onDismiss, onRequestDismiss, pointerBlocking, exclude: excludeContainers, debug, type = "dialog" } = options; | ||
| const layer = { dismiss: onDismiss, node, type, pointerBlocking, requestDismiss: onRequestDismiss }; | ||
| const { | ||
| onDismiss, | ||
| onRequestDismiss, | ||
| pointerBlocking, | ||
| exclude: excludeContainers, | ||
| debug, | ||
| type = "dialog", | ||
| layerStyleTargets | ||
| } = options; | ||
| const layer = { | ||
| dismiss: onDismiss, | ||
| node, | ||
| type, | ||
| pointerBlocking, | ||
| requestDismiss: onRequestDismiss, | ||
| styleTargets: layerStyleTargets | ||
| }; | ||
| import_layer_stack.layerStack.add(layer); | ||
@@ -46,0 +61,0 @@ (0, import_pointer_event_outside.assignPointerEventToLayers)(); |
@@ -19,4 +19,19 @@ // src/dismissable-layer.ts | ||
| } | ||
| const { onDismiss, onRequestDismiss, pointerBlocking, exclude: excludeContainers, debug, type = "dialog" } = options; | ||
| const layer = { dismiss: onDismiss, node, type, pointerBlocking, requestDismiss: onRequestDismiss }; | ||
| const { | ||
| onDismiss, | ||
| onRequestDismiss, | ||
| pointerBlocking, | ||
| exclude: excludeContainers, | ||
| debug, | ||
| type = "dialog", | ||
| layerStyleTargets | ||
| } = options; | ||
| const layer = { | ||
| dismiss: onDismiss, | ||
| node, | ||
| type, | ||
| pointerBlocking, | ||
| requestDismiss: onRequestDismiss, | ||
| styleTargets: layerStyleTargets | ||
| }; | ||
| layerStack.add(layer); | ||
@@ -23,0 +38,0 @@ assignPointerEventToLayers(); |
+1
-1
| export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, PointerDownOutsideEvent } from '@zag-js/interact-outside'; | ||
| export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.mjs'; | ||
| export { LayerType } from './layer-stack.mjs'; | ||
| export { LayerStyleTarget, LayerType } from './layer-stack.mjs'; | ||
| import '@zag-js/utils'; |
+1
-1
| export { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, PointerDownOutsideEvent } from '@zag-js/interact-outside'; | ||
| export { DismissableElementHandlers, DismissableElementOptions, PersistentElementOptions, trackDismissableBranch, trackDismissableElement } from './dismissable-layer.js'; | ||
| export { LayerType } from './layer-stack.js'; | ||
| export { LayerStyleTarget, LayerType } from './layer-stack.js'; | ||
| import '@zag-js/utils'; |
@@ -9,2 +9,3 @@ type LayerType = "dialog" | "popover" | "menu" | "listbox" | (string & {}); | ||
| type LayerDismissEvent = CustomEvent<LayerDismissEventDetail>; | ||
| type LayerStyleTarget = () => HTMLElement | null; | ||
| interface Layer { | ||
@@ -16,2 +17,3 @@ dismiss: VoidFunction; | ||
| requestDismiss?: ((event: LayerDismissEvent) => void) | undefined; | ||
| styleTargets?: LayerStyleTarget[] | undefined; | ||
| } | ||
@@ -45,2 +47,2 @@ declare const layerStack: { | ||
| export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerType, layerStack }; | ||
| export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerStyleTarget, type LayerType, layerStack }; |
@@ -9,2 +9,3 @@ type LayerType = "dialog" | "popover" | "menu" | "listbox" | (string & {}); | ||
| type LayerDismissEvent = CustomEvent<LayerDismissEventDetail>; | ||
| type LayerStyleTarget = () => HTMLElement | null; | ||
| interface Layer { | ||
@@ -16,2 +17,3 @@ dismiss: VoidFunction; | ||
| requestDismiss?: ((event: LayerDismissEvent) => void) | undefined; | ||
| styleTargets?: LayerStyleTarget[] | undefined; | ||
| } | ||
@@ -45,2 +47,2 @@ declare const layerStack: { | ||
| export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerType, layerStack }; | ||
| export { type Layer, type LayerDismissEvent, type LayerDismissEventDetail, type LayerStyleTarget, type LayerType, layerStack }; |
+41
-13
@@ -82,2 +82,6 @@ "use strict"; | ||
| add(layer) { | ||
| const existingIndex = this.indexOf(layer.node); | ||
| if (existingIndex !== -1) { | ||
| this.layers.splice(existingIndex, 1); | ||
| } | ||
| this.layers.push(layer); | ||
@@ -92,2 +96,9 @@ this.syncLayers(); | ||
| if (index < 0) return; | ||
| const layer = this.layers[index]; | ||
| layer.styleTargets?.forEach((getTarget) => { | ||
| const target = getTarget(); | ||
| if (target) { | ||
| clearLayerStyleMirror(target); | ||
| } | ||
| }); | ||
| this.recentlyRemoved.add(node); | ||
@@ -97,3 +108,3 @@ (0, import_dom_query.nextTick)(() => this.recentlyRemoved.delete(node)); | ||
| const _layers = this.getNestedLayers(node); | ||
| _layers.forEach((layer) => layerStack.dismiss(layer.node, node)); | ||
| _layers.forEach((layer2) => layerStack.dismiss(layer2.node, node)); | ||
| } | ||
@@ -109,14 +120,10 @@ this.layers.splice(index, 1); | ||
| 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}`); | ||
| applyLayerStackMetadata(layer, index, layer.node); | ||
| layer.styleTargets?.forEach((getTarget) => { | ||
| const target = getTarget(); | ||
| if (!target || target === layer.node) return; | ||
| applyLayerStackMetadata(layer, index, target); | ||
| const { zIndex } = (0, import_dom_query.getComputedStyle)(layer.node); | ||
| target.style.setProperty("--z-index", zIndex); | ||
| }); | ||
| }); | ||
@@ -149,2 +156,23 @@ }, | ||
| }; | ||
| function applyLayerStackMetadata(layer, index, el) { | ||
| el.style.setProperty("--layer-index", `${index}`); | ||
| el.removeAttribute("data-nested"); | ||
| el.removeAttribute("data-has-nested"); | ||
| const parentOfSameType = layerStack.getParentLayerOfType(layer.node, layer.type); | ||
| if (parentOfSameType) { | ||
| el.setAttribute("data-nested", layer.type); | ||
| } | ||
| const nestedCount = layerStack.countNestedLayersOfType(layer.node, layer.type); | ||
| if (nestedCount > 0) { | ||
| el.setAttribute("data-has-nested", layer.type); | ||
| } | ||
| el.style.setProperty("--nested-layer-count", `${nestedCount}`); | ||
| } | ||
| function clearLayerStyleMirror(el) { | ||
| el.style.removeProperty("--layer-index"); | ||
| el.style.removeProperty("--nested-layer-count"); | ||
| el.style.removeProperty("--z-index"); | ||
| el.removeAttribute("data-nested"); | ||
| el.removeAttribute("data-has-nested"); | ||
| } | ||
| function fireCustomEvent(el, type, detail) { | ||
@@ -151,0 +179,0 @@ const win = el.ownerDocument.defaultView || window; |
+42
-14
| // src/layer-stack.ts | ||
| import { contains, nextTick } from "@zag-js/dom-query"; | ||
| import { contains, nextTick, getComputedStyle } from "@zag-js/dom-query"; | ||
| var LAYER_REQUEST_DISMISS_EVENT = "layer:request-dismiss"; | ||
@@ -58,2 +58,6 @@ var layerStack = { | ||
| add(layer) { | ||
| const existingIndex = this.indexOf(layer.node); | ||
| if (existingIndex !== -1) { | ||
| this.layers.splice(existingIndex, 1); | ||
| } | ||
| this.layers.push(layer); | ||
@@ -68,2 +72,9 @@ this.syncLayers(); | ||
| if (index < 0) return; | ||
| const layer = this.layers[index]; | ||
| layer.styleTargets?.forEach((getTarget) => { | ||
| const target = getTarget(); | ||
| if (target) { | ||
| clearLayerStyleMirror(target); | ||
| } | ||
| }); | ||
| this.recentlyRemoved.add(node); | ||
@@ -73,3 +84,3 @@ nextTick(() => this.recentlyRemoved.delete(node)); | ||
| const _layers = this.getNestedLayers(node); | ||
| _layers.forEach((layer) => layerStack.dismiss(layer.node, node)); | ||
| _layers.forEach((layer2) => layerStack.dismiss(layer2.node, node)); | ||
| } | ||
@@ -85,14 +96,10 @@ this.layers.splice(index, 1); | ||
| 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}`); | ||
| applyLayerStackMetadata(layer, index, layer.node); | ||
| layer.styleTargets?.forEach((getTarget) => { | ||
| const target = getTarget(); | ||
| if (!target || target === layer.node) return; | ||
| applyLayerStackMetadata(layer, index, target); | ||
| const { zIndex } = getComputedStyle(layer.node); | ||
| target.style.setProperty("--z-index", zIndex); | ||
| }); | ||
| }); | ||
@@ -125,2 +132,23 @@ }, | ||
| }; | ||
| function applyLayerStackMetadata(layer, index, el) { | ||
| el.style.setProperty("--layer-index", `${index}`); | ||
| el.removeAttribute("data-nested"); | ||
| el.removeAttribute("data-has-nested"); | ||
| const parentOfSameType = layerStack.getParentLayerOfType(layer.node, layer.type); | ||
| if (parentOfSameType) { | ||
| el.setAttribute("data-nested", layer.type); | ||
| } | ||
| const nestedCount = layerStack.countNestedLayersOfType(layer.node, layer.type); | ||
| if (nestedCount > 0) { | ||
| el.setAttribute("data-has-nested", layer.type); | ||
| } | ||
| el.style.setProperty("--nested-layer-count", `${nestedCount}`); | ||
| } | ||
| function clearLayerStyleMirror(el) { | ||
| el.style.removeProperty("--layer-index"); | ||
| el.style.removeProperty("--nested-layer-count"); | ||
| el.style.removeProperty("--z-index"); | ||
| el.removeAttribute("data-nested"); | ||
| el.removeAttribute("data-has-nested"); | ||
| } | ||
| function fireCustomEvent(el, type, detail) { | ||
@@ -127,0 +155,0 @@ const win = el.ownerDocument.defaultView || window; |
@@ -43,6 +43,8 @@ "use strict"; | ||
| if (import_layer_stack.layerStack.hasPointerBlockingLayer() && !doc.body.hasAttribute("data-inert")) { | ||
| originalBodyPointerEvents = document.body.style.pointerEvents; | ||
| originalBodyPointerEvents = doc.body.style.pointerEvents; | ||
| queueMicrotask(() => { | ||
| doc.body.style.pointerEvents = "none"; | ||
| doc.body.setAttribute("data-inert", ""); | ||
| const body = doc.body; | ||
| if (!body) return; | ||
| body.style.pointerEvents = "none"; | ||
| body.setAttribute("data-inert", ""); | ||
| }); | ||
@@ -64,5 +66,7 @@ } | ||
| queueMicrotask(() => { | ||
| doc.body.style.pointerEvents = originalBodyPointerEvents; | ||
| doc.body.removeAttribute("data-inert"); | ||
| if (doc.body.style.length === 0) doc.body.removeAttribute("style"); | ||
| const body = doc.body; | ||
| if (!body) return; | ||
| body.style.pointerEvents = originalBodyPointerEvents; | ||
| body.removeAttribute("data-inert"); | ||
| if (body.style.length === 0) body.removeAttribute("style"); | ||
| }); | ||
@@ -69,0 +73,0 @@ cleanups.forEach((fn) => fn()); |
@@ -17,6 +17,8 @@ // src/pointer-event-outside.ts | ||
| if (layerStack.hasPointerBlockingLayer() && !doc.body.hasAttribute("data-inert")) { | ||
| originalBodyPointerEvents = document.body.style.pointerEvents; | ||
| originalBodyPointerEvents = doc.body.style.pointerEvents; | ||
| queueMicrotask(() => { | ||
| doc.body.style.pointerEvents = "none"; | ||
| doc.body.setAttribute("data-inert", ""); | ||
| const body = doc.body; | ||
| if (!body) return; | ||
| body.style.pointerEvents = "none"; | ||
| body.setAttribute("data-inert", ""); | ||
| }); | ||
@@ -38,5 +40,7 @@ } | ||
| queueMicrotask(() => { | ||
| doc.body.style.pointerEvents = originalBodyPointerEvents; | ||
| doc.body.removeAttribute("data-inert"); | ||
| if (doc.body.style.length === 0) doc.body.removeAttribute("style"); | ||
| const body = doc.body; | ||
| if (!body) return; | ||
| body.style.pointerEvents = originalBodyPointerEvents; | ||
| body.removeAttribute("data-inert"); | ||
| if (body.style.length === 0) body.removeAttribute("style"); | ||
| }); | ||
@@ -43,0 +47,0 @@ cleanups.forEach((fn) => fn()); |
+4
-4
| { | ||
| "name": "@zag-js/dismissable", | ||
| "version": "1.40.0", | ||
| "version": "1.41.0", | ||
| "description": "Dismissable layer utilities for the DOM", | ||
@@ -26,5 +26,5 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@zag-js/interact-outside": "1.40.0", | ||
| "@zag-js/dom-query": "1.40.0", | ||
| "@zag-js/utils": "1.40.0" | ||
| "@zag-js/interact-outside": "1.41.0", | ||
| "@zag-js/dom-query": "1.41.0", | ||
| "@zag-js/utils": "1.41.0" | ||
| }, | ||
@@ -31,0 +31,0 @@ "devDependencies": { |
43099
8.05%941
12.16%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
Updated
Updated