/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-f1f3d22 | Cube Dev Team */
import { SlotProvider } from "../../../utils/react/Slots.js";
import { useEventBus } from "../../../utils/react/useEventBus.js";
import { MenuContext } from "./context.js";
import { generateRandomId } from "../../../utils/random.js";
import { _Tray } from "../../overlays/Modal/Tray.js";
import { _Popover } from "../../overlays/Modal/Popover.js";
import { Fragment, forwardRef, useEffect, useMemo, useRef } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { DismissButton, useMenuTrigger, useOverlayPosition } from "react-aria";
import { useDOMRef, useIsMobileDevice } from "@react-spectrum/utils";
import { useMenuTriggerState } from "react-stately";
import { PressResponder } from "@react-aria/interactions";

//#region src/components/actions/Menu/MenuTrigger.tsx
function MenuTrigger(props, ref) {
	const menuPopoverRef = useRef(null);
	const triggerRef = useRef(null);
	const domRef = useDOMRef(ref);
	const menuTriggerRef = props.targetRef || domRef || triggerRef;
	const menuRef = useRef(null);
	const wasOpenRef = useRef(false);
	const { children, shouldFlip = true, closeOnSelect, trigger = "press", isDisabled, isDummy } = props;
	const menuId = useMemo(() => generateRandomId(), []);
	const { emit, on } = useEventBus();
	if (!Array.isArray(children) || children.length > 2) throw new Error("MenuTrigger must have exactly 2 children");
	let [menuTrigger, menu] = children;
	const state = useMenuTriggerState(props);
	useEffect(() => {
		return on("popover:open", (data) => {
			if (data.menuId !== menuId && state.isOpen && !isDummy) state.close();
		});
	}, [
		on,
		menuId,
		state
	]);
	useEffect(() => {
		if (state.isOpen && !isDummy) emit("popover:open", { menuId });
	}, [
		state.isOpen,
		emit,
		menuId,
		isDummy
	]);
	useEffect(() => {
		if (!state.isOpen && wasOpenRef.current && !isDummy) {
			wasOpenRef.current = false;
			setTimeout(() => {
				menuTriggerRef.current?.focus();
			}, 0);
		} else if (state.isOpen) wasOpenRef.current = true;
	}, [
		state.isOpen,
		menuTriggerRef,
		isDummy
	]);
	if (typeof menuTrigger === "function") menuTrigger = menuTrigger(state);
	const { menuTriggerProps, menuProps } = useMenuTrigger({ isDisabled }, state, menuTriggerRef);
	let initialPlacement = props.placement ?? "bottom start";
	const isMobile = useIsMobileDevice();
	const { overlayProps: positionProps, placement } = useOverlayPosition({
		targetRef: menuTriggerRef,
		overlayRef: menuPopoverRef,
		scrollRef: menuRef,
		placement: initialPlacement,
		shouldFlip,
		isOpen: state.isOpen && !isMobile,
		onClose: state.close,
		containerPadding: props.containerPadding,
		offset: props.offset ?? 8,
		crossOffset: props.crossOffset ?? 0
	});
	const menuContext = {
		...menuProps,
		ref: menuRef,
		onClose: state.close,
		closeOnSelect,
		autoFocus: state.focusStrategy ?? "first",
		style: isMobile ? {
			width: "100%",
			maxHeight: "inherit"
		} : void 0,
		mods: {
			popover: !isMobile,
			tray: isMobile
		},
		isClosing: !state.isOpen
	};
	const contents = /* @__PURE__ */ jsxs(Fragment$1, { children: [
		/* @__PURE__ */ jsx(DismissButton, { onDismiss: state.close }),
		menu,
		/* @__PURE__ */ jsx(DismissButton, { onDismiss: state.close })
	] });
	let overlay;
	if (isMobile) overlay = /* @__PURE__ */ jsx(_Tray, {
		isOpen: state.isOpen,
		onClose: state.close,
		children: contents
	});
	else overlay = /* @__PURE__ */ jsx(_Popover, {
		ref: menuPopoverRef,
		hideArrow: true,
		isNonModal: true,
		isOpen: state.isOpen,
		style: positionProps.style,
		placement,
		shouldCloseOnInteractOutside: (el) => {
			const menuTriggerEl = el.closest("[data-popover-trigger]");
			if (!menuTriggerEl) return true;
			if (isDummy && (menuTriggerEl === menuTriggerRef.current || menuTriggerRef.current?.contains(el))) return true;
			if (menuTriggerEl === menuTriggerRef.current) return true;
			return false;
		},
		onClose: state.close,
		children: contents
	});
	return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SlotProvider, {
		slots: { actionButton: { holdAffordance: trigger === "longPress" } },
		children: !isDummy ? /* @__PURE__ */ jsx(PressResponder, {
			...menuTriggerProps,
			ref: menuTriggerRef,
			"data-popover-trigger": true,
			isPressed: state.isOpen,
			children: menuTrigger
		}) : null
	}), /* @__PURE__ */ jsx(MenuContext.Provider, {
		value: menuContext,
		children: overlay
	})] });
}
/**
* The MenuTrigger serves as a wrapper around a Menu and its associated trigger,
* linking the Menu's open state with the trigger's press state.
*/
let _MenuTrigger = forwardRef(MenuTrigger);
_MenuTrigger.displayName = "MenuTrigger";

//#endregion
export { _MenuTrigger };
//# sourceMappingURL=MenuTrigger.js.map