UNPKG

@laserware/hoverboard

Version:

Better context menus for Electron.

467 lines (452 loc) 18.3 kB
import { MenuItemConstructorOptions } from 'electron'; type ContextMenuEventType = "click" | "hide" | "show"; interface ContextMenuEventInit extends EventModifierInit { clientX?: number; clientY?: number; menuItem: ContextMenuItem | null; triggeredByAccelerator?: boolean; } type ContextMenuEventListener = (event: ContextMenuEvent) => void; interface ContextMenuEventListenerObject { handleEvent(object: ContextMenuEvent): void; } type ContextMenuEventListenerOrEventListenerObject = ContextMenuEventListener | ContextMenuEventListenerObject; declare class ContextMenuEvent extends Event { clientX: number; clientY: number; menuItem: ContextMenuItem | null; triggeredByAccelerator: boolean; constructor(type: ContextMenuEventType, eventInitDict: ContextMenuEventInit); } interface RadioMenuItemOptions extends NormalMenuItemOptions { checked?: boolean | undefined; } declare function radio(options: RadioMenuItemOptions): RadioMenuItem; declare class RadioMenuItem extends NormalMenuItem<RadioMenuItemOptions> { constructor(options: RadioMenuItemOptions); checked: boolean | undefined; select(): void; toTemplate(): MenuItemConstructorOptions; } /** * Role for a {@linkcode RoleMenuItem}. See the [Electron documentation](https://www.electronjs.org/docs/latest/api/menu-item#roles) * for additional information. * * @remarks * Some of the menu item roles don't work in a context menu, so if clicking * on it doesn't do anything, that's why. */ type ContextMenuItemRole = MenuItemConstructorOptions["role"]; /** * Type of context menu item. See the [Electron documentation](https://www.electronjs.org/docs/latest/api/menu-item#menuitemtype) * for additional information. */ type ContextMenuItemType = MenuItemConstructorOptions["type"]; interface RoleMenuItemOptions extends ContextMenuItemOptions { accelerator?: string | undefined; acceleratorWorksWhenHidden?: boolean | undefined; enabled?: boolean | undefined; icon?: string | undefined; role: ContextMenuItemRole; registerAccelerator?: boolean | undefined; tooltip?: string | undefined; } declare function role(role: ContextMenuItemRole): RoleMenuItem; declare function role(options: RoleMenuItemOptions): RoleMenuItem; declare class RoleMenuItem extends ContextMenuItem { constructor(role: ContextMenuItemRole); constructor(options: RoleMenuItemOptions); accelerator: string | undefined; acceleratorWorksWhenHidden: boolean | undefined; enabled: boolean | undefined; icon: string | undefined; registerAccelerator: boolean | undefined; role: ContextMenuItemRole; tooltip: string | undefined; toTemplate(): MenuItemConstructorOptions; } type SeparatorMenuItemOptions = ContextMenuItemOptions; declare function separator(options?: SeparatorMenuItemOptions): SeparatorMenuItem; declare class SeparatorMenuItem extends ContextMenuItem { constructor(options?: SeparatorMenuItemOptions); toTemplate(): MenuItemConstructorOptions; } /** * Options for creating a Share menu item. */ interface ShareMenuItemOptions extends ContextMenuItemOptions { /** Array of file paths to share. */ filePaths?: string[]; /** Array of text values to share. */ texts?: string[]; /** Array of URLs to share. */ urls?: string[]; } /** * Creates a new Share menu for sharing items on macOS. * * @param options Options for the share menu item. */ declare function shareMenu(options: ShareMenuItemOptions): ShareMenuItem; /** * Share menu for sharing items on macOS. */ declare class ShareMenuItem extends ContextMenuItem { constructor(options: ShareMenuItemOptions); filePaths: string[] | undefined; texts: string[] | undefined; urls: string[] | undefined; toTemplate(): MenuItemConstructorOptions; /** * Ensures the share menu has at least 1 sharing item. * * @throws Error If nothing is being shared. */ validate(): void; } type MenuBuilderFunction = (builder: MenuBuilder) => MenuBuilder; /** * Used to build a context menu with a builder function, rather than specifying * an array of menu items. * * @internal */ declare class MenuBuilder { #private; /** Items in the context menu. */ get items(): ContextMenuItem[]; /** * Adds the specified `item` to the context menu. * * @param item Context menu item to add. */ add(item: ContextMenuItem): this; /** * Iterates over the specified `values` and calls the `onValue` callback to * add menu items to the menu. * * This is useful for adding multiple submenu items in a builder function. * * @param values Array of values of any type to iterate over. * @param onValue Callback called for each value. * * @example * const menu = contextMenu((builder) => * builder.submenu( * { * id: "submenu", * label: "Radio Options", * sublabel: "This is a sublabel", * }, * (builder) => * builder.map(["1", "2", "3"], (value) => * builder.radio({ * label: `Option ${value}`, * checked: activeOption === value, * click() { * console.log(`Clicked ${value}`); * }, * }), * ), * ), * ); */ map<T>(values: T[], onValue: (value: T) => any): this; /** Adds a checkbox menu item to the menu with the specified options. */ checkbox(options: CheckboxMenuItemOptions): this; /** Adds a normal menu item to the menu with the specified options. */ normal(options: NormalMenuItemOptions): this; /** Adds a radio menu item to the menu with the specified options. */ radio(options: RadioMenuItemOptions): this; /** Adds a role menu item to the menu with the specified options. */ role(options: RoleMenuItemOptions): this; /** Adds a separator menu item to the menu. */ separator(options?: SeparatorMenuItemOptions): this; /** * Adds a Share Menu item to the menu. * * @platforms macOS */ shareMenu(options: ShareMenuItemOptions): this; /** * Adds a submenu menu item to the context menu with the specified `options` * and containing the specified `items`. */ submenu(options: SubmenuMenuItemOptions, items: ContextMenuItem[]): this; /** * Adds a submenu menu item to the context menu with the specified `options` * and items added with the specified `build` function. */ submenu(options: SubmenuMenuItemOptions, build: MenuBuilderFunction): this; } interface SubmenuMenuItemOptions extends ContextMenuItemOptions { enabled?: boolean | undefined; icon?: string | undefined; label: string | undefined; toolTip?: string | undefined; } declare function submenu(options: SubmenuMenuItemOptions, items: ContextMenuItem[]): SubmenuMenuItem; declare function submenu(options: SubmenuMenuItemOptions, build: MenuBuilderFunction): SubmenuMenuItem; declare class SubmenuMenuItem extends ContextMenuItem { constructor(options: SubmenuMenuItemOptions, build: MenuBuilderFunction); constructor(options: SubmenuMenuItemOptions, items: ContextMenuItem[]); enabled: boolean | undefined; icon: string | undefined; items: ContextMenuItem[]; label: string | undefined; toolTip: string | undefined; [Symbol.iterator](): Generator<ContextMenuItem, void, unknown>; toTemplate(): MenuItemConstructorOptions; } /** * This is the click event fired in the _renderer_ process when a context menu * item is clicked. It has a different signature than the [`click` property](https://www.electronjs.org/docs/latest/api/menu-item#menuitemclick) * of the `MenuItemConstructorOptions`. */ type OnContextMenuItemClick = (menuItem: ContextMenuItem, event: ContextMenuEvent) => void | Promise<void>; /** * Options for creating a base context menu item. * * @internal */ interface ContextMenuItemOptions { /** * ID of the menu item. Not all menu items require an ID (i.e. separator and * role), but all other menu items will need an ID to capture the click event, * so we set it here. */ id?: string; /** * Sets the visibility of the menu item. */ visible?: boolean; /** * Inserts this item before the item with the specified ID. If the referenced item * doesn't exist the item will be inserted at the end of the menu. Also implies * that the menu item in question should be placed in the same "group" as the item. */ before?: string[]; /** * Inserts this item after the item with the specified ID. If the referenced item * doesn't exist the item will be inserted at the end of the menu. */ after?: string[]; /** * Provides a means for a single context menu to declare the placement of their * containing group before the containing group of the item with the specified ID. */ beforeGroupContaining?: string[]; /** * Provides a means for a single context menu to declare the placement of their * containing group after the containing group of the item with the specified ID. */ afterGroupContaining?: string[]; } /** * Base context menu item from which other context menu items are derived. */ declare class ContextMenuItem { constructor(options?: ContextMenuItemOptions, type?: ContextMenuItemType); /** ID of the menu item. */ id: string; /** * Type of the context menu item. See the [Electron documentation](https://www.electronjs.org/docs/latest/api/menu-item#menuitemtype) * for additional information. */ type: ContextMenuItemType; /** Indicates if the menu item is visible. */ visible: boolean | undefined; /** * Inserts this item before the item with the specified ID. If the referenced item * doesn't exist the item will be inserted at the end of the menu. Also implies * that the menu item in question should be placed in the same "group" as the item. */ before: string[] | undefined; /** * Inserts this item after the item with the specified ID. If the referenced item * doesn't exist the item will be inserted at the end of the menu. */ after: string[] | undefined; /** * Provides a means for a single context menu to declare the placement of their * containing group before the containing group of the item with the specified ID. */ beforeGroupContaining: string[] | undefined; /** * Provides a means for a single context menu to declare the placement of their * containing group after the containing group of the item with the specified ID. */ afterGroupContaining: string[] | undefined; /** * Parent submenu of the menu item. If the menu item is not part of a submenu, * this is undefined. */ parent: SubmenuMenuItem | undefined; /** * Converts the properties of this menu item to a template that can be sent * to the main process to build the menu. */ toTemplate(): MenuItemConstructorOptions; } interface NormalMenuItemOptions extends ContextMenuItemOptions { accelerator?: string | undefined; acceleratorWorksWhenHidden?: boolean | undefined; enabled?: boolean | undefined; icon?: string | undefined; label: string | undefined; registerAccelerator?: boolean | undefined; toolTip?: string | undefined; click?: OnContextMenuItemClick; } declare function normal(options: NormalMenuItemOptions): NormalMenuItem; declare class NormalMenuItem<Options extends NormalMenuItemOptions = NormalMenuItemOptions> extends ContextMenuItem { constructor(options: Options, type?: ContextMenuItemType); accelerator: string | undefined; acceleratorWorksWhenHidden: boolean | undefined; click: OnContextMenuItemClick | undefined; enabled: boolean | undefined; icon: string | undefined; label: string | undefined; registerAccelerator: boolean | undefined; toolTip: string | undefined; toTemplate(): MenuItemConstructorOptions; } /** * Options for creating a checkbox menu item. */ interface CheckboxMenuItemOptions extends NormalMenuItemOptions { /** Indicates if checkbox is currently checked. */ checked?: boolean | undefined; } /** * Returns a new {@linkcode CheckboxMenuItem} that can be added to a context * menu. * * @param options Options for creating the checkbox menu item. */ declare function checkbox(options: CheckboxMenuItemOptions): CheckboxMenuItem; /** * Checkbox menu item in a context menu. This behaves similarly to a * {@linkcode NormalMenuItem} with the addition of a checked state. Multiple * items in the same submenu can be checked. If you need only one item checked * at a time, use the {@linkcode RadioMenuItem} instead. */ declare class CheckboxMenuItem extends NormalMenuItem<CheckboxMenuItemOptions> { constructor(options: CheckboxMenuItemOptions); /** Indicates if checkbox is currently checked. */ checked: boolean | undefined; toTemplate(): MenuItemConstructorOptions; } /** * Creates a new context menu with the specified `items`. * * @param items Context menu items to add to context menu. * * @returns Context menu with specified items. */ declare function contextMenu(items: ContextMenuItem[]): ContextMenu; /** * Builds a new context menu using the specified `build` function. * * @param build Function with menu builder to assign items to menu. * * @returns Context menu with items added from build function. */ declare function contextMenu(build: MenuBuilderFunction): ContextMenu; /** * Provides the means to create and show custom context menus. */ declare class ContextMenu extends EventTarget { /** * Creates a new context menu with the specified `items`. * * @param items Context menu items to add to context menu. */ constructor(items: ContextMenuItem[]); /** * Builds a new context menu using the specified `build` function. * * @param build Function with menu builder to assign items to menu. */ constructor(build: MenuBuilderFunction); [Symbol.iterator](): Generator<ContextMenuItem, void, unknown>; id: string; items: ContextMenuItem[]; /** * Appends the specified `item` to the context menu. * * @param item Menu item to append to context menu. */ append(item: ContextMenuItem): void; /** * Inserts the specified `item` in the specified position of the context * menu. * * @param position Position in the menu to add the item. * @param item Item to insert into the context menu. */ insert(position: number, item: ContextMenuItem): void; /** * Removes the specified `item` from the context menu. * * @param item Menu item to remove from context menu. */ remove(item: ContextMenuItem): void; /** * Returns the menu item associated with the specified `id`. If the menu * item doesn't exist, returns null. * * @param id ID of the menu item to find. * * @returns The menu item if found, otherwise null. */ getMenuItemById(id: string): ContextMenuItem | null; /** * Converts the contents of the context menu item to a serializable template * that is sent to the main process to build the context menu. */ toTemplate(): MenuItemConstructorOptions[]; /** * Adds an event listener for the click event of a context menu item. This * event is fired when any context menu item is clicked. This is dispatched * *after* the `click` property of a menu item. */ addEventListener(type: "click", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; /** * Adds an event listener for the hide event of a context menu. This event * is dispatched immediately after the menu is hidden. */ addEventListener(type: "hide", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; /** * Adds an event listener for the show event of a context menu. This event * is dispatched immediately before the menu is shown. */ addEventListener(type: "show", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; removeEventListener(type: "click", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; removeEventListener(type: "hide", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; removeEventListener(type: "show", callback: ContextMenuEventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; /** * Hides the context menu (if it is open). */ hide(): Promise<void>; /** * Shows the context menu in the specified `x` and `y` coordinates. * * @param x X location to display the context menu. * @param y Y location to display the context menu. * * @returns Promise resolving with the menu item that was clicked. If no menu * item was clicked, resolves to `null`. */ show(x: number, y: number): Promise<ContextMenuItem | null>; } declare const items: { checkbox: typeof checkbox; normal: typeof normal; radio: typeof radio; role: typeof role; separator: typeof separator; shareMenu: typeof shareMenu; submenu: typeof submenu; }; export { CheckboxMenuItem, type CheckboxMenuItemOptions, ContextMenu, ContextMenuEvent, type ContextMenuEventInit, type ContextMenuEventListenerOrEventListenerObject, type ContextMenuEventType, ContextMenuItem, NormalMenuItem, type NormalMenuItemOptions, RadioMenuItem, type RadioMenuItemOptions, RoleMenuItem, type RoleMenuItemOptions, SeparatorMenuItem, type SeparatorMenuItemOptions, ShareMenuItem, type ShareMenuItemOptions, SubmenuMenuItem, type SubmenuMenuItemOptions, checkbox, contextMenu, items, normal, radio, role, separator, shareMenu, submenu };