import { createEffect, createSignal, onCleanup } from "solid-js"; type DesktopMenuController = { isOpen: () => boolean; rootRef: HTMLDivElement | undefined; menuRef: HTMLDivElement | undefined; setRootRef: (element: HTMLDivElement) => void; setMenuRef: (element: HTMLDivElement) => void; closeMenu: VoidFunction; toggleMenu: VoidFunction; }; // Shared desktop popover behavior for top-bar menus. export const createDesktopMenuController = (): DesktopMenuController => { const [isOpen, setIsOpen] = createSignal(false); let rootRef: HTMLDivElement | undefined; let menuRef: HTMLDivElement | undefined; const closeMenu = (): void => { setIsOpen(false); }; const toggleMenu = (): void => { setIsOpen((open) => !open); }; createEffect(() => { if (!isOpen()) return; const handlePointerDown = (event: PointerEvent): void => { if (!rootRef) return; const target = event.target; if (target instanceof Node && !rootRef.contains(target)) { closeMenu(); } }; const handleKeyDown = (event: KeyboardEvent): void => { if (event.key === "Escape") { closeMenu(); } }; document.addEventListener("pointerdown", handlePointerDown); document.addEventListener("keydown", handleKeyDown); menuRef?.querySelector("[role='menuitem']")?.focus(); onCleanup(() => { document.removeEventListener("pointerdown", handlePointerDown); document.removeEventListener("keydown", handleKeyDown); }); }); return { isOpen, get rootRef() { return rootRef; }, get menuRef() { return menuRef; }, setRootRef: (element: HTMLDivElement): void => { rootRef = element; }, setMenuRef: (element: HTMLDivElement): void => { menuRef = element; }, closeMenu, toggleMenu, }; };