"use strict"; "use client"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/react/dismissable-layer/src/index.ts var src_exports = {}; __export(src_exports, { Branch: () => Branch, DismissableLayer: () => DismissableLayer, DismissableLayerBranch: () => DismissableLayerBranch, Root: () => Root }); module.exports = __toCommonJS(src_exports); // packages/react/dismissable-layer/src/DismissableLayer.tsx var React = __toESM(require("react")); var import_primitive = require("@radix-ui/primitive"); var import_react_primitive = require("@radix-ui/react-primitive"); var import_react_compose_refs = require("@radix-ui/react-compose-refs"); var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref"); var import_react_use_escape_keydown = require("@radix-ui/react-use-escape-keydown"); var import_jsx_runtime = require("react/jsx-runtime"); var DISMISSABLE_LAYER_NAME = "DismissableLayer"; var CONTEXT_UPDATE = "dismissableLayer.update"; var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside"; var FOCUS_OUTSIDE = "dismissableLayer.focusOutside"; var originalBodyPointerEvents; var DismissableLayerContext = React.createContext({ layers: /* @__PURE__ */ new Set(), layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(), branches: /* @__PURE__ */ new Set() }); var DismissableLayer = React.forwardRef( (props, forwardedRef) => { const { disableOutsidePointerEvents = false, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, ...layerProps } = props; const context = React.useContext(DismissableLayerContext); const [node, setNode] = React.useState(null); const ownerDocument = node?.ownerDocument ?? globalThis?.document; const [, force] = React.useState({}); const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node2) => setNode(node2)); const layers = Array.from(context.layers); const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1); const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled); const index = node ? layers.indexOf(node) : -1; const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0; const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex; const pointerDownOutside = usePointerDownOutside((event) => { const target = event.target; const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target)); if (!isPointerEventsEnabled || isPointerDownOnBranch) return; onPointerDownOutside?.(event); onInteractOutside?.(event); if (!event.defaultPrevented) onDismiss?.(); }, ownerDocument); const focusOutside = useFocusOutside((event) => { const target = event.target; const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target)); if (isFocusInBranch) return; onFocusOutside?.(event); onInteractOutside?.(event); if (!event.defaultPrevented) onDismiss?.(); }, ownerDocument); (0, import_react_use_escape_keydown.useEscapeKeydown)((event) => { const isHighestLayer = index === context.layers.size - 1; if (!isHighestLayer) return; onEscapeKeyDown?.(event); if (!event.defaultPrevented && onDismiss) { event.preventDefault(); onDismiss(); } }, ownerDocument); React.useEffect(() => { if (!node) return; if (disableOutsidePointerEvents) { if (context.layersWithOutsidePointerEventsDisabled.size === 0) { originalBodyPointerEvents = ownerDocument.body.style.pointerEvents; ownerDocument.body.style.pointerEvents = "none"; } context.layersWithOutsidePointerEventsDisabled.add(node); } context.layers.add(node); dispatchUpdate(); return () => { if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) { ownerDocument.body.style.pointerEvents = originalBodyPointerEvents; } }; }, [node, ownerDocument, disableOutsidePointerEvents, context]); React.useEffect(() => { return () => { if (!node) return; context.layers.delete(node); context.layersWithOutsidePointerEventsDisabled.delete(node); dispatchUpdate(); }; }, [node, context]); React.useEffect(() => { const handleUpdate = () => force({}); document.addEventListener(CONTEXT_UPDATE, handleUpdate); return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate); }, []); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_react_primitive.Primitive.div, { ...layerProps, ref: composedRefs, style: { pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0, ...props.style }, onFocusCapture: (0, import_primitive.composeEventHandlers)(props.onFocusCapture, focusOutside.onFocusCapture), onBlurCapture: (0, import_primitive.composeEventHandlers)(props.onBlurCapture, focusOutside.onBlurCapture), onPointerDownCapture: (0, import_primitive.composeEventHandlers)( props.onPointerDownCapture, pointerDownOutside.onPointerDownCapture ) } ); } ); DismissableLayer.displayName = DISMISSABLE_LAYER_NAME; var BRANCH_NAME = "DismissableLayerBranch"; var DismissableLayerBranch = React.forwardRef((props, forwardedRef) => { const context = React.useContext(DismissableLayerContext); const ref = React.useRef(null); const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref); React.useEffect(() => { const node = ref.current; if (node) { context.branches.add(node); return () => { context.branches.delete(node); }; } }, [context.branches]); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref: composedRefs }); }); DismissableLayerBranch.displayName = BRANCH_NAME; function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) { const handlePointerDownOutside = (0, import_react_use_callback_ref.useCallbackRef)(onPointerDownOutside); const isPointerInsideReactTreeRef = React.useRef(false); const handleClickRef = React.useRef(() => { }); React.useEffect(() => { const handlePointerDown = (event) => { if (event.target && !isPointerInsideReactTreeRef.current) { let handleAndDispatchPointerDownOutsideEvent2 = function() { handleAndDispatchCustomEvent( POINTER_DOWN_OUTSIDE, handlePointerDownOutside, eventDetail, { discrete: true } ); }; var handleAndDispatchPointerDownOutsideEvent = handleAndDispatchPointerDownOutsideEvent2; const eventDetail = { originalEvent: event }; if (event.pointerType === "touch") { ownerDocument.removeEventListener("click", handleClickRef.current); handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2; ownerDocument.addEventListener("click", handleClickRef.current, { once: true }); } else { handleAndDispatchPointerDownOutsideEvent2(); } } else { ownerDocument.removeEventListener("click", handleClickRef.current); } isPointerInsideReactTreeRef.current = false; }; const timerId = window.setTimeout(() => { ownerDocument.addEventListener("pointerdown", handlePointerDown); }, 0); return () => { window.clearTimeout(timerId); ownerDocument.removeEventListener("pointerdown", handlePointerDown); ownerDocument.removeEventListener("click", handleClickRef.current); }; }, [ownerDocument, handlePointerDownOutside]); return { // ensures we check React component tree (not just DOM tree) onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true }; } function useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) { const handleFocusOutside = (0, import_react_use_callback_ref.useCallbackRef)(onFocusOutside); const isFocusInsideReactTreeRef = React.useRef(false); React.useEffect(() => { const handleFocus = (event) => { if (event.target && !isFocusInsideReactTreeRef.current) { const eventDetail = { originalEvent: event }; handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, { discrete: false }); } }; ownerDocument.addEventListener("focusin", handleFocus); return () => ownerDocument.removeEventListener("focusin", handleFocus); }, [ownerDocument, handleFocusOutside]); return { onFocusCapture: () => isFocusInsideReactTreeRef.current = true, onBlurCapture: () => isFocusInsideReactTreeRef.current = false }; } function dispatchUpdate() { const event = new CustomEvent(CONTEXT_UPDATE); document.dispatchEvent(event); } function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) { const target = detail.originalEvent.target; const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail }); if (handler) target.addEventListener(name, handler, { once: true }); if (discrete) { (0, import_react_primitive.dispatchDiscreteCustomEvent)(target, event); } else { target.dispatchEvent(event); } } var Root = DismissableLayer; var Branch = DismissableLayerBranch; //# sourceMappingURL=index.js.map