Orca Note Plugin API Documentation
    Preparing search index...

    Interface Orca

    The main Orca API entry, access it with the global orca object.

    console.log(orca.state.locale)
    
    interface Orca {
        blockMenuCommands: {
            registerBlockMenuCommand(id: string, command: BlockMenuCommand): void;
            unregisterBlockMenuCommand(id: string): void;
        };
        broadcasts: {
            broadcast(type: string, ...args: any[]): void;
            isHandlerRegistered(type: string): boolean;
            registerHandler(type: string, handler: CommandFn): void;
            unregisterHandler(type: string, handler: CommandFn): void;
        };
        commands: {
            invokeCommand(id: string, ...args: any[]): Promise<any>;
            invokeEditorCommand(
                id: string,
                cursor: null | CursorData,
                ...args: any[],
            ): Promise<any>;
            invokeGroup(
                callback: () => Promise<void>,
                options?: { topGroup?: boolean; undoable?: boolean },
            ): Promise<void>;
            invokeTopEditorCommand(
                id: string,
                cursor: null | CursorData,
                ...args: any[],
            ): Promise<any>;
            registerAfterCommand(id: string, fn: AfterHook): void;
            registerBeforeCommand(id: string, pred: BeforeHookPred): void;
            registerCommand(id: string, fn: CommandFn, label: string): void;
            registerEditorCommand(
                id: string,
                doFn: EditorCommandFn,
                undoFn: CommandFn,
                opts: { hasArgs?: boolean; label: string; noFocusNeeded?: boolean },
            ): void;
            unregisterAfterCommand(id: string, fn: AfterHook): void;
            unregisterBeforeCommand(id: string, pred: BeforeHookPred): void;
            unregisterCommand(id: string): void;
            unregisterEditorCommand(id: string): void;
        };
        components: {
            AliasEditor: (
                props: { blockId: number } & Partial<
                    {
                        alignment?: "top"
                        | "bottom"
                        | "left"
                        | "right"
                        | "center";
                        allowBeyondContainer?: boolean;
                        children: (
                            openMenu: (e: UIEvent, state?: any) => void,
                            closeMenu: () => void,
                        ) => ReactNode;
                        className?: string;
                        container?: any;
                        crossOffset?: number;
                        defaultPlacement?: "top" | "bottom" | "left" | "right";
                        escapeToClose?: boolean;
                        keyboardNav?: boolean;
                        menu: (close: () => void, state?: any) => ReactNode;
                        menuAttr?: Record<string, any>;
                        navDirection?: "vertical" | "both";
                        noPointerLogic?: boolean;
                        offset?: number;
                        onClosed?: () => void;
                        onOpened?: () => void;
                        placement?: "vertical" | "horizontal";
                        style?: any;
                    },
                >,
            ) => null
            | Element;
            Block: (
                props: {
                    blockId: number;
                    blockLevel: number;
                    indentLevel: number;
                    initiallyCollapsed?: boolean;
                    panelId: string;
                    renderingMode?: BlockRenderingMode;
                    withBreadcrumb?: boolean;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            BlockBreadcrumb: (
                props: { blockId: number; className?: string; style?: CSSProperties },
            ) => null | Element;
            BlockChildren: (
                props: {
                    block: Block;
                    blockLevel: number;
                    indentLevel: number;
                    panelId: string;
                    renderingMode?: BlockRenderingMode;
                },
            ) => null
            | Element;
            BlockSelect: (
                props: {
                    mode: "block" | "ref";
                    onChange?: (selected: string[]) => void | Promise<void>;
                    scope?: string;
                    selected: number[];
                } & Omit<
                    SelectProps,
                    | "options"
                    | "selected"
                    | "filter"
                    | "filterPlaceholder"
                    | "filterFunction"
                    | "onChange",
                >,
            ) => null
            | Element;
            BlockShell: (
                props: {
                    blockId: number;
                    blockLevel: number;
                    childrenJsx: ReactNode;
                    contentAttrs?: Record<string, any>;
                    contentClassName?: string;
                    contentJsx: ReactNode;
                    contentStyle?: CSSProperties;
                    contentTag?: any;
                    dropppable?: boolean;
                    indentLevel: number;
                    initiallyCollapsed?: boolean;
                    mirrorId?: number;
                    panelId: string;
                    renderingMode?: BlockRenderingMode;
                    reprAttrs?: Record<string, any>;
                    reprClassName: string;
                    rndId: string;
                    withBreadcrumb?: boolean;
                },
            ) => null
            | Element;
            Breadcrumb: (
                props: {
                    className?: string;
                    items: ReactNode[];
                    style?: CSSProperties;
                },
            ) => null
            | Element;
            Button: (
                props: HTMLAttributes<HTMLButtonElement> & {
                    variant: "solid" | "soft" | "dangerous" | "outline" | "plain";
                },
            ) => null
            | Element;
            Checkbox: (
                props: {
                    checked?: boolean;
                    disabled?: boolean;
                    indeterminate?: boolean;
                    onChange?: (e: { checked: boolean }) => void | Promise<void>;
                } & Omit<HTMLAttributes<HTMLSpanElement>, "onChange">,
            ) => null | Element;
            CompositionInput: (
                props: HTMLAttributes<HTMLInputElement> & {
                    error?: ReactNode;
                    post?: ReactElement<any, string | JSXElementConstructor<any>>;
                    pre?: ReactElement<any, string | JSXElementConstructor<any>>;
                },
            ) => null
            | Element;
            CompositionTextArea: (
                props: HTMLAttributes<HTMLTextAreaElement>,
            ) => null | Element;
            ConfirmBox: (
                props: {
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    onConfirm: (
                        e: UIEvent,
                        close: () => void,
                        state?: any,
                    ) => void | Promise<void>;
                    text: string;
                } & Partial<
                    {
                        alignment?: "top"
                        | "bottom"
                        | "left"
                        | "right"
                        | "center";
                        allowBeyondContainer?: boolean;
                        children: (
                            openMenu: (e: UIEvent, state?: any) => void,
                            closeMenu: () => void,
                        ) => ReactNode;
                        className?: string;
                        container?: any;
                        crossOffset?: number;
                        defaultPlacement?: "top" | "bottom" | "left" | "right";
                        escapeToClose?: boolean;
                        keyboardNav?: boolean;
                        menu: (close: () => void, state?: any) => ReactNode;
                        menuAttr?: Record<string, any>;
                        navDirection?: "vertical" | "both";
                        noPointerLogic?: boolean;
                        offset?: number;
                        onClosed?: () => void;
                        onOpened?: () => void;
                        placement?: "vertical" | "horizontal";
                        style?: any;
                    },
                >,
            ) => null
            | Element;
            ContextMenu: (
                props: {
                    alignment?: "top" | "bottom" | "left" | "right" | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: RefObject<HTMLElement>;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: CSSProperties;
                },
            ) => null
            | Element;
            DatePicker: (
                props: {
                    alignment?: "left" | "right" | "center";
                    className?: string;
                    menuContainer?: RefObject<HTMLElement>;
                    mode?: "date" | "time" | "datetime";
                    onChange: (v: Date | [Date, Date]) => void | Promise<void>;
                    onClose?: () => void | Promise<void>;
                    onClosed?: () => void | Promise<void>;
                    range?: boolean;
                    rect?: DOMRect;
                    refElement?: RefObject<HTMLElement>;
                    style?: CSSProperties;
                    value: Date | [Date, Date];
                    visible?: boolean;
                },
            ) => null
            | Element;
            HoverContextMenu: (
                props: { children: ReactElement } & Omit<ContextMenuProps, "children">,
            ) => null | Element;
            Image: (props: HTMLAttributes<HTMLImageElement>) => null | Element;
            Input: (
                props: HTMLAttributes<HTMLInputElement> & {
                    error?: ReactNode;
                    post?: ReactElement<any, string | JSXElementConstructor<any>>;
                    pre?: ReactElement<any, string | JSXElementConstructor<any>>;
                },
            ) => null
            | Element;
            InputBox: (
                props: {
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    defaultValue?: string;
                    error?: ReactNode;
                    label: string;
                    onConfirm: (
                        value: undefined | string,
                        e: UIEvent,
                        close: () => void,
                    ) => void | Promise<void>;
                } & Partial<
                    {
                        alignment?: "top"
                        | "bottom"
                        | "left"
                        | "right"
                        | "center";
                        allowBeyondContainer?: boolean;
                        children: (
                            openMenu: (e: UIEvent, state?: any) => void,
                            closeMenu: () => void,
                        ) => ReactNode;
                        className?: string;
                        container?: any;
                        crossOffset?: number;
                        defaultPlacement?: "top" | "bottom" | "left" | "right";
                        escapeToClose?: boolean;
                        keyboardNav?: boolean;
                        menu: (close: () => void, state?: any) => ReactNode;
                        menuAttr?: Record<string, any>;
                        navDirection?: "vertical" | "both";
                        noPointerLogic?: boolean;
                        offset?: number;
                        onClosed?: () => void;
                        onOpened?: () => void;
                        placement?: "vertical" | "horizontal";
                        style?: any;
                    },
                >,
            ) => null
            | Element;
            LoadMore: (
                props: {
                    debounceTime?: number;
                    message?: string;
                    onLoadMore: () => void | Promise<void>;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            MemoizedViews: (
                props: {
                    active: string;
                    className?: string;
                    name: string;
                    orientation?: "vertical" | "horizontal";
                    style?: CSSProperties;
                    views: {
                        [key: string]:
                            | null
                            | ReactElement<any, string | JSXElementConstructor<any>>;
                    };
                },
            ) => null
            | Element;
            Menu: (
                props: {
                    children?: ReactNode;
                    container?: RefObject<HTMLElement>;
                    keyboardNav?: boolean;
                    navDirection?: "vertical" | "both";
                    onKeyboardNav?: (el: HTMLElement) => void | Promise<void>;
                    refocus?: boolean;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            MenuItem: (
                props: {
                    children?: ReactElement<any, string | JSXElementConstructor<any>>;
                    className?: string;
                    jsx: ReactElement;
                    onClick?: (e: MouseEvent) => void | Promise<void>;
                    style?: CSSProperties;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            MenuSeparator: (props: {}) => null | Element;
            MenuText: (
                props: {
                    centered?: boolean;
                    children?: ReactElement<any, string | JSXElementConstructor<any>>;
                    className?: string;
                    contextMenu?: (close: () => void) => ReactNode;
                    dangerous?: boolean;
                    disabled?: boolean;
                    onClick?: (e: MouseEvent) => void | Promise<void>;
                    postIcon?: string;
                    preIcon?: string;
                    raw?: boolean;
                    shortcut?: string;
                    style?: CSSProperties;
                    subtitle?: string;
                    title: string;
                } & Omit<HTMLAttributes<HTMLDivElement>, "contextMenu">,
            ) => null | Element;
            MenuTitle: (
                props: {
                    className?: string;
                    info?: ReactNode;
                    style?: CSSProperties;
                    title: string;
                },
            ) => null
            | Element;
            ModalOverlay: (
                props: {
                    blurred?: boolean;
                    canClose?: boolean;
                    children: ReactNode;
                    className?: string;
                    onClose?: () => void | Promise<void>;
                    onClosed?: () => void;
                    style?: CSSProperties;
                    visible: boolean;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            Popup: (
                props: {
                    alignment?: "top" | "bottom" | "left" | "right" | "center";
                    allowBeyondContainer?: boolean;
                    boundary?: RefObject<HTMLElement>;
                    children?: ReactElement<any, string | JSXElementConstructor<any>>;
                    className?: string;
                    container?: RefObject<HTMLElement>;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClose?: () => void | Promise<void>;
                    onClosed?: () => void;
                    placement?: "vertical" | "horizontal";
                    rect?: DOMRect;
                    refElement?: RefObject<HTMLElement>;
                    visible: boolean;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            Segmented: (
                props: {
                    className?: string;
                    onChange: (value: string) => void | Promise<void>;
                    options: {
                        jsx?: ReactElement<any, string | JSXElementConstructor<any>>;
                        label?: string;
                        value: string;
                    }[];
                    selected: string;
                    style?: CSSProperties;
                } & Omit<HTMLAttributes<HTMLDivElement>, "onChange">,
            ) => null | Element;
            Select: (
                props: {
                    alignment?: "left" | "right" | "center";
                    buttonClassName?: string;
                    disabled?: boolean;
                    filter?: boolean;
                    filterFunction?: (
                        keyword: string,
                    ) => Promise<{ group?: string; label: string; value: string }[]>;
                    filterPlaceholder?: string;
                    menuClassName?: string;
                    menuContainer?: RefObject<HTMLElement>;
                    multiSelection?: boolean;
                    onChange?: (
                        selected: string[],
                        filterKeyword?: string,
                    ) => void | Promise<void>;
                    onMouseEnter?: (e: MouseEvent) => void;
                    onMouseLeave?: (e: MouseEvent) => void;
                    options: { group?: string; label: string; value: string }[];
                    placeholder?: string;
                    pre?: ReactElement<any, string | JSXElementConstructor<any>>;
                    readOnly?: boolean;
                    selected: string[];
                    width?: string | number;
                    withClear?: boolean;
                },
            ) => null
            | Element;
            Skeleton: (props: {}) => null | Element;
            Switch: (
                props: {
                    on?: boolean;
                    onChange?: (on: boolean) => void | Promise<void>;
                    readonly?: boolean;
                    unset?: boolean;
                } & Omit<HTMLAttributes<HTMLButtonElement>, "onChange">,
            ) => null | Element;
            Table: (
                props: {
                    columns: { icon?: string; name: string }[];
                    initialColumnSizes: string;
                    items: { _type: string; [key: string]: any }[];
                    onColumnResize?: (value: string) => void | Promise<void>;
                    pinColumn?: boolean;
                    rowRenderer: (
                        item: { _type: string; [key: string]: any },
                        className: string,
                        index: number,
                    ) => ReactNode;
                } & HTMLAttributes<HTMLDivElement>,
            ) => null | Element;
            TagPopup: (
                props: {
                    blockId: number;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    closeMenu: () => void;
                    onTagClick: (alias: string) => void | Promise<void>;
                    placeholder?: string;
                } & Partial<
                    {
                        alignment?: "top"
                        | "bottom"
                        | "left"
                        | "right"
                        | "center";
                        allowBeyondContainer?: boolean;
                        children: (
                            openMenu: (e: UIEvent, state?: any) => void,
                            closeMenu: () => void,
                        ) => ReactNode;
                        className?: string;
                        container?: any;
                        crossOffset?: number;
                        defaultPlacement?: "top" | "bottom" | "left" | "right";
                        escapeToClose?: boolean;
                        keyboardNav?: boolean;
                        menu: (close: () => void, state?: any) => ReactNode;
                        menuAttr?: Record<string, any>;
                        navDirection?: "vertical" | "both";
                        noPointerLogic?: boolean;
                        offset?: number;
                        onClosed?: () => void;
                        onOpened?: () => void;
                        placement?: "vertical" | "horizontal";
                        style?: any;
                    },
                >,
            ) => null
            | Element;
            TagPropsEditor: (
                props: {
                    blockId: number;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                } & Partial<
                    {
                        alignment?: "top"
                        | "bottom"
                        | "left"
                        | "right"
                        | "center";
                        allowBeyondContainer?: boolean;
                        children: (
                            openMenu: (e: UIEvent, state?: any) => void,
                            closeMenu: () => void,
                        ) => ReactNode;
                        className?: string;
                        container?: any;
                        crossOffset?: number;
                        defaultPlacement?: "top" | "bottom" | "left" | "right";
                        escapeToClose?: boolean;
                        keyboardNav?: boolean;
                        menu: (close: () => void, state?: any) => ReactNode;
                        menuAttr?: Record<string, any>;
                        navDirection?: "vertical" | "both";
                        noPointerLogic?: boolean;
                        offset?: number;
                        onClosed?: () => void;
                        onOpened?: () => void;
                        placement?: "vertical" | "horizontal";
                        style?: any;
                    },
                >,
            ) => null
            | Element;
            Tooltip: (
                props: {
                    alignment?: "top" | "bottom" | "left" | "right" | "center";
                    allowBeyondContainer?: boolean;
                    children: ReactElement;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    delay?: number;
                    image?: string;
                    modifier?: "shift" | "ctrl" | "alt" | "meta";
                    placement?: "vertical" | "horizontal";
                    shortcut?: string;
                    text: ReactNode;
                    [key: string]: any;
                },
            ) => null
            | Element;
        };
        converters: {
            blockConvert(
                format: string,
                blockContent: BlockForConversion,
                repr: Repr,
                block?: Block,
                forExport?: boolean,
            ): Promise<string>;
            inlineConvert(
                format: string,
                type: string,
                content: ContentFragment,
            ): Promise<string>;
            registerBlock(
                format: string,
                type: string,
                fn: (
                    blockContent: BlockForConversion,
                    repr: Repr,
                    block?: Block,
                    forExport?: boolean,
                ) => string | Promise<string>,
            ): void;
            registerInline(
                format: string,
                type: string,
                fn: (content: ContentFragment) => string | Promise<string>,
            ): void;
            unregisterBlock(format: string, type: string): void;
            unregisterInline(format: string, type: string): void;
        };
        headbar: {
            registerHeadbarButton(id: string, render: () => ReactElement): void;
            unregisterHeadbarButton(id: string): void;
        };
        nav: {
            addTo(
                id: string,
                dir: "top" | "bottom" | "left" | "right",
                src?: Pick<ViewPanel, "view" | "viewArgs" | "viewState">,
            ): null | string;
            changeSizes(startPanelId: string, values: number[]): void;
            close(id: string): void;
            closeAllBut(id: string): void;
            findViewPanel(id: string, panels: RowPanel): null | ViewPanel;
            focusNext(): void;
            focusPrev(): void;
            goBack(withRedo?: boolean): void;
            goForward(): void;
            goTo(
                view: PanelView,
                viewArgs?: Record<string, any>,
                panelId?: string,
            ): void;
            isThereMoreThanOneViewPanel(): boolean;
            move(
                from: string,
                to: string,
                dir: "top" | "bottom" | "left" | "right",
            ): void;
            openInLastPanel(view: PanelView, viewArgs?: Record<string, any>): void;
            switchFocusTo(id: string): void;
        };
        notify: (
            type: "info" | "success" | "warn" | "error",
            message: string,
            options?: { action?: () => void | Promise<void>; title?: string },
        ) => void;
        plugins: {
            clearData(name: string): Promise<void>;
            disable(name: string): Promise<void>;
            enable(name: string): Promise<void>;
            getData(name: string, key: string): Promise<any>;
            getDataKeys(name: string): Promise<string[]>;
            load(
                name: string,
                schema: PluginSettingsSchema,
                settings: Record<string, any>,
            ): Promise<void>;
            register(name: string): Promise<void>;
            removeData(name: string, key: string): Promise<void>;
            setData(
                name: string,
                key: string,
                value: null | string | number | ArrayBuffer,
            ): Promise<void>;
            setSettings(
                to: "app" | "repo",
                name: string,
                settings: Record<string, any>,
            ): Promise<void>;
            setSettingsSchema(
                name: string,
                schema: PluginSettingsSchema,
            ): Promise<void>;
            unload(name: string): Promise<void>;
            unregister(name: string): Promise<void>;
        };
        renderers: {
            registerBlock(
                type: string,
                isEditable: boolean,
                renderer: any,
                assetFields?: string[],
            ): void;
            registerInline(type: string, isEditable: boolean, renderer: any): void;
            unregisterBlock(type: string): void;
            unregisterInline(type: string): void;
        };
        shortcuts: {
            assign(shortcut: string, command: string): Promise<void>;
            reload(): Promise<void>;
            reset(command: string): Promise<void>;
        };
        slashCommands: {
            registerSlashCommand(id: string, command: SlashCommand): void;
            unregisterSlashCommand(id: string): void;
        };
        state: {
            activePanel: string;
            blockConverters: Record<
                string,
                | undefined
                | Record<
                    string,
                    | undefined
                    | (
                        (
                            blockContent: BlockForConversion,
                            repr: Repr,
                            block?: Block,
                            forExport?: boolean,
                        ) => string | Promise<string>
                    ),
                >,
            >;
            blockMenuCommands: Record<string, undefined | BlockMenuCommand>;
            blockRenderers: Record<string, any>;
            blocks: Record<string | number, undefined | Block>;
            commandPaletteOpened: boolean;
            commands: Record<string, undefined | CommandWithPinyin>;
            dataDir: string;
            filterInTags?: string;
            globalSearchOpened: boolean;
            headbarButtons: Record<string, undefined | (() => ReactElement)>;
            inlineConverters: Record<
                string,
                | undefined
                | Record<string, (content: ContentFragment) => string | Promise<string>>,
            >;
            inlineRenderers: Record<string, any>;
            locale: string;
            notifications: Notification[];
            panelBackHistory: PanelHistory[];
            panelForwardHistory: PanelHistory[];
            panels: RowPanel;
            plugins: Record<string, undefined | Plugin>;
            repo: string;
            repoDir?: string;
            settings: Record<number, any>;
            settingsOpened: boolean;
            shortcuts: Record<string, undefined | string>;
            sidebarTab: string;
            slashCommands: Record<string, undefined | SlashCommandWithPinyin>;
            tagMenuCommands: Record<string, undefined | TagMenuCommand>;
            themeMode: "light" | "dark";
            themes: Record<string, undefined | string>;
            toolbarButtons: Record<
                string,
                undefined
                | ToolbarButton
                | ToolbarButton[],
            >;
        };
        tagMenuCommands: {
            registerTagMenuCommand(id: string, command: TagMenuCommand): void;
            unregisterTagMenuCommand(id: string): void;
        };
        themes: {
            injectCSSResource(url: string, role: string): void;
            register(
                pluginName: string,
                themeName: string,
                themeFileName: string,
            ): void;
            removeCSSResources(role: string): void;
            unregister(themeName: string): void;
        };
        toolbar: {
            registerToolbarButton(
                id: string,
                button: ToolbarButton | ToolbarButton[],
            ): void;
            unregisterToolbarButton(id: string): void;
        };
        invokeBackend(type: string, ...args: any[]): Promise<any>;
    }
    Index

    Properties

    blockMenuCommands: {
        registerBlockMenuCommand(id: string, command: BlockMenuCommand): void;
        unregisterBlockMenuCommand(id: string): void;
    }

    Block menu commands API for adding custom commands to block context menus. This allows plugins to add custom actions that appear when users right-click on blocks' handle.

    Type declaration

    • registerBlockMenuCommand: function
      • Registers a custom command in the block context menu.

        Parameters

        • id: string

          A unique identifier for the command

        • command: BlockMenuCommand

          The command configuration, including whether it works with multiple blocks and a render function that returns a React element

        Returns void

        // Command that works on a single block
        orca.blockMenuCommands.registerBlockMenuCommand("myplugin.exportBlock", {
        worksOnMultipleBlocks: false,
        render: (blockId, rootBlockId, close) => (
        <orca.components.MenuText
        preIcon="ti ti-file-export"
        title="Export as JSON"
        onClick={() => {
        close()
        exportBlockAsJson(blockId)
        }}
        />
        )
        })

        // Command that works on multiple blocks
        orca.blockMenuCommands.registerBlockMenuCommand("myplugin.mergeBlocks", {
        worksOnMultipleBlocks: true,
        render: (blockIds, rootBlockId, close) => (
        <orca.components.MenuText
        preIcon="ti ti-combine"
        title={`Merge ${blockIds.length} Blocks`}
        onClick={() => {
        close()
        mergeSelectedBlocks(blockIds)
        }}
        />
        )
        })
    • unregisterBlockMenuCommand: function
      • Unregisters a previously registered block menu command.

        Parameters

        • id: string

          The identifier of the block menu command to unregister

        Returns void

        // When unloading the plugin
        orca.blockMenuCommands.unregisterBlockMenuCommand("myplugin.exportBlock")
    // Register a command for single block selection
    orca.blockMenuCommands.registerBlockMenuCommand("myplugin.analyzeBlock", {
    worksOnMultipleBlocks: false,
    render: (blockId, rootBlockId, close) => (
    <orca.components.MenuText
    title="Analyze Block"
    onClick={() => {
    close()
    analyzeBlockContent(blockId)
    }}
    />
    )
    })
    broadcasts: {
        broadcast(type: string, ...args: any[]): void;
        isHandlerRegistered(type: string): boolean;
        registerHandler(type: string, handler: CommandFn): void;
        unregisterHandler(type: string, handler: CommandFn): void;
    }

    Broadcasts API, used for application-wide event messaging between different windows of Orca. This is useful for communication between different windows of the same plugin.

    Type declaration

    • broadcast: function
      • Broadcasts an event of a specific type with optional arguments to all registered handlers.

        Parameters

        • type: string

          The broadcast type to emit

        • ...args: any[]

          Any arguments to pass to the handlers

        Returns void

        // Simple notification
        orca.broadcasts.broadcast("myplugin.processCompleted")

        // With data
        orca.broadcasts.broadcast("myplugin.dataFetched", {
        items: dataItems,
        timestamp: Date.now()
        })
    • isHandlerRegistered: function
      • Checks if a handler is registered for a specific broadcast type.

        Parameters

        • type: string

          The broadcast type to check

        Returns boolean

        True if a handler is registered, false otherwise

        if (!orca.broadcasts.isHandlerRegistered("myplugin.dataUpdated")) {
        orca.broadcasts.registerHandler("myplugin.dataUpdated", handleDataUpdate)
        }
    • registerHandler: function
      • Registers a handler function for a specific broadcast type.

        Parameters

        • type: string

          The broadcast type to listen for

        • handler: CommandFn

          The function to execute when the broadcast is received

        Returns void

        orca.broadcasts.registerHandler("core.themeChanged", (theme) => {
        console.log("Theme changed to:", theme)
        updateUIForTheme(theme)
        })
    • unregisterHandler: function
      • Unregisters a previously registered handler for a specific broadcast type.

        Parameters

        • type: string

          The broadcast type of the handler to remove

        • handler: CommandFn

          The handler function to unregister

        Returns void

        // When the component unmounts or plugin unloads
        orca.broadcasts.unregisterHandler("core.themeChanged", handleThemeChange)
    // Register a handler for a specific broadcast type
    orca.broadcasts.registerHandler("myplugin.dataUpdated", (data) => {
    console.log("Data was updated:", data)
    // Update UI or perform other actions
    })

    // Broadcast an event
    orca.broadcasts.broadcast("myplugin.dataUpdated", { key: "value" })
    commands: {
        invokeCommand(id: string, ...args: any[]): Promise<any>;
        invokeEditorCommand(
            id: string,
            cursor: null | CursorData,
            ...args: any[],
        ): Promise<any>;
        invokeGroup(
            callback: () => Promise<void>,
            options?: { topGroup?: boolean; undoable?: boolean },
        ): Promise<void>;
        invokeTopEditorCommand(
            id: string,
            cursor: null | CursorData,
            ...args: any[],
        ): Promise<any>;
        registerAfterCommand(id: string, fn: AfterHook): void;
        registerBeforeCommand(id: string, pred: BeforeHookPred): void;
        registerCommand(id: string, fn: CommandFn, label: string): void;
        registerEditorCommand(
            id: string,
            doFn: EditorCommandFn,
            undoFn: CommandFn,
            opts: { hasArgs?: boolean; label: string; noFocusNeeded?: boolean },
        ): void;
        unregisterAfterCommand(id: string, fn: AfterHook): void;
        unregisterBeforeCommand(id: string, pred: BeforeHookPred): void;
        unregisterCommand(id: string): void;
        unregisterEditorCommand(id: string): void;
    }

    Commands API, used to register, invoke, and manage commands in Orca. Commands are the primary way to add functionality to Orca, and can be bound to shortcuts, toolbar buttons, slash commands, and more.

    Type declaration

    • invokeCommand: function
      • Invokes a command by its ID with optional arguments.

        Parameters

        • id: string

          The identifier of the command to invoke

        • ...args: any[]

          Optional arguments to pass to the command

        Returns Promise<any>

        A Promise that resolves to the result of the command execution

        // Invoke a command without arguments
        await orca.commands.invokeCommand("myplugin.refreshData")

        // Invoke a command with arguments
        const result = await orca.commands.invokeCommand(
        "myplugin.searchDocuments",
        "search query",
        )
    • invokeEditorCommand: function
      • Invokes an editor command by its ID with cursor context and optional arguments.

        Parameters

        • id: string

          The identifier of the editor command to invoke

        • cursor: null | CursorData

          The cursor data context for the command, or null

        • ...args: any[]

          Optional arguments to pass to the command

        Returns Promise<any>

        A Promise that resolves to the result of the command execution

        // Invoke an editor command
        await orca.commands.invokeEditorCommand(
        "core.editor.insertFragments",
        null,
        [{t: "t", v: "Text to insert"}]
        )
    • invokeGroup: function
      • Executes a group of commands as a single undoable operation. This is useful when multiple commands should be treated as a single step in the undo/redo history.

        Parameters

        • callback: () => Promise<void>

          An async function that will perform multiple command operations

        • Optionaloptions: { topGroup?: boolean; undoable?: boolean }

          Optional configuration for the command group

          • OptionaltopGroup?: boolean

            Whether this is a top-level command group not nested in another group (defaults to false)

          • Optionalundoable?: boolean

            Whether the command group should be undoable (defaults to true)

        Returns Promise<void>

        // Group multiple editor commands as one undoable operation
        await orca.commands.invokeGroup(async () => {
        // Create a heading block
        const headingId = await orca.commands.invokeEditorCommand(
        "core.editor.insertBlock",
        null,
        null, // If there is no reference block, this is null
        null, // Since it's null, the position parameter here is also null
        null, // No content
        { type: "heading", level: 1 }, // repr parameter, defines this as a level 1 heading
        )

        // Add a content block under the heading block
        await orca.commands.invokeEditorCommand(
        "core.editor.insertBlock",
        null,
        orca.state.blocks[headingId], // Reference block (heading block)
        "lastChild", // Position: as the last child of the heading block
        [{ t: "t", v: "This is the first paragraph." }], // Content
        { type: "text" } // repr parameter
        )

        // Add another content block
        await orca.commands.invokeEditorCommand(
        "core.editor.insertBlock",
        null,
        orca.state.blocks[headingId], // Reference block (heading block)
        "lastChild", // Position: as the last child of the heading block
        [{ t: "t", v: "This is the second paragraph." }], // Content
        { type: "text" } // repr parameter
        )
        })
    • invokeTopEditorCommand: function
      • Invokes an editor command (as a top command) by its ID with cursor context and optional arguments.

        Parameters

        • id: string

          The identifier of the editor command to invoke

        • cursor: null | CursorData

          The cursor data context for the command, or null

        • ...args: any[]

          Optional arguments to pass to the command

        Returns Promise<any>

        A Promise that resolves to the result of the command execution

        // Invoke an editor command
        await orca.commands.invokeEditorCommand(
        "core.editor.insertFragments",
        null,
        [{t: "t", v: "Text to insert"}]
        )
    • registerAfterCommand: function
      • Registers an "after command" hook to execute code after a command completes.

        Parameters

        • id: string

          The identifier of the command to hook into

        • fn: AfterHook

          The function to execute after the command completes. The first parameter is the command ID, followed by the arguments of the command being monitored.

        Returns void

        // Log when blocks are deleted
        orca.commands.registerAfterCommand(
        "core.editor.deleteBlocks",
        (cmdId, blockIds) => {
        console.log(`Deleted blocks: ${blockIds.join(", ")}`)

        // Update UI or perform additional operations
        updateBlockCountDisplay()
        }
        )
    • registerBeforeCommand: function
      • Registers a "before command" hook to conditionally prevent a command from executing.

        Parameters

        • id: string

          The identifier of the command to hook into

        • pred: BeforeHookPred

          A predicate function that returns true if the command should proceed, false to cancel. The first parameter is the command ID, followed by the arguments of the command being monitored.

        Returns void

        // Prevent deletion of locked blocks
        orca.commands.registerBeforeCommand(
        "core.editor.deleteBlocks",
        (cmdId, blockIds) => {
        // Check if any of the blocks are locked
        const hasLockedBlock = blockIds.some(id => isBlockLocked(id))

        if (hasLockedBlock) {
        orca.notify("error", "Cannot delete locked blocks")
        return false // Prevent the command from executing
        }

        return true // Allow the command to proceed
        }
        )
    • registerCommand: function
      • Registers a new command with Orca.

        Parameters

        • id: string

          A unique identifier for the command

        • fn: CommandFn

          The function to execute when the command is invoked

        • label: string

          A human-readable label for the command

        Returns void

        // Register a simple command
        orca.commands.registerCommand(
        "myplugin.exportAsPDF",
        async () => {
        // Command implementation
        const result = await exportCurrentDocumentAsPDF()
        orca.notify("success", "Document exported as PDF successfully")
        },
        "Export as PDF"
        )
    • registerEditorCommand: function
      • Registers an editor command that can be undone/redone in the editor. Editor commands are automatically added to the undo/redo stack.

        Parameters

        • id: string

          A unique identifier for the command

        • doFn: EditorCommandFn

          The function to execute when the command is invoked

        • undoFn: CommandFn

          The function to execute when the command is undone

        • opts: { hasArgs?: boolean; label: string; noFocusNeeded?: boolean }

          Options for the command including label, whether it has arguments, and if focus is needed

        Returns void

        // Register an editor command to format text
        orca.commands.registerEditorCommand(
        "myplugin.formatSelectedText",
        // Do function
        ([panelId, rootBlockId, cursor]) => {
        // Get the selected text
        const selection = window.getSelection()
        if (!selection || selection.isCollapsed) return null

        // const formattedText = ...

        // Return undo arguments
        return {
        ret: formattedText,
        undoArgs: { text: formattedText }
        }
        },
        // Undo function
        (panelId, { text }) => {
        // ...
        },
        {
        label: "Format Selected Text",
        hasArgs: false
        }
        )
    • unregisterAfterCommand: function
      • Unregisters a previously registered "after command" hook.

        Parameters

        • id: string

          The identifier of the command

        • fn: AfterHook

          The function to unregister

        Returns void

        // When unloading a plugin
        orca.commands.unregisterAfterCommand(
        "core.editor.deleteBlocks",
        myAfterDeleteHook
        )
    • unregisterBeforeCommand: function
      • Unregisters a previously registered "before command" hook.

        Parameters

        • id: string

          The identifier of the command

        • pred: BeforeHookPred

          The predicate function to unregister

        Returns void

        // When unloading a plugin
        orca.commands.unregisterBeforeCommand(
        "core.editor.deleteBlocks",
        myBeforeDeleteHook
        )
    • unregisterCommand: function
      • Unregisters a previously registered command.

        Parameters

        • id: string

          The identifier of the command to unregister

        Returns void

        // When unloading a plugin
        orca.commands.unregisterCommand("myplugin.exportAsPDF")
    • unregisterEditorCommand: function
      • Unregisters a previously registered editor command.

        Parameters

        • id: string

          The identifier of the editor command to unregister

        Returns void

        // When unloading a plugin
        orca.commands.unregisterEditorCommand("myplugin.formatSelectedText")
    // Register a simple command
    orca.commands.registerCommand(
    "myplugin.sayHello",
    (name) => {
    orca.notify("info", `Hello, ${name || "world"}!`)
    },
    "Say Hello"
    )

    // Invoke a command
    await orca.commands.invokeCommand("myplugin.sayHello", "User")
    components: {
        AliasEditor: (
            props: { blockId: number } & Partial<
                {
                    alignment?: "top"
                    | "bottom"
                    | "left"
                    | "right"
                    | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: any;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: any;
                },
            >,
        ) => null
        | Element;
        Block: (
            props: {
                blockId: number;
                blockLevel: number;
                indentLevel: number;
                initiallyCollapsed?: boolean;
                panelId: string;
                renderingMode?: BlockRenderingMode;
                withBreadcrumb?: boolean;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        BlockBreadcrumb: (
            props: { blockId: number; className?: string; style?: CSSProperties },
        ) => null | Element;
        BlockChildren: (
            props: {
                block: Block;
                blockLevel: number;
                indentLevel: number;
                panelId: string;
                renderingMode?: BlockRenderingMode;
            },
        ) => null
        | Element;
        BlockSelect: (
            props: {
                mode: "block" | "ref";
                onChange?: (selected: string[]) => void | Promise<void>;
                scope?: string;
                selected: number[];
            } & Omit<
                SelectProps,
                | "options"
                | "selected"
                | "filter"
                | "filterPlaceholder"
                | "filterFunction"
                | "onChange",
            >,
        ) => null
        | Element;
        BlockShell: (
            props: {
                blockId: number;
                blockLevel: number;
                childrenJsx: ReactNode;
                contentAttrs?: Record<string, any>;
                contentClassName?: string;
                contentJsx: ReactNode;
                contentStyle?: CSSProperties;
                contentTag?: any;
                dropppable?: boolean;
                indentLevel: number;
                initiallyCollapsed?: boolean;
                mirrorId?: number;
                panelId: string;
                renderingMode?: BlockRenderingMode;
                reprAttrs?: Record<string, any>;
                reprClassName: string;
                rndId: string;
                withBreadcrumb?: boolean;
            },
        ) => null
        | Element;
        Breadcrumb: (
            props: {
                className?: string;
                items: ReactNode[];
                style?: CSSProperties;
            },
        ) => null
        | Element;
        Button: (
            props: HTMLAttributes<HTMLButtonElement> & {
                variant: "solid" | "soft" | "dangerous" | "outline" | "plain";
            },
        ) => null
        | Element;
        Checkbox: (
            props: {
                checked?: boolean;
                disabled?: boolean;
                indeterminate?: boolean;
                onChange?: (e: { checked: boolean }) => void | Promise<void>;
            } & Omit<HTMLAttributes<HTMLSpanElement>, "onChange">,
        ) => null | Element;
        CompositionInput: (
            props: HTMLAttributes<HTMLInputElement> & {
                error?: ReactNode;
                post?: ReactElement<any, string | JSXElementConstructor<any>>;
                pre?: ReactElement<any, string | JSXElementConstructor<any>>;
            },
        ) => null
        | Element;
        CompositionTextArea: (
            props: HTMLAttributes<HTMLTextAreaElement>,
        ) => null | Element;
        ConfirmBox: (
            props: {
                children: (
                    openMenu: (e: UIEvent, state?: any) => void,
                    closeMenu: () => void,
                ) => ReactNode;
                onConfirm: (
                    e: UIEvent,
                    close: () => void,
                    state?: any,
                ) => void | Promise<void>;
                text: string;
            } & Partial<
                {
                    alignment?: "top"
                    | "bottom"
                    | "left"
                    | "right"
                    | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: any;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: any;
                },
            >,
        ) => null
        | Element;
        ContextMenu: (
            props: {
                alignment?: "top" | "bottom" | "left" | "right" | "center";
                allowBeyondContainer?: boolean;
                children: (
                    openMenu: (e: UIEvent, state?: any) => void,
                    closeMenu: () => void,
                ) => ReactNode;
                className?: string;
                container?: RefObject<HTMLElement>;
                crossOffset?: number;
                defaultPlacement?: "top" | "bottom" | "left" | "right";
                escapeToClose?: boolean;
                keyboardNav?: boolean;
                menu: (close: () => void, state?: any) => ReactNode;
                menuAttr?: Record<string, any>;
                navDirection?: "vertical" | "both";
                noPointerLogic?: boolean;
                offset?: number;
                onClosed?: () => void;
                onOpened?: () => void;
                placement?: "vertical" | "horizontal";
                style?: CSSProperties;
            },
        ) => null
        | Element;
        DatePicker: (
            props: {
                alignment?: "left" | "right" | "center";
                className?: string;
                menuContainer?: RefObject<HTMLElement>;
                mode?: "date" | "time" | "datetime";
                onChange: (v: Date | [Date, Date]) => void | Promise<void>;
                onClose?: () => void | Promise<void>;
                onClosed?: () => void | Promise<void>;
                range?: boolean;
                rect?: DOMRect;
                refElement?: RefObject<HTMLElement>;
                style?: CSSProperties;
                value: Date | [Date, Date];
                visible?: boolean;
            },
        ) => null
        | Element;
        HoverContextMenu: (
            props: { children: ReactElement } & Omit<ContextMenuProps, "children">,
        ) => null | Element;
        Image: (props: HTMLAttributes<HTMLImageElement>) => null | Element;
        Input: (
            props: HTMLAttributes<HTMLInputElement> & {
                error?: ReactNode;
                post?: ReactElement<any, string | JSXElementConstructor<any>>;
                pre?: ReactElement<any, string | JSXElementConstructor<any>>;
            },
        ) => null
        | Element;
        InputBox: (
            props: {
                children: (
                    openMenu: (e: UIEvent, state?: any) => void,
                    closeMenu: () => void,
                ) => ReactNode;
                defaultValue?: string;
                error?: ReactNode;
                label: string;
                onConfirm: (
                    value: undefined | string,
                    e: UIEvent,
                    close: () => void,
                ) => void | Promise<void>;
            } & Partial<
                {
                    alignment?: "top"
                    | "bottom"
                    | "left"
                    | "right"
                    | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: any;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: any;
                },
            >,
        ) => null
        | Element;
        LoadMore: (
            props: {
                debounceTime?: number;
                message?: string;
                onLoadMore: () => void | Promise<void>;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        MemoizedViews: (
            props: {
                active: string;
                className?: string;
                name: string;
                orientation?: "vertical" | "horizontal";
                style?: CSSProperties;
                views: {
                    [key: string]:
                        | null
                        | ReactElement<any, string | JSXElementConstructor<any>>;
                };
            },
        ) => null
        | Element;
        Menu: (
            props: {
                children?: ReactNode;
                container?: RefObject<HTMLElement>;
                keyboardNav?: boolean;
                navDirection?: "vertical" | "both";
                onKeyboardNav?: (el: HTMLElement) => void | Promise<void>;
                refocus?: boolean;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        MenuItem: (
            props: {
                children?: ReactElement<any, string | JSXElementConstructor<any>>;
                className?: string;
                jsx: ReactElement;
                onClick?: (e: MouseEvent) => void | Promise<void>;
                style?: CSSProperties;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        MenuSeparator: (props: {}) => null | Element;
        MenuText: (
            props: {
                centered?: boolean;
                children?: ReactElement<any, string | JSXElementConstructor<any>>;
                className?: string;
                contextMenu?: (close: () => void) => ReactNode;
                dangerous?: boolean;
                disabled?: boolean;
                onClick?: (e: MouseEvent) => void | Promise<void>;
                postIcon?: string;
                preIcon?: string;
                raw?: boolean;
                shortcut?: string;
                style?: CSSProperties;
                subtitle?: string;
                title: string;
            } & Omit<HTMLAttributes<HTMLDivElement>, "contextMenu">,
        ) => null | Element;
        MenuTitle: (
            props: {
                className?: string;
                info?: ReactNode;
                style?: CSSProperties;
                title: string;
            },
        ) => null
        | Element;
        ModalOverlay: (
            props: {
                blurred?: boolean;
                canClose?: boolean;
                children: ReactNode;
                className?: string;
                onClose?: () => void | Promise<void>;
                onClosed?: () => void;
                style?: CSSProperties;
                visible: boolean;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        Popup: (
            props: {
                alignment?: "top" | "bottom" | "left" | "right" | "center";
                allowBeyondContainer?: boolean;
                boundary?: RefObject<HTMLElement>;
                children?: ReactElement<any, string | JSXElementConstructor<any>>;
                className?: string;
                container?: RefObject<HTMLElement>;
                crossOffset?: number;
                defaultPlacement?: "top" | "bottom" | "left" | "right";
                escapeToClose?: boolean;
                noPointerLogic?: boolean;
                offset?: number;
                onClose?: () => void | Promise<void>;
                onClosed?: () => void;
                placement?: "vertical" | "horizontal";
                rect?: DOMRect;
                refElement?: RefObject<HTMLElement>;
                visible: boolean;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        Segmented: (
            props: {
                className?: string;
                onChange: (value: string) => void | Promise<void>;
                options: {
                    jsx?: ReactElement<any, string | JSXElementConstructor<any>>;
                    label?: string;
                    value: string;
                }[];
                selected: string;
                style?: CSSProperties;
            } & Omit<HTMLAttributes<HTMLDivElement>, "onChange">,
        ) => null | Element;
        Select: (
            props: {
                alignment?: "left" | "right" | "center";
                buttonClassName?: string;
                disabled?: boolean;
                filter?: boolean;
                filterFunction?: (
                    keyword: string,
                ) => Promise<{ group?: string; label: string; value: string }[]>;
                filterPlaceholder?: string;
                menuClassName?: string;
                menuContainer?: RefObject<HTMLElement>;
                multiSelection?: boolean;
                onChange?: (
                    selected: string[],
                    filterKeyword?: string,
                ) => void | Promise<void>;
                onMouseEnter?: (e: MouseEvent) => void;
                onMouseLeave?: (e: MouseEvent) => void;
                options: { group?: string; label: string; value: string }[];
                placeholder?: string;
                pre?: ReactElement<any, string | JSXElementConstructor<any>>;
                readOnly?: boolean;
                selected: string[];
                width?: string | number;
                withClear?: boolean;
            },
        ) => null
        | Element;
        Skeleton: (props: {}) => null | Element;
        Switch: (
            props: {
                on?: boolean;
                onChange?: (on: boolean) => void | Promise<void>;
                readonly?: boolean;
                unset?: boolean;
            } & Omit<HTMLAttributes<HTMLButtonElement>, "onChange">,
        ) => null | Element;
        Table: (
            props: {
                columns: { icon?: string; name: string }[];
                initialColumnSizes: string;
                items: { _type: string; [key: string]: any }[];
                onColumnResize?: (value: string) => void | Promise<void>;
                pinColumn?: boolean;
                rowRenderer: (
                    item: { _type: string; [key: string]: any },
                    className: string,
                    index: number,
                ) => ReactNode;
            } & HTMLAttributes<HTMLDivElement>,
        ) => null | Element;
        TagPopup: (
            props: {
                blockId: number;
                children: (
                    openMenu: (e: UIEvent, state?: any) => void,
                    closeMenu: () => void,
                ) => ReactNode;
                closeMenu: () => void;
                onTagClick: (alias: string) => void | Promise<void>;
                placeholder?: string;
            } & Partial<
                {
                    alignment?: "top"
                    | "bottom"
                    | "left"
                    | "right"
                    | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: any;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: any;
                },
            >,
        ) => null
        | Element;
        TagPropsEditor: (
            props: {
                blockId: number;
                children: (
                    openMenu: (e: UIEvent, state?: any) => void,
                    closeMenu: () => void,
                ) => ReactNode;
            } & Partial<
                {
                    alignment?: "top"
                    | "bottom"
                    | "left"
                    | "right"
                    | "center";
                    allowBeyondContainer?: boolean;
                    children: (
                        openMenu: (e: UIEvent, state?: any) => void,
                        closeMenu: () => void,
                    ) => ReactNode;
                    className?: string;
                    container?: any;
                    crossOffset?: number;
                    defaultPlacement?: "top" | "bottom" | "left" | "right";
                    escapeToClose?: boolean;
                    keyboardNav?: boolean;
                    menu: (close: () => void, state?: any) => ReactNode;
                    menuAttr?: Record<string, any>;
                    navDirection?: "vertical" | "both";
                    noPointerLogic?: boolean;
                    offset?: number;
                    onClosed?: () => void;
                    onOpened?: () => void;
                    placement?: "vertical" | "horizontal";
                    style?: any;
                },
            >,
        ) => null
        | Element;
        Tooltip: (
            props: {
                alignment?: "top" | "bottom" | "left" | "right" | "center";
                allowBeyondContainer?: boolean;
                children: ReactElement;
                defaultPlacement?: "top" | "bottom" | "left" | "right";
                delay?: number;
                image?: string;
                modifier?: "shift" | "ctrl" | "alt" | "meta";
                placement?: "vertical" | "horizontal";
                shortcut?: string;
                text: ReactNode;
                [key: string]: any;
            },
        ) => null
        | Element;
    }

    Pre-built UI components from Orca that can be used in plugin development. These components follow Orca's design system and provide consistent UI patterns.

    Type declaration

    • AliasEditor: (
          props: { blockId: number } & Partial<
              {
                  alignment?: "top"
                  | "bottom"
                  | "left"
                  | "right"
                  | "center";
                  allowBeyondContainer?: boolean;
                  children: (
                      openMenu: (e: UIEvent, state?: any) => void,
                      closeMenu: () => void,
                  ) => ReactNode;
                  className?: string;
                  container?: any;
                  crossOffset?: number;
                  defaultPlacement?: "top" | "bottom" | "left" | "right";
                  escapeToClose?: boolean;
                  keyboardNav?: boolean;
                  menu: (close: () => void, state?: any) => ReactNode;
                  menuAttr?: Record<string, any>;
                  navDirection?: "vertical" | "both";
                  noPointerLogic?: boolean;
                  offset?: number;
                  onClosed?: () => void;
                  onOpened?: () => void;
                  placement?: "vertical" | "horizontal";
                  style?: any;
              },
          >,
      ) => null
      | Element

      Provides an editor interface for managing aliases/tags, including adding/removing aliases, formatting options, template selection, and inclusion relationships.

      // Edit aliases for a block
      <orca.components.AliasEditor
      blockId={123}
      >
      {(open) => (
      <orca.components.Button variant="outline" onClick={open}>
      Edit Alias
      </orca.components.Button>
      )}
      </orca.components.AliasEditor>

      // With custom container
      <orca.components.AliasEditor
      blockId={456}
      container={containerRef}
      >
      {(open) => (
      <span onClick={open}>Configure Tag Settings</span>
      )}
      </orca.components.AliasEditor>
    • Block: (
          props: {
              blockId: number;
              blockLevel: number;
              indentLevel: number;
              initiallyCollapsed?: boolean;
              panelId: string;
              renderingMode?: BlockRenderingMode;
              withBreadcrumb?: boolean;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Renders a block with all its content and children

      // Render a regular block
      <orca.components.Block
      panelId="main-panel"
      blockId={123}
      blockLevel={0}
      indentLevel={0}
      />

      // Read-only block with breadcrumb
      <orca.components.Block
      panelId="panel-1"
      blockId={456}
      blockLevel={1}
      indentLevel={2}
      withBreadcrumb
      renderingMode="readonly"
      />
    • BlockBreadcrumb: (
          props: { blockId: number; className?: string; style?: CSSProperties },
      ) => null | Element

      Renders a breadcrumb trail for a block's ancestors

      // Basic usage
      <orca.components.BlockBreadcrumb blockId={123} />

      // With custom styles
      <orca.components.BlockBreadcrumb
      blockId={456}
      className="custom-breadcrumb"
      style={{ marginBottom: '10px' }}
      />
    • BlockChildren: (
          props: {
              block: Block;
              blockLevel: number;
              indentLevel: number;
              panelId: string;
              renderingMode?: BlockRenderingMode;
          },
      ) => null
      | Element

      Renders a block's children

      // Standard usage
      <orca.components.BlockChildren
      block={blockObject}
      panelId="main-panel"
      blockLevel={1}
      indentLevel={1}
      />

      // Using simplified rendering mode
      <orca.components.BlockChildren
      block={blockObject}
      panelId="panel-2"
      blockLevel={2}
      indentLevel={3}
      renderingMode="simple"
      />
    • BlockSelect: (
          props: {
              mode: "block" | "ref";
              onChange?: (selected: string[]) => void | Promise<void>;
              scope?: string;
              selected: number[];
          } & Omit<
              SelectProps,
              | "options"
              | "selected"
              | "filter"
              | "filterPlaceholder"
              | "filterFunction"
              | "onChange",
          >,
      ) => null
      | Element

      Provides block selection functionality

      // Block selection
      <orca.components.BlockSelect
      mode="block"
      selected={[123, 456]}
      onChange={async (selected) => {
      console.log("Selected blocks:", selected);
      }}
      />

      // Reference selection with scope restriction
      <orca.components.BlockSelect
      mode="ref"
      scope="project-blocks"
      selected={[789]}
      onChange={handleSelectionChange}
      />
    • BlockShell: (
          props: {
              blockId: number;
              blockLevel: number;
              childrenJsx: ReactNode;
              contentAttrs?: Record<string, any>;
              contentClassName?: string;
              contentJsx: ReactNode;
              contentStyle?: CSSProperties;
              contentTag?: any;
              dropppable?: boolean;
              indentLevel: number;
              initiallyCollapsed?: boolean;
              mirrorId?: number;
              panelId: string;
              renderingMode?: BlockRenderingMode;
              reprAttrs?: Record<string, any>;
              reprClassName: string;
              rndId: string;
              withBreadcrumb?: boolean;
          },
      ) => null
      | Element

      Core component for block rendering with common UI elements

      // Basic text block
      <orca.components.BlockShell
      panelId="main-panel"
      blockId={123}
      rndId="unique-rand-id"
      blockLevel={0}
      indentLevel={0}
      reprClassName="orca-repr-text"
      contentJsx={<div>This is text content</div>}
      childrenJsx={<ChildrenComponent />}
      />

      // Code block example
      <orca.components.BlockShell
      panelId="code-panel"
      blockId={456}
      rndId="code-rand-id"
      blockLevel={1}
      indentLevel={2}
      withBreadcrumb={true}
      reprClassName="orca-repr-code"
      contentClassName="orca-repr-code-content"
      contentAttrs={{ contentEditable: false }}
      contentJsx={<CodeEditor />}
      childrenJsx={childrenBlocks}
      />
    • Breadcrumb: (
          props: { className?: string; items: ReactNode[]; style?: CSSProperties },
      ) => null | Element

      Renders a generic breadcrumb navigation

      // Simple breadcrumb
      <orca.components.Breadcrumb
      items={["Home", "Projects", "Document"]}
      />

      // Breadcrumb with links and icons
      <orca.components.Breadcrumb
      items={[
      <a href="#home">Home <i className="ti ti-home" /></a>,
      <a href="#projects">Projects</a>,
      "Current Document"
      ]}
      className="custom-breadcrumb"
      />
    • Button: (
          props: HTMLAttributes<HTMLButtonElement> & {
              variant: "solid" | "soft" | "dangerous" | "outline" | "plain";
          },
      ) => null
      | Element

      Standard button component with multiple variants

      // Basic button
      <orca.components.Button variant="solid" onClick={handleClick}>
      Save
      </orca.components.Button>

      // Dangerous action button
      <orca.components.Button variant="dangerous" onClick={handleDelete}>
      <i className="ti ti-trash" /> Delete
      </orca.components.Button>

      // Outline button with disabled state
      <orca.components.Button variant="outline" disabled={true}>
      Edit
      </orca.components.Button>

      // Simple icon button
      <orca.components.Button variant="plain" onClick={handleRefresh}>
      <i className="ti ti-refresh" />
      </orca.components.Button>
    • Checkbox: (
          props: {
              checked?: boolean;
              disabled?: boolean;
              indeterminate?: boolean;
              onChange?: (e: { checked: boolean }) => void | Promise<void>;
          } & Omit<HTMLAttributes<HTMLSpanElement>, "onChange">,
      ) => null | Element

      Checkbox form element

      // Basic checkbox
      <orca.components.Checkbox
      checked={isChecked}
      onChange={({ checked }) => setIsChecked(checked)}
      />

      // Disabled checkbox
      <orca.components.Checkbox checked={true} disabled={true} />

      // Indeterminate state checkbox
      <orca.components.Checkbox
      indeterminate={true}
      onChange={handleSelectionChange}
      />
    • CompositionInput: (
          props: HTMLAttributes<HTMLInputElement> & {
              error?: ReactNode;
              post?: ReactElement<any, string | JSXElementConstructor<any>>;
              pre?: ReactElement<any, string | JSXElementConstructor<any>>;
          },
      ) => null
      | Element

      Input that handles IME composition events properly

      // Basic input
      <orca.components.CompositionInput
      placeholder="Enter text"
      value={inputValue}
      onChange={(e) => setInputValue(e.target.value)}
      />

      // Input with prefix and suffix
      <orca.components.CompositionInput
      pre={<i className="ti ti-search" />}
      post={<Button onClick={clearInput}>Clear</Button>}
      placeholder="Search..."
      />

      // Input with validation error
      <orca.components.CompositionInput
      value={email}
      onChange={handleEmailChange}
      error={emailError ? <span className="error">{emailError}</span> : null}
      />
    • CompositionTextArea: (props: HTMLAttributes<HTMLTextAreaElement>) => null | Element

      Textarea that handles IME composition events properly

      // Basic multiline text input
      <orca.components.CompositionTextArea
      placeholder="Enter multiline text"
      value={textValue}
      onChange={(e) => setTextValue(e.target.value)}
      />

      // Set rows and auto-grow
      <orca.components.CompositionTextArea
      rows={5}
      style={{ minHeight: '100px' }}
      placeholder="Enter notes..."
      />
    • ConfirmBox: (
          props: {
              children: (
                  openMenu: (e: UIEvent, state?: any) => void,
                  closeMenu: () => void,
              ) => ReactNode;
              onConfirm: (
                  e: UIEvent,
                  close: () => void,
                  state?: any,
              ) => void | Promise<void>;
              text: string;
          } & Partial<
              {
                  alignment?: "top"
                  | "bottom"
                  | "left"
                  | "right"
                  | "center";
                  allowBeyondContainer?: boolean;
                  children: (
                      openMenu: (e: UIEvent, state?: any) => void,
                      closeMenu: () => void,
                  ) => ReactNode;
                  className?: string;
                  container?: any;
                  crossOffset?: number;
                  defaultPlacement?: "top" | "bottom" | "left" | "right";
                  escapeToClose?: boolean;
                  keyboardNav?: boolean;
                  menu: (close: () => void, state?: any) => ReactNode;
                  menuAttr?: Record<string, any>;
                  navDirection?: "vertical" | "both";
                  noPointerLogic?: boolean;
                  offset?: number;
                  onClosed?: () => void;
                  onOpened?: () => void;
                  placement?: "vertical" | "horizontal";
                  style?: any;
              },
          >,
      ) => null
      | Element

      Displays a confirmation dialog

      // Basic confirmation dialog
      <orca.components.ConfirmBox
      text="Are you sure you want to delete this item?"
      onConfirm={(e, close) => {
      deleteItem();
      close();
      }}
      >
      {(open, close) => (
      <orca.components.Button variant="dangerous" onClick={open}>
      Delete
      </orca.components.Button>
      )}
      </orca.components.ConfirmBox>

      // Confirmation dialog with state
      <orca.components.ConfirmBox
      text="Are you sure you want to move this block?"
      onConfirm={(e, close, state) => {
      moveBlock(state.blockId, state.destination);
      close();
      }}
      >
      {(open) => (
      <orca.components.Button
      variant="soft"
      onClick={(e) => open(e, { blockId: 123, destination: 'section-1' })}
      >
      Move
      </orca.components.Button>
      )}
      </orca.components.ConfirmBox>
    • ContextMenu: (
          props: {
              alignment?: "top" | "bottom" | "left" | "right" | "center";
              allowBeyondContainer?: boolean;
              children: (
                  openMenu: (e: UIEvent, state?: any) => void,
                  closeMenu: () => void,
              ) => ReactNode;
              className?: string;
              container?: RefObject<HTMLElement>;
              crossOffset?: number;
              defaultPlacement?: "top" | "bottom" | "left" | "right";
              escapeToClose?: boolean;
              keyboardNav?: boolean;
              menu: (close: () => void, state?: any) => ReactNode;
              menuAttr?: Record<string, any>;
              navDirection?: "vertical" | "both";
              noPointerLogic?: boolean;
              offset?: number;
              onClosed?: () => void;
              onOpened?: () => void;
              placement?: "vertical" | "horizontal";
              style?: CSSProperties;
          },
      ) => null
      | Element

      Creates a context menu attached to an element

      // Basic context menu
      <orca.components.ContextMenu
      menu={(close) => (
      <orca.components.Menu>
      <orca.components.MenuText
      title="Edit"
      onClick={() => { editItem(); close(); }}
      />
      <orca.components.MenuText
      title="Delete"
      dangerous={true}
      onClick={() => { deleteItem(); close(); }}
      />
      </orca.components.Menu>
      )}
      >
      {(open) => (
      <div onContextMenu={open}>Right-click here to show the menu</div>
      )}
      </orca.components.ContextMenu>

      // Custom position and alignment menu
      <orca.components.ContextMenu
      placement="horizontal"
      alignment="top"
      defaultPlacement="right"
      menu={(close) => (
      <orca.components.Menu>
      <orca.components.MenuText title="Option 1" onClick={close} />
      <orca.components.MenuText title="Option 2" onClick={close} />
      </orca.components.Menu>
      )}
      >
      {(open) => (
      <orca.components.Button variant="soft" onClick={open}>
      Show Menu
      </orca.components.Button>
      )}
      </orca.components.ContextMenu>
    • DatePicker: (
          props: {
              alignment?: "left" | "right" | "center";
              className?: string;
              menuContainer?: RefObject<HTMLElement>;
              mode?: "date" | "time" | "datetime";
              onChange: (v: Date | [Date, Date]) => void | Promise<void>;
              onClose?: () => void | Promise<void>;
              onClosed?: () => void | Promise<void>;
              range?: boolean;
              rect?: DOMRect;
              refElement?: RefObject<HTMLElement>;
              style?: CSSProperties;
              value: Date | [Date, Date];
              visible?: boolean;
          },
      ) => null
      | Element

      Calendar date picker

      // Basic date picker
      const [date, setDate] = useState(new Date());
      <orca.components.DatePicker
      value={date}
      onChange={(newDate) => setDate(newDate)}
      />

      // Date-time picker
      <orca.components.DatePicker
      mode="datetime"
      value={dateTime}
      onChange={handleDateTimeChange}
      />

      // Date range picker
      const [dateRange, setDateRange] = useState([new Date(), new Date(Date.now() + 86400000)]);
      <orca.components.DatePicker
      range={true}
      value={dateRange}
      onChange={(newRange) => setDateRange(newRange)}
      />
    • HoverContextMenu: (
          props: { children: ReactElement } & Omit<ContextMenuProps, "children">,
      ) => null | Element

      Context menu that appears on hover

      // Basic hover menu
      <orca.components.HoverContextMenu
      menu={(close) => (
      <orca.components.Menu>
      <orca.components.MenuText
      title="View"
      preIcon="ti ti-eye"
      onClick={close}
      />
      <orca.components.MenuText
      title="Edit"
      preIcon="ti ti-pencil"
      onClick={close}
      />
      </orca.components.Menu>
      )}
      >
      <div className="hoverable-element">Hover to show menu</div>
      </orca.components.HoverContextMenu>

      // Custom positioned hover menu
      <orca.components.HoverContextMenu
      placement="horizontal"
      defaultPlacement="right"
      menu={(close) => (
      <orca.components.Menu>
      <orca.components.MenuText
      title="View Details"
      preIcon="ti ti-info-circle"
      onClick={() => { viewDetails(); close(); }}
      />
      </orca.components.Menu>
      )}
      >
      <i className="ti ti-info" />
      </orca.components.HoverContextMenu>
    • Image: (props: HTMLAttributes<HTMLImageElement>) => null | Element

      Image component with loading states

      // Basic image
      <orca.components.Image
      src="/path/to/image.jpg"
      alt="Description"
      />

      // Styled image
      <orca.components.Image
      src="/path/to/image.png"
      alt="Logo"
      className="profile-image"
      style={{ width: 100, height: 100, borderRadius: '50%' }}
      />

      // Handle loading events
      <orca.components.Image
      src="/path/to/large-image.jpg"
      alt="Large Image"
      onLoad={() => setImageLoaded(true)}
      onError={() => handleImageError()}
      />
    • Input: (
          props: HTMLAttributes<HTMLInputElement> & {
              error?: ReactNode;
              post?: ReactElement<any, string | JSXElementConstructor<any>>;
              pre?: ReactElement<any, string | JSXElementConstructor<any>>;
          },
      ) => null
      | Element

      Standard text input component

      // Basic input field
      <orca.components.Input
      placeholder="Enter text"
      value={inputValue}
      onChange={(e) => setInputValue(e.target.value)}
      />

      // Input field with prefix and suffix
      <orca.components.Input
      pre={<i className="ti ti-user" />}
      post={<orca.components.Button variant="plain">Clear</orca.components.Button>}
      placeholder="Username"
      />

      // Input field with error message
      <orca.components.Input
      value={email}
      onChange={handleEmailChange}
      error={emailError ? "Please enter a valid email address" : undefined}
      />
    • InputBox: (
          props: {
              children: (
                  openMenu: (e: UIEvent, state?: any) => void,
                  closeMenu: () => void,
              ) => ReactNode;
              defaultValue?: string;
              error?: ReactNode;
              label: string;
              onConfirm: (
                  value: undefined | string,
                  e: UIEvent,
                  close: () => void,
              ) => void | Promise<void>;
          } & Partial<
              {
                  alignment?: "top"
                  | "bottom"
                  | "left"
                  | "right"
                  | "center";
                  allowBeyondContainer?: boolean;
                  children: (
                      openMenu: (e: UIEvent, state?: any) => void,
                      closeMenu: () => void,
                  ) => ReactNode;
                  className?: string;
                  container?: any;
                  crossOffset?: number;
                  defaultPlacement?: "top" | "bottom" | "left" | "right";
                  escapeToClose?: boolean;
                  keyboardNav?: boolean;
                  menu: (close: () => void, state?: any) => ReactNode;
                  menuAttr?: Record<string, any>;
                  navDirection?: "vertical" | "both";
                  noPointerLogic?: boolean;
                  offset?: number;
                  onClosed?: () => void;
                  onOpened?: () => void;
                  placement?: "vertical" | "horizontal";
                  style?: any;
              },
          >,
      ) => null
      | Element

      Input dialog with label and actions

      // Basic input dialog
      <orca.components.InputBox
      label="Enter name"
      defaultValue="Default value"
      onConfirm={(value, e, close) => {
      if (value) {
      saveName(value);
      close();
      }
      }}
      >
      {(open) => (
      <orca.components.Button variant="soft" onClick={open}>
      Edit Name
      </orca.components.Button>
      )}
      </orca.components.InputBox>

      // Input dialog with validation
      <orca.components.InputBox
      label="Enter URL"
      error={urlError}
      onConfirm={(url, e, close) => {
      if (isValidUrl(url)) {
      addUrl(url);
      close();
      } else {
      setUrlError("Please enter a valid URL");
      }
      }}
      >
      {(open) => (
      <orca.components.Button variant="outline" onClick={open}>
      Add Link
      </orca.components.Button>
      )}
      </orca.components.InputBox>
    • LoadMore: (
          props: {
              debounceTime?: number;
              message?: string;
              onLoadMore: () => void | Promise<void>;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Component for loading more items in paginated lists

      // Basic Load More component
      <orca.components.LoadMore
      onLoadMore={async () => {
      await fetchMoreItems();
      }}
      />

      // Custom message and debounce time
      <orca.components.LoadMore
      message="Loading more results..."
      debounceTime={500}
      onLoadMore={loadMoreResults}
      className="custom-load-more"
      />
    • MemoizedViews: (
          props: {
              active: string;
              className?: string;
              name: string;
              orientation?: "vertical" | "horizontal";
              style?: CSSProperties;
              views: {
                  [key: string]:
                      | null
                      | ReactElement<any, string | JSXElementConstructor<any>>;
              };
          },
      ) => null
      | Element

      Efficient view container for switching between components

      // Basic view switching container
      <orca.components.MemoizedViews
      name="main-views"
      active="details"
      views={{
      "list": <ListView items={items} />,
      "details": <DetailsView itemId={123} />,
      "settings": <SettingsView />
      }}
      />

      // Horizontally arranged views
      <orca.components.MemoizedViews
      name="side-views"
      active={currentTab}
      orientation="horizontal"
      className="side-panel"
      views={{
      "info": <InfoPanel />,
      "history": <HistoryPanel />,
      "comments": <CommentsPanel />
      }}
      />
    • Menu: (
          props: {
              children?: ReactNode;
              container?: RefObject<HTMLElement>;
              keyboardNav?: boolean;
              navDirection?: "vertical" | "both";
              onKeyboardNav?: (el: HTMLElement) => void | Promise<void>;
              refocus?: boolean;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Standard menu container

      // Basic menu
      <orca.components.Menu>
      <orca.components.MenuText title="Option 1" onClick={() => handleOption(1)} />
      <orca.components.MenuText title="Option 2" onClick={() => handleOption(2)} />
      <orca.components.MenuSeparator />
      <orca.components.MenuText
      title="Exit"
      dangerous={true}
      onClick={() => handleExit(0)}
      />
      </orca.components.Menu>

      // Menu with keyboard navigation enabled
      <orca.components.Menu
      keyboardNav={true}
      navDirection="both"
      onKeyboardNav={(el) => scrollToElement(el)}
      className="keyboard-nav-menu"
      >
      <orca.components.MenuTitle title="Actions" />
      <orca.components.MenuText title="Edit" onClick={() => handleEdit(123)} />
      <orca.components.MenuText title="Copy" onClick={() => handleCopy(456)} />
      <orca.components.MenuText title="Delete" onClick={() => handleDelete(789)} />
      </orca.components.Menu>
    • MenuItem: (
          props: {
              children?: ReactElement<any, string | JSXElementConstructor<any>>;
              className?: string;
              jsx: ReactElement;
              onClick?: (e: MouseEvent) => void | Promise<void>;
              style?: CSSProperties;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Menu item component

      // Basic menu item
      <orca.components.MenuItem
      jsx={<div>Option 1</div>}
      onClick={() => handleOption(1)}
      />

      // Menu item with nested content
      <orca.components.MenuItem
      jsx={<div className="menu-item-header">Display Settings</div>}
      onClick={() => handleSettingsClick(123)}
      >
      <div className="submenu">
      <div>Theme: {currentTheme}</div>
      <div>Font Size: {fontSize}</div>
      </div>
      </orca.components.MenuItem>

      // Menu item with custom styles
      <orca.components.MenuItem
      jsx={<div className="icon-item"><i className="ti ti-user"/> User</div>}
      className="highlighted-item"
      style={{ fontWeight: 'bold' }}
      onClick={() => handleUserClick(456)}
      />
    • MenuSeparator: (props: {}) => null | Element

      Visual separator for menus

      // Add a separator between menu items
      <orca.components.Menu>
      <orca.components.MenuText title="Edit" onClick={() => handleEdit(123)} />
      <orca.components.MenuText title="Copy" onClick={() => handleCopy(456)} />
      <orca.components.MenuSeparator />
      <orca.components.MenuText
      title="Delete"
      dangerous={true}
      onClick={() => handleDelete(789)}
      />
      </orca.components.Menu>
    • MenuText: (
          props: {
              centered?: boolean;
              children?: ReactElement<any, string | JSXElementConstructor<any>>;
              className?: string;
              contextMenu?: (close: () => void) => ReactNode;
              dangerous?: boolean;
              disabled?: boolean;
              onClick?: (e: MouseEvent) => void | Promise<void>;
              postIcon?: string;
              preIcon?: string;
              raw?: boolean;
              shortcut?: string;
              style?: CSSProperties;
              subtitle?: string;
              title: string;
          } & Omit<HTMLAttributes<HTMLDivElement>, "contextMenu">,
      ) => null | Element

      Text-based menu item

      // Basic text menu item
      <orca.components.MenuText
      title="Save Document"
      onClick={handleSave}
      />

      // Menu item with icon and shortcut
      <orca.components.MenuText
      title="Copy"
      preIcon="ti ti-copy"
      shortcut="⌘C"
      onClick={handleCopy}
      />

      // Menu item with subtitle
      <orca.components.MenuText
      title="Export as PDF"
      subtitle="Export the current document as a PDF file"
      preIcon="ti ti-file-export"
      onClick={handleExport}
      />

      // Disabled menu item
      <orca.components.MenuText
      title="Delete"
      preIcon="ti ti-trash"
      dangerous={true}
      disabled={!hasSelection}
      onClick={handleDelete}
      />

      // Menu item with context menu
      <orca.components.MenuText
      title="Share"
      preIcon="ti ti-share"
      contextMenu={(close) => (
      <orca.components.Menu>
      <orca.components.MenuText title="Copy Link" onClick={() => { copyLink(); close(); }} />
      <orca.components.MenuText title="Send Email" onClick={() => { sendEmail(); close(); }} />
      </orca.components.Menu>
      )}
      />
    • MenuTitle: (
          props: {
              className?: string;
              info?: ReactNode;
              style?: CSSProperties;
              title: string;
          },
      ) => null
      | Element

      Menu section title

      // Basic menu title
      <orca.components.Menu>
      <orca.components.MenuTitle title="File Operations" />
      <orca.components.MenuText title="New" onClick={handleNew} />
      <orca.components.MenuText title="Open" onClick={handleOpen} />
      <orca.components.MenuSeparator />
      <orca.components.MenuTitle title="Edit Operations" />
      <orca.components.MenuText title="Copy" onClick={handleCopy} />
      <orca.components.MenuText title="Paste" onClick={handlePaste} />
      </orca.components.Menu>

      // Menu title with additional info
      <orca.components.Menu>
      <orca.components.MenuTitle
      title="Recent Documents"
      info={<span className="count">{recentDocs.length}</span>}
      />
      {recentDocs.map(doc => (
      <orca.components.MenuText
      key={doc.id}
      title={doc.name}
      onClick={() => openDoc(doc.id)}
      />
      ))}
      </orca.components.Menu>
    • ModalOverlay: (
          props: {
              blurred?: boolean;
              canClose?: boolean;
              children: ReactNode;
              className?: string;
              onClose?: () => void | Promise<void>;
              onClosed?: () => void;
              style?: CSSProperties;
              visible: boolean;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Full-screen modal overlay

      // Basic modal
      const [isVisible, setIsVisible] = useState(false);
      <orca.components.Button onClick={() => setIsVisible(true)}>
      Open Modal
      </orca.components.Button>

      <orca.components.ModalOverlay
      visible={isVisible}
      canClose={true}
      onClose={() => setIsVisible(false)}
      >
      <div className="modal-content">
      <h2>Modal Title</h2>
      <p>This is the content of the modal...</p>
      <orca.components.Button onClick={() => setIsVisible(false)}>
      Close
      </orca.components.Button>
      </div>
      </orca.components.ModalOverlay>

      // Modal with blur effect
      <orca.components.ModalOverlay
      visible={isImportant}
      blurred={true}
      canClose={false}
      className="important-modal"
      >
      <div className="confirmation-dialog">
      <h3>Important Action Confirmation</h3>
      <p>Are you sure you want to proceed? This action cannot be undone.</p>
      <div className="actions">
      <orca.components.Button variant="outline" onClick={handleCancel}>
      Cancel
      </orca.components.Button>
      <orca.components.Button variant="dangerous" onClick={handleConfirm}>
      Confirm
      </orca.components.Button>
      </div>
      </div>
      </orca.components.ModalOverlay>
    • Popup: (
          props: {
              alignment?: "top" | "bottom" | "left" | "right" | "center";
              allowBeyondContainer?: boolean;
              boundary?: RefObject<HTMLElement>;
              children?: ReactElement<any, string | JSXElementConstructor<any>>;
              className?: string;
              container?: RefObject<HTMLElement>;
              crossOffset?: number;
              defaultPlacement?: "top" | "bottom" | "left" | "right";
              escapeToClose?: boolean;
              noPointerLogic?: boolean;
              offset?: number;
              onClose?: () => void | Promise<void>;
              onClosed?: () => void;
              placement?: "vertical" | "horizontal";
              rect?: DOMRect;
              refElement?: RefObject<HTMLElement>;
              visible: boolean;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Popup panel attached to an element

      // Basic popup panel
      const [isVisible, setIsVisible] = useState(false);
      const buttonRef = useRef(null);

      <orca.components.Button
      ref={buttonRef}
      onClick={() => setIsVisible(true)}
      >
      Show Popup
      </orca.components.Button>

      <orca.components.Popup
      refElement={buttonRef}
      visible={isVisible}
      onClose={() => setIsVisible(false)}
      >
      <div className="popup-content">
      <p>This is the popup content</p>
      </div>
      </orca.components.Popup>

      // Custom positioned and aligned popup panel
      <orca.components.Popup
      refElement={anchorRef}
      visible={showPopup}
      placement="horizontal"
      defaultPlacement="right"
      alignment="center"
      offset={10}
      onClose={closePopup}
      className="custom-popup"
      >
      <div className="info-card">
      <h3>Details</h3>
      <p>Here is more detailed content...</p>
      </div>
      </orca.components.Popup>
    • Segmented: (
          props: {
              className?: string;
              onChange: (value: string) => void | Promise<void>;
              options: {
                  jsx?: ReactElement<any, string | JSXElementConstructor<any>>;
                  label?: string;
                  value: string;
              }[];
              selected: string;
              style?: CSSProperties;
          } & Omit<HTMLAttributes<HTMLDivElement>, "onChange">,
      ) => null | Element

      Segmented control for selecting from options

      // Basic segmented control
      const [selected, setSelected] = useState("list");
      <orca.components.Segmented
      selected={selected}
      options={[
      { value: "list", label: "List" },
      { value: "grid", label: "Grid" },
      { value: "table", label: "Table" }
      ]}
      onChange={(value) => setSelected(value)}
      />

      // Segmented control with custom JSX
      <orca.components.Segmented
      selected={viewMode}
      options={[
      { value: "day", jsx: <i className="ti ti-calendar-day" /> },
      { value: "week", jsx: <i className="ti ti-calendar-week" /> },
      { value: "month", jsx: <i className="ti ti-calendar-month" /> }
      ]}
      onChange={setViewMode}
      className="calendar-mode-selector"
      />
    • Select: (
          props: {
              alignment?: "left" | "right" | "center";
              buttonClassName?: string;
              disabled?: boolean;
              filter?: boolean;
              filterFunction?: (
                  keyword: string,
              ) => Promise<{ group?: string; label: string; value: string }[]>;
              filterPlaceholder?: string;
              menuClassName?: string;
              menuContainer?: RefObject<HTMLElement>;
              multiSelection?: boolean;
              onChange?: (
                  selected: string[],
                  filterKeyword?: string,
              ) => void | Promise<void>;
              onMouseEnter?: (e: MouseEvent) => void;
              onMouseLeave?: (e: MouseEvent) => void;
              options: { group?: string; label: string; value: string }[];
              placeholder?: string;
              pre?: ReactElement<any, string | JSXElementConstructor<any>>;
              readOnly?: boolean;
              selected: string[];
              width?: string | number;
              withClear?: boolean;
          },
      ) => null
      | Element

      Dropdown select component

      // Basic dropdown selector
      const [selected, setSelected] = useState(["option1"]);
      <orca.components.Select
      selected={selected}
      options={[
      { value: "option1", label: "Option 1" },
      { value: "option2", label: "Option 2" },
      { value: "option3", label: "Option 3" }
      ]}
      onChange={(newSelected) => setSelected(newSelected)}
      />

      // Multi-select dropdown with filtering
      <orca.components.Select
      selected={selectedTags}
      options={availableTags}
      multiSelection={true}
      filter={true}
      filterPlaceholder="Search tags..."
      placeholder="Select tags"
      onChange={handleTagsChange}
      />

      // Grouped dropdown selector
      <orca.components.Select
      selected={[selectedLanguage]}
      options={[
      { value: "js", label: "JavaScript", group: "Frontend" },
      { value: "ts", label: "TypeScript", group: "Frontend" },
      { value: "py", label: "Python", group: "Backend" },
      { value: "go", label: "Golang", group: "Backend" }
      ]}
      pre={<i className="ti ti-code" />}
      alignment="left"
      width="200px"
      onChange={(selected) => setSelectedLanguage(selected[0])}
      />
    • Skeleton: (props: {}) => null | Element

      Loading placeholder

      // Basic loading placeholder
      <div className="loading-container">
      <orca.components.Skeleton />
      </div>

      // Layout during content loading
      <div className="content-card">
      <div className="header">
      {isLoading ? <orca.components.Skeleton /> : <h2>{title}</h2>}
      </div>
      <div className="body">
      {isLoading ? (
      <>
      <orca.components.Skeleton />
      <orca.components.Skeleton />
      <orca.components.Skeleton />
      </>
      ) : (
      <p>{content}</p>
      )}
      </div>
      </div>
    • Switch: (
          props: {
              on?: boolean;
              onChange?: (on: boolean) => void | Promise<void>;
              readonly?: boolean;
              unset?: boolean;
          } & Omit<HTMLAttributes<HTMLButtonElement>, "onChange">,
      ) => null | Element

      Toggle switch component

      // Basic switch
      const [isOn, setIsOn] = useState(false);
      <orca.components.Switch
      on={isOn}
      onChange={(newValue) => setIsOn(newValue)}
      />

      // Read-only switch
      <orca.components.Switch
      on={featureEnabled}
      readonly={true}
      />

      // Unset state switch
      <orca.components.Switch
      unset={true}
      onChange={handleInheritedSetting}
      />

      // Switch with label
      <div className="setting-row">
      <label>Enable Notifications</label>
      <orca.components.Switch
      on={notificationsEnabled}
      onChange={toggleNotifications}
      />
      </div>
    • Table: (
          props: {
              columns: { icon?: string; name: string }[];
              initialColumnSizes: string;
              items: { _type: string; [key: string]: any }[];
              onColumnResize?: (value: string) => void | Promise<void>;
              pinColumn?: boolean;
              rowRenderer: (
                  item: { _type: string; [key: string]: any },
                  className: string,
                  index: number,
              ) => ReactNode;
          } & HTMLAttributes<HTMLDivElement>,
      ) => null | Element

      Data table component

      // Basic data table
      <orca.components.Table
      columns={[
      { name: "Name", icon: "ti ti-file" },
      { name: "Size", icon: "ti ti-ruler" },
      { name: "Modified Date", icon: "ti ti-calendar" }
      ]}
      items={files}
      initialColumnSizes="2fr 1fr 1fr"
      rowRenderer={(item, className, index) => (
      <tr key={item.id} className={className}>
      <td>{item.name}</td>
      <td>{item.size}</td>
      <td>{item.modifiedDate}</td>
      </tr>
      )}
      />

      // Table with pinned column and resizable columns
      <orca.components.Table
      columns={[
      { name: "ID" },
      { name: "Product Name" },
      { name: "Price" },
      { name: "Stock" }
      ]}
      items={products}
      initialColumnSizes="80px 2fr 1fr 1fr"
      pinColumn={true}
      onColumnResize={handleColumnResize}
      className="products-table"
      rowRenderer={(product, className, index) => (
      <tr key={product.id} className={className} onClick={() => selectProduct(product.id)}>
      <td>{product.id}</td>
      <td>{product.name}</td>
      <td>{formatCurrency(product.price)}</td>
      <td>{product.stock}</td>
      </tr>
      )}
      />
    • TagPopup: (
          props: {
              blockId: number;
              children: (
                  openMenu: (e: UIEvent, state?: any) => void,
                  closeMenu: () => void,
              ) => ReactNode;
              closeMenu: () => void;
              onTagClick: (alias: string) => void | Promise<void>;
              placeholder?: string;
          } & Partial<
              {
                  alignment?: "top"
                  | "bottom"
                  | "left"
                  | "right"
                  | "center";
                  allowBeyondContainer?: boolean;
                  children: (
                      openMenu: (e: UIEvent, state?: any) => void,
                      closeMenu: () => void,
                  ) => ReactNode;
                  className?: string;
                  container?: any;
                  crossOffset?: number;
                  defaultPlacement?: "top" | "bottom" | "left" | "right";
                  escapeToClose?: boolean;
                  keyboardNav?: boolean;
                  menu: (close: () => void, state?: any) => ReactNode;
                  menuAttr?: Record<string, any>;
                  navDirection?: "vertical" | "both";
                  noPointerLogic?: boolean;
                  offset?: number;
                  onClosed?: () => void;
                  onOpened?: () => void;
                  placement?: "vertical" | "horizontal";
                  style?: any;
              },
          >,
      ) => null
      | Element

      Provides a popup menu for tag selection and creation. Allows users to search, select existing tags, or create new ones.

      // Basic usage
      <orca.components.TagPopup
      blockId={123}
      closeMenu={() => setMenuVisible(false)}
      onTagClick={(tag) => console.log(`Selected tag: ${tag}`)}
      >
      {(open) => (
      <orca.components.Button variant="outline" onClick={open}>
      Add Tag
      </orca.components.Button>
      )}
      </orca.components.TagPopup>

      // Custom placeholder text
      <orca.components.TagPopup
      blockId={456}
      closeMenu={handleClose}
      onTagClick={handleTagSelect}
      placeholder="Search or create a new tag..."
      container={containerRef}
      >
      {(open) => (
      <span onClick={open}>Manage Tags</span>
      )}
      </orca.components.TagPopup>
    • TagPropsEditor: (
          props: {
              blockId: number;
              children: (
                  openMenu: (e: UIEvent, state?: any) => void,
                  closeMenu: () => void,
              ) => ReactNode;
          } & Partial<
              {
                  alignment?: "top"
                  | "bottom"
                  | "left"
                  | "right"
                  | "center";
                  allowBeyondContainer?: boolean;
                  children: (
                      openMenu: (e: UIEvent, state?: any) => void,
                      closeMenu: () => void,
                  ) => ReactNode;
                  className?: string;
                  container?: any;
                  crossOffset?: number;
                  defaultPlacement?: "top" | "bottom" | "left" | "right";
                  escapeToClose?: boolean;
                  keyboardNav?: boolean;
                  menu: (close: () => void, state?: any) => ReactNode;
                  menuAttr?: Record<string, any>;
                  navDirection?: "vertical" | "both";
                  noPointerLogic?: boolean;
                  offset?: number;
                  onClosed?: () => void;
                  onOpened?: () => void;
                  placement?: "vertical" | "horizontal";
                  style?: any;
              },
          >,
      ) => null
      | Element

      Provides an editor interface for managing and configuring tag properties. Allows users to add, edit, and delete tag properties, set property types and values.

      // Basic usage
      <orca.components.TagPropsEditor
      blockId={123}
      >
      {(open) => (
      <orca.components.Button variant="outline" onClick={open}>
      Edit Tag Properties
      </orca.components.Button>
      )}
      </orca.components.TagPropsEditor>

      // With custom container
      <orca.components.TagPropsEditor
      blockId={456}
      container={containerRef}
      >
      {(open) => (
      <span onClick={open}>Configure Properties</span>
      )}
      </orca.components.TagPropsEditor>

      // Combined with other components
      <div className="tag-controls">
      <orca.components.TagPropsEditor blockId={789}>
      {(open) => (
      <orca.components.Button
      variant="plain"
      onClick={open}
      className="property-button"
      >
      <i className="ti ti-settings" />
      </orca.components.Button>
      )}
      </orca.components.TagPropsEditor>
      </div>
    • Tooltip: (
          props: {
              alignment?: "top" | "bottom" | "left" | "right" | "center";
              allowBeyondContainer?: boolean;
              children: ReactElement;
              defaultPlacement?: "top" | "bottom" | "left" | "right";
              delay?: number;
              image?: string;
              modifier?: "shift" | "ctrl" | "alt" | "meta";
              placement?: "vertical" | "horizontal";
              shortcut?: string;
              text: ReactNode;
              [key: string]: any;
          },
      ) => null
      | Element

      Tooltip component

      // Basic text tooltip
      <orca.components.Tooltip text="Delete this item">
      <button><i className="ti ti-trash" /></button>
      </orca.components.Tooltip>

      // Tooltip with shortcut
      <orca.components.Tooltip
      text="Save document"
      shortcut="⌘S"
      defaultPlacement="bottom"
      >
      <orca.components.Button variant="solid">
      <i className="ti ti-device-floppy" />
      </orca.components.Button>
      </orca.components.Tooltip>

      // Tooltip with image preview
      <orca.components.Tooltip
      text="View original image"
      image="/path/to/preview.jpg"
      placement="horizontal"
      alignment="top"
      delay={500}
      >
      <div className="thumbnail">
      <img src="/path/to/thumbnail.jpg" alt="Thumbnail" />
      </div>
      </orca.components.Tooltip>
    import * as React from "react"

    function MyPluginUI() {
    const Button = orca.components.Button
    return (
    <Button
    variant="solid"
    onClick={() => console.log("Clicked!")}>
    Click Me
    </Button>
    )
    }
    converters: {
        blockConvert(
            format: string,
            blockContent: BlockForConversion,
            repr: Repr,
            block?: Block,
            forExport?: boolean,
        ): Promise<string>;
        inlineConvert(
            format: string,
            type: string,
            content: ContentFragment,
        ): Promise<string>;
        registerBlock(
            format: string,
            type: string,
            fn: (
                blockContent: BlockForConversion,
                repr: Repr,
                block?: Block,
                forExport?: boolean,
            ) => string | Promise<string>,
        ): void;
        registerInline(
            format: string,
            type: string,
            fn: (content: ContentFragment) => string | Promise<string>,
        ): void;
        unregisterBlock(format: string, type: string): void;
        unregisterInline(format: string, type: string): void;
    }

    Content converter API, used to register converters for transforming blocks and inline content between different formats (e.g., HTML, plain text, Markdown).

    Type declaration

    • blockConvert: function
      • Converts a block to a specific format. This is typically used internally by the system when exporting content.

        Parameters

        • format: string

          The target format to convert to

        • blockContent: BlockForConversion

          The block content to convert

        • repr: Repr

          The block representation object

        • Optionalblock: Block

          Optional full block data

        • OptionalforExport: boolean

          Whether the conversion is for export purposes

        Returns Promise<string>

        A Promise that resolves to the converted string

        const htmlContent = await orca.converters.blockConvert(
        "html",
        blockContent,
        { type: "myplugin.customBlock", data: { key: "value" } }
        )
    • inlineConvert: function
      • Converts an inline content fragment to a specific format. This is typically used internally by the system when exporting content.

        Parameters

        • format: string

          The target format to convert to

        • type: string

          The type of the inline content

        • content: ContentFragment

          The inline content fragment to convert

        Returns Promise<string>

        A Promise that resolves to the converted string

        const markdownText = await orca.converters.inlineConvert(
        "markdown",
        "myplugin.highlight",
        { t: "myplugin.highlight", v: "Important note" }
        )
    • registerBlock: function
      • Registers a block converter for transforming a block type to a specific format.

        Parameters

        • format: string

          The target format (e.g., "plain", "html", "markdown")

        • type: string

          The block type to convert from

        • fn: (
              blockContent: BlockForConversion,
              repr: Repr,
              block?: Block,
              forExport?: boolean,
          ) => string | Promise<string>

          Conversion function that transforms block content to the target format

        Returns void

        // Convert a countdown block to HTML
        orca.converters.registerBlock(
        "html",
        "myplugin.countdown",
        (blockContent, repr, block, forExport) => {
        const date = new Date(repr.date)
        return `<div class="countdown" data-date="${date.toISOString()}">
        <span class="label">${repr.label}</span>
        <span class="date">${date.toLocaleDateString()}</span>
        </div>`
        }
        )
    • registerInline: function
      • Registers an inline content converter for transforming inline content to a specific format.

        Parameters

        • format: string

          The target format (e.g., "plain", "html", "markdown")

        • type: string

          The inline content type to convert from

        • fn: (content: ContentFragment) => string | Promise<string>

          Conversion function that transforms inline content to the target format

        Returns void

        // Convert a custom highlight inline content to Markdown
        orca.converters.registerInline(
        "markdown",
        "myplugin.highlight",
        (content) => {
        return `==${content.v}==`
        }
        )

        // Convert a user mention to HTML
        orca.converters.registerInline(
        "html",
        "myplugin.userMention",
        (content) => {
        return `<span class="user-mention" data-user-id="${content.id}">@${content.v}</span>`
        }
        )
    • unregisterBlock: function
      • Unregisters a block converter.

        Parameters

        • format: string

          The target format the converter was registered for

        • type: string

          The block type the converter was registered for

        Returns void

        orca.converters.unregisterBlock("html", "myplugin.countdown")
        
    • unregisterInline: function
      • Unregisters an inline content converter.

        Parameters

        • format: string

          The target format the converter was registered for

        • type: string

          The inline content type the converter was registered for

        Returns void

        orca.converters.unregisterInline("markdown", "myplugin.highlight")
        
    // Register a block converter
    orca.converters.registerBlock(
    "html",
    "myplugin.customBlock",
    (blockContent, repr) => {
    return `<div class="custom-block">${blockContent.text}</div>`
    }
    )
    headbar: {
        registerHeadbarButton(id: string, render: () => ReactElement): void;
        unregisterHeadbarButton(id: string): void;
    }

    Headbar API for registering custom buttons in the application's header bar.

    Type declaration

    • registerHeadbarButton: function
      • Registers a custom button in the Orca headbar.

        Parameters

        • id: string

          A unique identifier for the button

        • render: () => ReactElement

          A function that returns a React element to render

        Returns void

        orca.headbar.registerHeadbarButton("myplugin.settingsButton", () => (
        <orca.components.Button
        variant="plain"
        onClick={() => orca.commands.invokeCommand("myplugin.openSettings")}
        >
        <i className="ti ti-settings-filled" />
        </orca.components.Button>
        ))
    • unregisterHeadbarButton: function
      • Unregisters a previously registered headbar button.

        Parameters

        • id: string

          The identifier of the button to unregister

        Returns void

        // When unloading the plugin
        orca.headbar.unregisterHeadbarButton("myplugin.settingsButton")
    // Register a custom button in the headbar
    orca.headbar.registerHeadbarButton("myplugin.syncButton", () => (
    <orca.components.Button
    variant="plain"
    onClick={() => syncData()}
    >
    <i className="ti ti-refresh" />
    </orca.components.Button>
    ))
    nav: {
        addTo(
            id: string,
            dir: "top" | "bottom" | "left" | "right",
            src?: Pick<ViewPanel, "view" | "viewArgs" | "viewState">,
        ): null | string;
        changeSizes(startPanelId: string, values: number[]): void;
        close(id: string): void;
        closeAllBut(id: string): void;
        findViewPanel(id: string, panels: RowPanel): null | ViewPanel;
        focusNext(): void;
        focusPrev(): void;
        goBack(withRedo?: boolean): void;
        goForward(): void;
        goTo(
            view: PanelView,
            viewArgs?: Record<string, any>,
            panelId?: string,
        ): void;
        isThereMoreThanOneViewPanel(): boolean;
        move(
            from: string,
            to: string,
            dir: "top" | "bottom" | "left" | "right",
        ): void;
        openInLastPanel(view: PanelView, viewArgs?: Record<string, any>): void;
        switchFocusTo(id: string): void;
    }

    Navigation API, used to control Orca's panel navigation and layout. Provides methods for managing panels, navigating between views, and handling navigation history.

    Type declaration

    • addTo: function
      • Adds a new panel next to an existing panel in the specified direction.

        Parameters

        • id: string

          The ID of the existing panel to add the new panel next to

        • dir: "top" | "bottom" | "left" | "right"

          The direction to add the panel ("top", "bottom", "left", or "right")

        • Optionalsrc: Pick<ViewPanel, "view" | "viewArgs" | "viewState">

          Optional parameters for the new panel's view, view arguments, and state

        Returns null | string

        The ID of the newly created panel, or null if the panel couldn't be created

        // Add a new panel to the right of the current panel
        const newPanelId = orca.nav.addTo(orca.state.activePanel, "right")
    • changeSizes: function
      • Changes the sizes of panels starting from the specified panel.

        Parameters

        • startPanelId: string

          The ID of the starting panel

        • values: number[]

          Array of new size values

        Returns void

        // Resize panels starting from the current panel
        orca.nav.changeSizes(orca.state.activePanel, [300, 700])
    • close: function
      • Closes a panel by its ID.

        Parameters

        • id: string

          The ID of the panel to close

        Returns void

        // Close the current panel
        orca.nav.close(orca.state.activePanel)
    • closeAllBut: function
      • Closes all panels except the specified one.

        Parameters

        • id: string

          The ID of the panel to keep open

        Returns void

        // Close all panels except the current one
        orca.nav.closeAllBut(orca.state.activePanel)
    • findViewPanel: function
      • Finds a view panel by its ID within the panel structure.

        Parameters

        • id: string

          The ID of the panel to find

        • panels: RowPanel

          The root panel structure to search in

        Returns null | ViewPanel

        The found ViewPanel or null if not found

        const panel = orca.nav.findViewPanel("panel1", orca.state.panels)
        if (panel) {
        console.log("Panel view:", panel.view)
        }
    • focusNext: function
      • Focuses the next panel in the tab order.

        Returns void

        orca.nav.focusNext()
        
    • focusPrev: function
      • Focuses the previous panel in the tab order.

        Returns void

        orca.nav.focusPrev()
        
    • goBack: function
      • Navigates back to the previous panel state in history.

        Parameters

        • OptionalwithRedo: boolean

          Whether to allow redo (forward navigation) after going back

        Returns void

        // Go back with redo support
        orca.nav.goBack(true)
    • goForward: function
      • Navigates forward to the next panel state in history.

        Returns void

        orca.nav.goForward()
        
    • goTo: function
      • Navigates to a specific view in the specified panel or current active panel.

        Parameters

        • view: PanelView

          The type of view to navigate to ("journal" or "block")

        • OptionalviewArgs: Record<string, any>

          Arguments for the view, such as blockId or date

        • OptionalpanelId: string

          Optional panel ID to navigate in, defaults to active panel

        Returns void

        // Open a specific block in the current panel
        orca.nav.goTo("block", { blockId: 123 })

        // Open today's journal in a specific panel
        orca.nav.goTo("journal", { date: new Date() }, "panel1")
    • isThereMoreThanOneViewPanel: function
      • Checks if there is more than one view panel open.

        Returns boolean

        True if there is more than one view panel, false otherwise

        if (orca.nav.isThereMoreThanOneViewPanel()) {
        console.log("Multiple panels are open")
        }
    • move: function
      • Moves a panel from one location to another in the specified direction.

        Parameters

        • from: string

          The ID of the panel to move

        • to: string

          The ID of the destination panel

        • dir: "top" | "bottom" | "left" | "right"

          The direction to move the panel relative to the destination panel

        Returns void

        // Move panel1 to the bottom of panel2
        orca.nav.move("panel1", "panel2", "bottom")
    • openInLastPanel: function
      • Opens a view in the last used panel or creates a new one if needed. Useful for opening content in a separate panel.

        Parameters

        • view: PanelView

          The type of view to open ("journal" or "block")

        • OptionalviewArgs: Record<string, any>

          Arguments for the view, such as blockId or date

        Returns void

        // Open a block in a new or last used panel
        orca.nav.openInLastPanel("block", { blockId: 123 })
    • switchFocusTo: function
      • Switches focus to the specified panel.

        Parameters

        • id: string

          The ID of the panel to focus

        Returns void

        orca.nav.switchFocusTo("panel1")
        
    // Open a block in the current panel
    orca.nav.goTo("block", { blockId: 123 })

    // Open a block in a new panel
    orca.nav.openInLastPanel("block", { blockId: 123 })
    notify: (
        type: "info" | "success" | "warn" | "error",
        message: string,
        options?: { action?: () => void | Promise<void>; title?: string },
    ) => void

    Display a notification to the user. Notifications appear in the bottom right corner of the application and can be used to inform users about events, actions, or state changes.

    Type declaration

      • (
            type: "info" | "success" | "warn" | "error",
            message: string,
            options?: { action?: () => void | Promise<void>; title?: string },
        ): void
      • Parameters

        • type: "info" | "success" | "warn" | "error"

          The type of notification, which determines its appearance and icon

        • message: string

          The main notification message to display

        • Optionaloptions: { action?: () => void | Promise<void>; title?: string }

          Optional configuration including title and action callback

        Returns void

    // Simple info notification
    orca.notify("info", "Processing complete")

    // Error notification with title
    orca.notify("error", "Failed to connect to API", {
    title: "Connection Error"
    })

    // Success notification with action button
    orca.notify("success", "File exported successfully", {
    title: "Export Complete",
    action: () => {
    orca.commands.invokeCommand("myplugin.openExportedFile")
    }
    })
    plugins: {
        clearData(name: string): Promise<void>;
        disable(name: string): Promise<void>;
        enable(name: string): Promise<void>;
        getData(name: string, key: string): Promise<any>;
        getDataKeys(name: string): Promise<string[]>;
        load(
            name: string,
            schema: PluginSettingsSchema,
            settings: Record<string, any>,
        ): Promise<void>;
        register(name: string): Promise<void>;
        removeData(name: string, key: string): Promise<void>;
        setData(
            name: string,
            key: string,
            value: null | string | number | ArrayBuffer,
        ): Promise<void>;
        setSettings(
            to: "app" | "repo",
            name: string,
            settings: Record<string, any>,
        ): Promise<void>;
        setSettingsSchema(
            name: string,
            schema: PluginSettingsSchema,
        ): Promise<void>;
        unload(name: string): Promise<void>;
        unregister(name: string): Promise<void>;
    }

    Plugin management API, used to register, enable, disable, and manage plugin data and settings.

    Type declaration

    • clearData: function
      • Removes all data stored by a plugin.

        Parameters

        • name: string

          The name of the plugin

        Returns Promise<void>

        A Promise that resolves when all data is cleared

        await orca.plugins.clearData("my-plugin")
        
    • disable: function
      • Disables a plugin without unregistering it. The plugin will remain installed but won't be loaded until enabled again.

        Parameters

        • name: string

          The name of the plugin to disable

        Returns Promise<void>

        A Promise that resolves when the plugin is disabled

        await orca.plugins.disable("my-plugin")
        
    • enable: function
      • Enables a previously disabled plugin.

        Parameters

        • name: string

          The name of the plugin to enable

        Returns Promise<void>

        A Promise that resolves when the plugin is enabled

        await orca.plugins.enable("my-plugin")
        
    • getData: function
      • Retrieves data stored by a plugin.

        Parameters

        • name: string

          The name of the plugin

        • key: string

          The key of the data to retrieve

        Returns Promise<any>

        A Promise that resolves to the stored data

        const userData = await orca.plugins.getData("my-plugin", "user-preferences")
        console.log("User preferences:", userData)
    • getDataKeys: function
      • Gets all data keys stored by a plugin.

        Parameters

        • name: string

          The name of the plugin

        Returns Promise<string[]>

        A Promise that resolves to an array of key strings

        const keys = await orca.plugins.getDataKeys("my-plugin")
        console.log("Stored data keys:", keys)
    • load: function
      • Loads a plugin with the given schema and settings. This is typically called internally by the plugin system.

        Parameters

        • name: string

          The name of the plugin to load

        • schema: PluginSettingsSchema

          The settings schema for the plugin

        • settings: Record<string, any>

          The current settings for the plugin

        Returns Promise<void>

        A Promise that resolves when the plugin is loaded

    • register: function
      • Registers a plugin with Orca. This is typically called automatically when a plugin is installed.

        Parameters

        • name: string

          The name of the plugin to register

        Returns Promise<void>

        A Promise that resolves when the plugin is registered

        await orca.plugins.register("my-plugin")
        
    • removeData: function
      • Removes a specific piece of data stored by a plugin.

        Parameters

        • name: string

          The name of the plugin

        • key: string

          The key of the data to remove

        Returns Promise<void>

        A Promise that resolves when the data is removed

        await orca.plugins.removeData("my-plugin", "cached-results")
        
    • setData: function
      • Stores data for a plugin.

        Parameters

        • name: string

          The name of the plugin

        • key: string

          The key to store the data under

        • value: null | string | number | ArrayBuffer

          The data to store (string, number, ArrayBuffer, or null)

        Returns Promise<void>

        A Promise that resolves when the data is stored

        await orca.plugins.setData(
        "my-plugin",
        "user-preferences",
        JSON.stringify({ theme: "dark", fontSize: 14 })
        )
    • setSettings: function
      • Sets settings for a plugin at either the application or repository level.

        Parameters

        • to: "app" | "repo"

          The scope of the settings ("app" for application-wide or "repo" for repository-specific)

        • name: string

          The name of the plugin

        • settings: Record<string, any>

          The settings to set

        Returns Promise<void>

        A Promise that resolves when settings are saved

        // Save app-level settings
        await orca.plugins.setSettings("app", "my-plugin", {
        apiKey: "sk-123456789",
        theme: "dark"
        })

        // Save repo-specific settings
        await orca.plugins.setSettings("repo", "my-plugin", {
        customTemplates: ["template1", "template2"]
        })
    • setSettingsSchema: function
      • Sets the settings schema for a plugin, defining what settings are available and how they should be presented in the UI.

        Parameters

        • name: string

          The name of the plugin

        • schema: PluginSettingsSchema

          The settings schema defining available settings

        Returns Promise<void>

        A Promise that resolves when the schema is set

        await orca.plugins.setSettingsSchema("my-plugin", {
        apiKey: {
        label: "API Key",
        description: "Your API key for the service",
        type: "string"
        },
        enableFeature: {
        label: "Enable Feature",
        description: "Turn on advanced features",
        type: "boolean",
        defaultValue: false
        }
        })
    • unload: function
      • Unloads a plugin. This is called when disabling or unregistering a plugin. This is typically called internally by the plugin system.

        Parameters

        • name: string

          The name of the plugin to unload

        Returns Promise<void>

        A Promise that resolves when the plugin is unloaded

    • unregister: function
      • Unregisters a plugin from Orca. This is typically called automatically when a plugin is uninstalled.

        Parameters

        • name: string

          The name of the plugin to unregister

        Returns Promise<void>

        A Promise that resolves when the plugin is unregistered

        await orca.plugins.unregister("my-plugin")
        
    // Register a plugin
    await orca.plugins.register("my-plugin")

    // Set plugin settings schema
    await orca.plugins.setSettingsSchema("my-plugin", {
    apiKey: {
    label: "API Key",
    description: "Your API key for the service",
    type: "string"
    }
    })
    renderers: {
        registerBlock(
            type: string,
            isEditable: boolean,
            renderer: any,
            assetFields?: string[],
        ): void;
        registerInline(type: string, isEditable: boolean, renderer: any): void;
        unregisterBlock(type: string): void;
        unregisterInline(type: string): void;
    }

    Renderer management API, used to register custom block and inline content renderers.

    Type declaration

    • registerBlock: function
      • Registers a custom block renderer.

        Parameters

        • type: string

          The type identifier for the block (e.g., "myplugin.diagram")

        • isEditable: boolean

          Whether this block type should be editable

        • renderer: any

          The React component that renders the block

        • OptionalassetFields: string[]

          Optional array of property names that may contain asset references (used for proper asset handling during import/export)

        Returns void

        import DiagramBlock from "./DiagramBlock"

        // Register a block renderer without asset fields
        orca.renderers.registerBlock(
        "myplugin.diagram",
        true,
        DiagramBlock
        )

        // Register a block renderer with asset fields
        orca.renderers.registerBlock(
        "myplugin.attachment",
        true,
        AttachmentBlock,
        ["url", "thumbnailUrl"]
        )
    • registerInline: function
      • Registers a custom inline content renderer.

        Parameters

        • type: string

          The type identifier for the inline content (e.g., "myplugin.special")

        • isEditable: boolean

          Whether this inline content should be editable

        • renderer: any

          The React component that renders the inline content

        Returns void

        import SpecialInline from "./SpecialInline"

        orca.renderers.registerInline(
        "myplugin.special",
        true,
        SpecialInline
        )
    • unregisterBlock: function
      • Unregisters a previously registered block renderer.

        Parameters

        • type: string

          The type identifier of the block renderer to remove

        Returns void

        orca.renderers.unregisterBlock("myplugin.diagram")
        
    • unregisterInline: function
      • Unregisters a previously registered inline content renderer.

        Parameters

        • type: string

          The type identifier of the inline content renderer to remove

        Returns void

        orca.renderers.unregisterInline("myplugin.special")
        
    // Register a custom block renderer
    orca.renderers.registerBlock(
    "myplugin.customBlock",
    true,
    CustomBlockRenderer,
    ["image", "attachmentUrl"]
    )
    shortcuts: {
        assign(shortcut: string, command: string): Promise<void>;
        reload(): Promise<void>;
        reset(command: string): Promise<void>;
    }

    Keyboard shortcuts management API, used to assign, reset and reload keyboard shortcuts.

    Type declaration

    • assign: function
      • Assigns a keyboard shortcut to a command. If the shortcut is empty, it will remove the shortcut from the command.

        Parameters

        • shortcut: string

          The keyboard shortcut string (e.g., "ctrl+shift+k" or "meta+p")

        • command: string

          The command ID to bind the shortcut to

        Returns Promise<void>

        A Promise that resolves when the shortcut is assigned

        // Assign a shortcut
        await orca.shortcuts.assign("ctrl+shift+k", "myplugin.myCommand")

        // Remove a shortcut
        await orca.shortcuts.assign("", "myplugin.myCommand")
    • reload: function
      • Reloads all keyboard shortcuts from the database. Usually not needed to be called directly as the system handles this automatically.

        Returns Promise<void>

        A Promise that resolves when shortcuts are reloaded

    • reset: function
      • Resets a command to its default keyboard shortcut.

        Parameters

        • command: string

          The command ID to reset

        Returns Promise<void>

        A Promise that resolves when the shortcut is reset

        await orca.shortcuts.reset("core.toggleThemeMode")
        
    // Assign a new keyboard shortcut
    await orca.shortcuts.assign("ctrl+shift+k", "myplugin.myCommand")

    // Reset a command to its default shortcut
    await orca.shortcuts.reset("myplugin.myCommand")
    slashCommands: {
        registerSlashCommand(id: string, command: SlashCommand): void;
        unregisterSlashCommand(id: string): void;
    }

    Slash commands API for registering custom commands that appear when a user types '/' in the editor. Slash commands provide quick access to actions directly from the editor.

    Type declaration

    • registerSlashCommand: function
      • Registers a slash command that appears in the slash command menu.

        Parameters

        • id: string

          A unique identifier for the command

        • command: SlashCommand

          The slash command configuration

        Returns void

        orca.slashCommands.registerSlashCommand("myplugin.insertChart", {
        icon: "ti ti-chart-bar",
        group: "Insert", // Group name for organization in the menu
        title: "Insert Chart", // Display name in the menu
        command: "myplugin.insertChartCommand" // Command ID to execute
        })
    • unregisterSlashCommand: function
      • Unregisters a previously registered slash command.

        Parameters

        • id: string

          The identifier of the slash command to unregister

        Returns void

        // When unloading the plugin
        orca.slashCommands.unregisterSlashCommand("myplugin.insertChart")
    // Register a slash command
    orca.slashCommands.registerSlashCommand("myplugin.insertTemplate", {
    icon: "ti ti-template",
    group: "Templates",
    title: "Insert Project Template",
    command: "myplugin.insertProjectTemplate"
    })
    state: {
        activePanel: string;
        blockConverters: Record<
            string,
            | undefined
            | Record<
                string,
                | undefined
                | (
                    (
                        blockContent: BlockForConversion,
                        repr: Repr,
                        block?: Block,
                        forExport?: boolean,
                    ) => string | Promise<string>
                ),
            >,
        >;
        blockMenuCommands: Record<string, undefined | BlockMenuCommand>;
        blockRenderers: Record<string, any>;
        blocks: Record<string | number, undefined | Block>;
        commandPaletteOpened: boolean;
        commands: Record<string, undefined | CommandWithPinyin>;
        dataDir: string;
        filterInTags?: string;
        globalSearchOpened: boolean;
        headbarButtons: Record<string, undefined | (() => ReactElement)>;
        inlineConverters: Record<
            string,
            | undefined
            | Record<string, (content: ContentFragment) => string | Promise<string>>,
        >;
        inlineRenderers: Record<string, any>;
        locale: string;
        notifications: Notification[];
        panelBackHistory: PanelHistory[];
        panelForwardHistory: PanelHistory[];
        panels: RowPanel;
        plugins: Record<string, undefined | Plugin>;
        repo: string;
        repoDir?: string;
        settings: Record<number, any>;
        settingsOpened: boolean;
        shortcuts: Record<string, undefined | string>;
        sidebarTab: string;
        slashCommands: Record<string, undefined | SlashCommandWithPinyin>;
        tagMenuCommands: Record<string, undefined | TagMenuCommand>;
        themeMode: "light" | "dark";
        themes: Record<string, undefined | string>;
        toolbarButtons: Record<string, undefined | ToolbarButton | ToolbarButton[]>;
    }

    The current state of the Orca Note application. This object contains the reactive state that updates as the application changes. Plugins can read from this state to understand the current context and subscribe to changes.

    Type declaration

    • activePanel: string

      The ID of the currently active (focused) panel. This can be used to target operations to the user's current working context.

      // Get the currently active panel
      const activePanelId = orca.state.activePanel

      // Open a block in the currently active panel
      orca.nav.goTo("block", { blockId: 123 }, activePanelId)
    • blockConverters: Record<
          string,
          | undefined
          | Record<
              string,
              | undefined
              | (
                  (
                      blockContent: BlockForConversion,
                      repr: Repr,
                      block?: Block,
                      forExport?: boolean,
                  ) => string | Promise<string>
              ),
          >,
      >

      Registry of block converters that transform block content to different formats. Organized as a nested record with format as the first key and block type as the second.

      // Check if a converter exists for HTML format and custom block type
      const hasConverter = !!orca.state.blockConverters?.["html"]?.["myplugin.customBlock"]
    • blockMenuCommands: Record<string, undefined | BlockMenuCommand>

      Registry of block menu commands that appear in block context menus. These commands provide custom actions for blocks.

      // Check if a specific block menu command is registered
      const hasExportCommand = !!orca.state.blockMenuCommands["myplugin.exportBlock"]
    • blockRenderers: Record<string, any>

      Registry of block renderer components used to render different block types. Each key is a block type, and the value is the React component used to render it.

      // Get the renderer for a specific block type
      const codeBlockRenderer = orca.state.blockRenderers["code"]
    • blocks: Record<string | number, undefined | Block>

      Map of all blocks currently loaded in memory, indexed by their database IDs. This provides quick access to block data without needing backend queries.

      // Get a block by its ID
      const block = orca.state.blocks[123]
      if (block) {
      console.log(`Block content: ${block.text}`)
      }
    • commandPaletteOpened: boolean

      Indicates whether the command palette is currently opened. This can be used to conditionally change behavior when the command palette is active.

      if (orca.state.commandPaletteOpened) {
      console.log("Command palette is currently open")
      }
    • commands: Record<string, undefined | CommandWithPinyin>

      Registry of all registered commands in the application, indexed by their IDs. Each command includes pinyin data for search functionality.

      // Check if a command exists
      if (orca.state.commands["core.createBlock"]) {
      console.log("Create block command is available")
      }
    • dataDir: string

      The absolute path to the application data directory. This is where Orca stores configuration and other application-level data.

      console.log(`Application data directory: ${orca.state.dataDir}`)
      
    • OptionalfilterInTags?: string

      Optional filter for tags shown in the tags panel. When set, only tags that match this filter will be displayed.

      if (orca.state.filterInTags === "project") {
      console.log("Tag panel is filtering to show only project tags")
      }
    • globalSearchOpened: boolean

      Indicates whether the global search panel is currently opened. This can be used to conditionally change behavior when search is active.

      if (orca.state.globalSearchOpened) {
      console.log("Global search is currently open")
      }
    • headbarButtons: Record<string, undefined | (() => ReactElement)>

      Registry of custom buttons registered for the header bar. Each entry contains a render function that returns a React element.

      // Check if a specific headbar button is registered
      const hasMyButton = !!orca.state.headbarButtons["myplugin.syncButton"]
    • inlineConverters: Record<
          string,
          | undefined
          | Record<string, (content: ContentFragment) => string | Promise<string>>,
      >

      Registry of inline content converters that transform inline content to different formats. Organized as a nested record with format as the first key and content type as the second.

      // Check if a converter exists for Markdown format and highlight content
      const hasConverter = !!orca.state.inlineConverters?.["markdown"]?.["highlight"]
    • inlineRenderers: Record<string, any>

      Registry of inline renderer components used to render different inline content types. Each key is a content type, and the value is the React component used to render it.

      // Get the renderer for a specific inline content type
      const codeInlineRenderer = orca.state.inlineRenderers["code"]
    • locale: string

      The current locale of the application (e.g., "en" for English, "zh-CN" for Chinese). This determines the language used for the UI and can be used for localization.

      if (orca.state.locale === "zh-CN") {
      console.log("Chinese language is active")
      }
    • notifications: Notification[]

      Array of active notifications currently displayed to the user. Each notification includes a type, message, and optional title and action.

      // Check if there are any error notifications active
      const hasErrors = orca.state.notifications.some(n => n.type === "error")
    • panelBackHistory: PanelHistory[]

      History of past panel states for backward navigation. This is used to implement the back button functionality in the UI.

      // Check if there are states to navigate back to
      const canGoBack = orca.state.panelBackHistory.length > 0
    • panelForwardHistory: PanelHistory[]

      History of forward panel states for forward navigation after going back. This is used to implement the forward button functionality in the UI.

      // Check if there are states to navigate forward to
      const canGoForward = orca.state.panelForwardHistory.length > 0
    • panels: RowPanel

      The root panel structure that defines the current layout of the application. This contains all panels and their arrangement in rows and columns.

      // Access the structure of all panels
      const rootPanel = orca.state.panels
      console.log(`Root panel ID: ${rootPanel.id}`)
      console.log(`Number of child panels: ${rootPanel.children.length}`)
    • plugins: Record<string, undefined | Plugin>

      Registry of all installed plugins, indexed by their names. Each entry contains the plugin metadata and its loaded module if active.

      // Check if a plugin is installed and enabled
      const myPlugin = orca.state.plugins["my-plugin"]
      if (myPlugin && myPlugin.enabled) {
      console.log("My plugin is installed and enabled")
      }
    • repo: string

      The name of the current repository. This is the identifier for the currently open note repository.

      console.log(`Current repository: ${orca.state.repo}`)
      
    • OptionalrepoDir?: string

      The absolute path to the current repository directory, if a repository is added from non-standard location. This is where the current note repository is stored on the file system.

      if (orca.state.repoDir) {
      console.log(`Current repository directory: ${orca.state.repoDir}`)
      }
    • settings: Record<number, any>

      Application and repository settings, indexed by their numeric IDs. Contains configuration values for both the application and the current repository.

      // Access a specific setting by its ID
      const editorFontSize = orca.state.settings[12345]
    • settingsOpened: boolean

      Indicates whether the settings panel is currently opened. This can be used to conditionally change behavior when settings are being edited.

      if (orca.state.settingsOpened) {
      console.log("Settings panel is currently open")
      }
    • shortcuts: Record<string, undefined | string>

      Registry of keyboard shortcuts, mapping shortcut strings to command IDs. This defines the current keyboard bindings in the application.

      // Find the command bound to a specific shortcut
      const boundCommand = orca.state.shortcuts["ctrl+shift+p"]
      if (boundCommand) {
      console.log(`Command ${boundCommand} is bound to Ctrl+Shift+P`)
      }
    • sidebarTab: string

      The currently active tab in the sidebar. This indicates which sidebar section is currently displayed.

      if (orca.state.sidebarTab === "tags") {
      console.log("Tags tab is currently active in sidebar")
      }
    • slashCommands: Record<string, undefined | SlashCommandWithPinyin>

      Registry of slash commands available in the editor, indexed by their IDs. Each command includes pinyin data for search functionality.

      // Check if a specific slash command is registered
      const hasInsertChartCommand = !!orca.state.slashCommands["myplugin.insertChart"]
    • tagMenuCommands: Record<string, undefined | TagMenuCommand>

      Registry of tag menu commands that appear in tag context menus. These commands provide custom actions for tags.

      // Check if a specific tag menu command is registered
      const hasTagStatsCommand = !!orca.state.tagMenuCommands["myplugin.tagStats"]
    • themeMode: "light" | "dark"

      The current theme mode of the application ("light" or "dark"). This determines whether the light or dark theme variant is active.

      if (orca.state.themeMode === "dark") {
      console.log("Dark theme is active")
      }
    • themes: Record<string, undefined | string>

      Registry of installed themes, mapping theme names to CSS file paths. This defines all available themes that can be selected.

      // Get the CSS file path for a specific theme
      const oceanThemePath = orca.state.themes["Ocean Blue"]
    • toolbarButtons: Record<string, undefined | ToolbarButton | ToolbarButton[]>

      Registry of toolbar buttons or button groups registered for the editor toolbar. Each entry can be a single button configuration or an array of related buttons.

      // Check if a specific toolbar button is registered
      const hasFormatButton = !!orca.state.toolbarButtons["myplugin.formatButton"]
    tagMenuCommands: {
        registerTagMenuCommand(id: string, command: TagMenuCommand): void;
        unregisterTagMenuCommand(id: string): void;
    }

    Tag menu commands API for adding custom commands to tag context menus. This allows plugins to add custom actions that appear when users open the tag's context menu.

    Type declaration

    • registerTagMenuCommand: function
      • Registers a custom command in the tag context menu.

        Parameters

        • id: string

          A unique identifier for the command

        • command: TagMenuCommand

          The command configuration, including a render function that returns a React element

        Returns void

        orca.tagMenuCommands.registerTagMenuCommand("myplugin.exportTaggedBlocks", {
        render: (tagBlock, close) => (
        <orca.components.MenuText
        preIcon="ti ti-file-export"
        title="Export Tagged Blocks"
        onClick={() => {
        close()
        exportTaggedBlocks(tagBlock)
        }}
        />
        )
        })
    • unregisterTagMenuCommand: function
      • Unregisters a previously registered tag menu command.

        Parameters

        • id: string

          The identifier of the tag menu command to unregister

        Returns void

        // When unloading the plugin
        orca.tagMenuCommands.unregisterTagMenuCommand("myplugin.exportTaggedBlocks")
    // Register a command for the tag context menu
    const MenuText = orca.components.MenuText
    orca.tagMenuCommands.registerTagMenuCommand("myplugin.tagStats", {
    render: (tagBlock, close) => (
    <MenuText
    title="Show Tag Statistics"
    onClick={() => {
    close()
    showTagStatistics(tagBlock)
    }}
    />
    )
    })
    themes: {
        injectCSSResource(url: string, role: string): void;
        register(
            pluginName: string,
            themeName: string,
            themeFileName: string,
        ): void;
        removeCSSResources(role: string): void;
        unregister(themeName: string): void;
    }

    Theme management API, used to register, unregister, and manage visual themes.

    Type declaration

    • injectCSSResource: function
      • Injects a CSS resource into the application. Useful for adding styles that are not part of a theme but are needed by a plugin.

        Parameters

        • url: string

          The URL or path to the CSS resource

        • role: string

          A unique identifier for the resource to allow for later removal

        Returns void

        orca.themes.injectCSSResource("styles/my-plugin-styles.css", "my-plugin-ui")
        
    • register: function
      • Registers a theme with Orca.

        Parameters

        • pluginName: string

          The name of the plugin registering the theme

        • themeName: string

          The display name of the theme

        • themeFileName: string

          The file path to the theme CSS file (relative to plugin directory)

        Returns void

        orca.themes.register("my-plugin", "Dark Ocean", "themes/dark-ocean.css")
        
    • removeCSSResources: function
      • Removes previously injected CSS resources with the specified role.

        Parameters

        • role: string

          The role identifier of the CSS resources to remove

        Returns void

        orca.themes.removeCSSResources("my-plugin-ui")
        
    • unregister: function
      • Unregisters a theme.

        Parameters

        • themeName: string

          The name of the theme to unregister

        Returns void

        orca.themes.unregister("Dark Ocean")
        
    // Register a theme from a plugin
    orca.themes.register("my-plugin", "Dark Ocean", "themes/dark-ocean.css")
    toolbar: {
        registerToolbarButton(
            id: string,
            button: ToolbarButton | ToolbarButton[],
        ): void;
        unregisterToolbarButton(id: string): void;
    }

    Toolbar API for registering custom buttons in the block editor toolbar.

    Type declaration

    • registerToolbarButton: function
      • Registers a toolbar button or group of buttons.

        Parameters

        • id: string

          A unique identifier for the button

        • button: ToolbarButton | ToolbarButton[]

          Button configuration or array of button configurations

        Returns void

        // Register a single button with a command
        orca.toolbar.registerToolbarButton("myplugin.formatButton", {
        icon: "ti ti-wand",
        tooltip: "Format text",
        command: "myplugin.formatText"
        })

        // Register a button with a dropdown menu
        const MenuText = orca.components.MenuText
        orca.toolbar.registerToolbarButton("myplugin.insertButton", {
        icon: "ti ti-plus",
        tooltip: "Insert special content",
        menu: (close) => (
        <>
        <MenuText
        title="Insert Table"
        onClick={() => {
        close()
        orca.commands.invokeCommand("myplugin.insertTable")
        }}
        />
        <MenuText
        title="Insert Chart"
        onClick={() => {
        close()
        orca.commands.invokeCommand("myplugin.insertChart")
        }}
        />
        </>
        )
        })

        // Register a group of related buttons
        orca.toolbar.registerToolbarButton("myplugin.formattingTools", [
        {
        icon: "ti ti-bold",
        tooltip: "Bold",
        command: "myplugin.makeBold"
        },
        {
        icon: "ti ti-italic",
        tooltip: "Italic",
        command: "myplugin.makeItalic"
        }
        ])
    • unregisterToolbarButton: function
      • Unregisters a previously registered toolbar button or button group.

        Parameters

        • id: string

          The identifier of the button or button group to unregister

        Returns void

        // When unloading the plugin
        orca.toolbar.unregisterToolbarButton("myplugin.formatButton")
    // Register a simple toolbar button
    orca.toolbar.registerToolbarButton("myplugin.formatButton", {
    icon: "ti ti-wand",
    tooltip: "Format selection",
    command: "myplugin.formatText"
    })

    Methods

    • Invokes a backend API with the specified API type and arguments. This is a core method for plugins to communicate with the Orca backend systems.

      Parameters

      • type: string

        The API message type to invoke, which specifies what backend functionality to call

      • ...args: any[]

        Any additional arguments needed by the specified backend API

      Returns Promise<any>

      A Promise that resolves with the result from the backend call

      // Get a block by its ID
      const block = await orca.invokeBackend("get-block", 12345)
      console.log(`Block content: ${block.text}`)

      // Get blocks with specific tags
      const taggedBlocks = await orca.invokeBackend(
      "get-blocks-with-tags",
      ["project", "active"]
      )
      console.log(`Found ${taggedBlocks.length} active projects`)