// A single app-wide context menu. import type { Component } from 'svelte'; export type MenuItem = | { label: string; icon?: Component; action: () => void; danger?: boolean; disabled?: boolean; hint?: string } | 'separator'; class Menu { open = $state(false); x = $state(0); y = $state(0); items = $state.raw([]); /** Grow upward from (x, y) — for menus opened from the bottom toolbar. */ above = $state(false); show(x: number, y: number, items: MenuItem[]) { this.above = false; this.x = x; this.y = y; this.items = items; this.open = true; } /** Open below/beside an anchor element. */ showAt(el: Element, items: MenuItem[], placement: 'below' | 'above' = 'below') { const r = el.getBoundingClientRect(); this.show(r.left, placement === 'below' ? r.bottom + 4 : r.top - 4, items); this.above = placement === 'above'; } close() { this.open = false; this.above = false; } } export const menu = new Menu();