import { promiseWithResolvers, type PromiseWithResolvers } from "octagonal-wheels/promises"; import { createNativeElement } from "@/apps/browserDom"; import { mount } from "svelte"; import MenuView from "./ui/MenuView.svelte"; import { _activeDocument } from "@vrtmrz/livesync-commonlib/compat/common/coreEnvFunctions"; export class MenuItem { type = "item"; title = ""; handler?: () => void | Promise; icon: string = ""; setTitle(title: string) { this.title = title; return this; } onClick(callback: () => void | Promise) { this.handler = callback; return this; } setIcon(icon: string | null) { this.icon = icon || ""; return this; } } export class MenuSeparator { type = "separator"; } export class Menu { type = "menu"; items: (MenuItem | MenuSeparator)[] = []; constructor() {} addItem(callback: (item: MenuItem) => void) { const item = new MenuItem(); callback(item); this.items.push(item); return this; } addSeparator() { this.items.push(new MenuSeparator()); return this; } waitingForClose?: PromiseWithResolvers; showAtPosition(pos: { x: number; y: number }) { const el = createNativeElement(_activeDocument, "div"); if (this.waitingForClose) { this.waitingForClose.resolve(); } this.waitingForClose = promiseWithResolvers(); mount(MenuView, { target: el, props: { items: this.items, closeMenu: () => { this.waitingForClose?.resolve(); this.waitingForClose = undefined; }, x: pos.x, y: pos.y, }, }); _activeDocument.body.appendChild(el); void this.waitingForClose.promise.finally(() => { el.remove(); }); return this.waitingForClose.promise; } hide() { this.waitingForClose?.resolve(); this.waitingForClose = undefined; } }