/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-29d58ba | Cube Dev Team */
import { mergeProps as mergeProps$1 } from "../../utils/react/mergeProps.js";
import { useEventBus } from "../../utils/react/useEventBus.js";
import { useEvent } from "../../_internal/hooks/use-event.js";
import { generateRandomId } from "../../utils/random.js";
import { _MenuTrigger } from "./Menu/MenuTrigger.js";
import { useEffect, useMemo, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { VisuallyHidden } from "react-aria";
import { Pressable } from "@react-aria/interactions";

//#region src/components/actions/use-anchored-menu.tsx
/**
* Generic hook to manage an anchored menu component.
*
* @param Component - A React component that represents the menu content (Menu or CommandMenu).
* @param defaultTriggerProps - Default props to pass to the MenuTrigger.
* @param defaultMenuProps - Default props to pass to the Menu component.
* @returns An object with `anchorRef` to position the menu, `open` function to open the menu with provided props, `close` function to close the menu, and `rendered` JSX element to include in your component tree.
*/
function useAnchoredMenu(Component, defaultTriggerProps, defaultMenuProps) {
	const [isOpen, setIsOpen] = useState(false);
	const [componentProps, setComponentProps] = useState(null);
	const [triggerProps, setTriggerProps] = useState(null);
	const anchorRef = useRef(null);
	const setupRef = useRef(false);
	useEffect(() => {
		const el = anchorRef.current;
		if (el) {
			el.dataset.popoverTrigger = "";
			return () => {
				delete el.dataset.popoverTrigger;
			};
		}
	}, []);
	const menuId = useMemo(() => generateRandomId(), []);
	const { emit, on } = useEventBus();
	useEffect(() => {
		return on("popover:open", (data) => {
			if (data.menuId !== menuId && isOpen) setIsOpen(false);
		});
	}, [
		on,
		menuId,
		isOpen
	]);
	useEffect(() => {
		if (isOpen) emit("popover:open", { menuId });
	}, [
		isOpen,
		emit,
		menuId
	]);
	function setupCheck() {
		if (!setupRef.current) throw new Error("useAnchoredMenu: MenuTrigger must be rendered. Use `rendered` property to include it in your component tree.");
	}
	const open = useEvent((props = {}, triggerProps) => {
		setupCheck();
		setComponentProps(defaultMenuProps ? {
			...defaultMenuProps,
			...props
		} : props);
		setTriggerProps(triggerProps ?? null);
		setIsOpen(true);
	});
	const update = useEvent((props, triggerProps) => {
		setupCheck();
		setComponentProps(defaultMenuProps ? {
			...defaultMenuProps,
			...props
		} : props);
		setTriggerProps(triggerProps ?? null);
	});
	const close = useEvent(() => {
		setIsOpen(false);
	});
	const renderedMenu = useMemo(() => {
		if (!componentProps) return null;
		return /* @__PURE__ */ jsxs(_MenuTrigger, {
			isDummy: true,
			isOpen,
			targetRef: anchorRef,
			placement: "bottom start",
			onOpenChange: setIsOpen,
			...mergeProps$1(defaultTriggerProps, triggerProps || void 0),
			children: [/* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(Pressable, { children: /* @__PURE__ */ jsx("button", { "aria-label": "context-menu" }) }) }), /* @__PURE__ */ jsx(Component, { ...componentProps })]
		});
	}, [
		componentProps,
		triggerProps,
		isOpen,
		defaultTriggerProps
	]);
	return {
		anchorRef,
		open,
		update,
		close,
		isOpen,
		get rendered() {
			setupRef.current = true;
			return renderedMenu;
		}
	};
}

//#endregion
export { useAnchoredMenu };
//# sourceMappingURL=use-anchored-menu.js.map