UNPKG

@difizen/mana-core

Version:

143 lines (128 loc) 4.08 kB
import type { CommandHandler } from '../command/command-protocol'; import type { DefaultActionMenuItem, DefaultGeneralMenuItem, } from './default-menu-node'; export type ActionMenuItem = DefaultActionMenuItem; export type GeneralMenuItem = DefaultGeneralMenuItem; export type MenuPath = string[]; export namespace MenuSymbol { export const MenuNodeSymbol = Symbol('MenuNodeSymbol'); export const ActionMenuNodeSymbol = Symbol('ActionMenuNodeSymbol'); export const ParentPathSymbol = Symbol('ParentPathSymbol'); } /** * Factory for instantiating menu item. */ export const GeneralMenuItemFactory = Symbol('GeneralMenuItemFactory'); export interface GeneralMenuItemFactory { (item: MenuNode, menuPath: MenuPath): GeneralMenuItem; } /** * Factory for instantiating menu item. */ export const ActionMenuItemFactory = Symbol('ActionMenuItemFactory'); export interface ActionMenuItemFactory { (item: ActionMenuNode, menuPath: MenuPath): ActionMenuItem; } /** * Base interface of the nodes used in the menu tree structure. */ export interface MenuNode { /** * The unique ID of the menu node. */ label?: React.ReactNode | React.FC; /** * technical identifier. */ readonly id: string; /** * The order to display menu node. */ order?: string; /** * Optional icon for the menu item */ icon?: React.ReactNode | React.FC; } export namespace MenuNode { export function is(arg: any): arg is MenuNode { return !!arg && typeof arg === 'object' && 'id' in arg; } } export interface CommandMenuNode extends MenuNode { /** * The command to execute. */ command: string; /** * In addition to the mandatory command property, an alternative command can be defined. * It will be shown and invoked when pressing Alt while opening a menu. */ alt?: string; } export namespace CommandMenuNode { /* Determine whether object is a MenuAction */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function is(arg: any): arg is CommandMenuNode { return MenuNode.is(arg) && 'command' in arg; } } export interface ExecutableMenuNode extends MenuNode, CommandHandler { command?: string; /** * In addition to the mandatory command property, an alternative command can be defined. * It will be shown and invoked when pressing Alt while opening a menu. */ alt?: string; } export namespace ExecutableMenuNode { /* Determine whether object is a MenuAction */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function is(arg: any): arg is ExecutableMenuNode { return MenuNode.is(arg) && 'execute' in arg; } } export type ActionMenuNode = CommandMenuNode | ExecutableMenuNode; export namespace ActionMenuNode { /* Determine whether object is a MenuAction */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function is(arg: any): arg is ActionMenuNode { return CommandMenuNode.is(arg) || ExecutableMenuNode.is(arg); } } export type MenuOptions = Omit<MenuNode, 'id'>; export namespace MenuItem { /* Determine whether object is a MenuAction */ export function isGeneralMenuItem(arg: any): arg is GeneralMenuItem { return ( MenuNode.is(arg) && 'children' in arg && ('addNode' in arg || 'removeNode' in arg) ); } /* Determine whether object is a MenuAction */ export function isActionMenuItem(arg: any): arg is ActionMenuItem { return ActionMenuNode.is(arg) && 'command' in arg && 'onDisposed' in arg; } } export namespace ActionMenuItem { /** * @deprecated use MenuItem.isActionMenuItem instead * @param arg * @returns arg is ActionMenuItem */ export function is(arg: any): arg is ActionMenuItem { return MenuItem.isActionMenuItem(arg); } } export namespace GeneralMenuItem { /** * @deprecated use MenuItem.isGeneralMenuItem instead * @param arg * @returns arg is GeneralMenuItem */ export function is(arg: any): arg is GeneralMenuItem { return MenuItem.isGeneralMenuItem(arg); } } export type MenuItem = ActionMenuItem | GeneralMenuItem;