import { CloseBehavior, MenuInstance, MenuInstanceOptions, PositionOptions, Selection } from "./MenuInstance" import { MenuItem } from "./MenuItem" export class Menu { private active?: MenuInstance async close(behavior = CloseBehavior.Immediate): Promise { if (!this.active) return return this.active.close(behavior) } /** * Shows a menu. * * It'll resolve with the selected item, but not before all the animations * finish. Note that this may break the user interaction chain, so if you * want to execute code that needs to originate with a user interaction, use * the {@link MenuInstanceOptions#onSelection} callback instead of awaiting * the returned promise. */ async show( items: MenuItem[], { className, location, within, isDarkMode, maxItemsPerMenu, enableTranslate, onSelection, expandRight, }: MenuInstanceOptions & PositionOptions ): Promise { if (this.active) { if (this.active.isOpenWith(items)) { this.active.position({ location, within, expandRight }) return this.active.wait() } else { await this.active.close(CloseBehavior.NoAnimation) } } const instance = new MenuInstance(items, { className, isDarkMode, maxItemsPerMenu, enableTranslate }) this.active = instance const promise = instance.show({ location, within, expandRight }, onSelection) promise.finally(() => { if (this.active !== instance) return this.active = undefined }) return promise } } /** * A single instance that can be used to avoid more than one menu showing on screen at once. */ export const menu = new Menu()