typograph-editor-documentation
    Preparing search index...

    Menu API — Developer Reference

    The Menu API lets you customize the editor's menu bar at runtime: hide or show menus and items, add your own items and menus, control which items are enabled, and respond to item selections.


    The API is available as gMenuAPI once the editor has finished loading. Wait for the typograph_editor_ready event before calling any method.

    Include the editor bundle and access gMenuAPI as a plain global:

    <script src="dist/editor.js"></script>
    <script>
    document.addEventListener('typograph_editor_ready', function() {
    gMenuAPI.hideMenu('menutitle-help');
    });
    </script>
    import { gMenuAPI } from 'typograph-editor-ui';

    document.addEventListener('typograph_editor_ready', () => {
    gMenuAPI.hideMenu('menutitle-help');
    });

    Each top-level menu in the menu bar has an HTML element ID. The built-in menus are:

    Menu bar label ID
    File menutitle-file
    Edit menutitle-edit
    Select menutitle-select
    View menutitle-view
    Page menutitle-page
    Arrange menutitle-arrange
    Insert menutitle-insert
    Help menutitle-help

    Every menu item has a unique ID formed by combining the menu title ID with the item label:

    {menuTitleId}_{ItemLabel}
    

    Spaces in labels are represented by underscores. Examples:

    Menu Label Item ID
    File Save menutitle-file_Save
    File Save as… menutitle-file_Save_as
    File Save as Template menutitle-file_Save_as_Template
    Edit Undo menutitle-edit_Undo
    Edit Step and Repeat… menutitle-edit_Step_and_Repeat
    View Show Rulers menutitle-view_Show_Rulers
    Arrange Group menutitle-arrange_Group

    Note: Trailing (ellipsis) is not part of the ID. Save as…menutitle-file_Save_as.

    A complete list of built-in item IDs is provided in the Built-in item ID reference at the end of this document.


    // Where to insert a custom item relative to an existing item
    type MenuItemPosition =
    | { before: string } // insert before the item with this ID
    | { after: string } // insert after the item with this ID
    | 'start' // prepend to the top of the menu
    | 'end'; // append to the bottom of the menu (default)

    // Descriptor for a custom menu item
    interface CustomMenuItemDescriptor {
    title: string; // label shown in the menu; use underscores for spaces
    shortcut: string; // keyboard shortcut text shown on the right, or "" for none
    }

    // Descriptor for a new top-level menu
    interface CustomTopLevelMenuDescriptor {
    menuTitleId: string; // unique ID for the new menu title element
    label: string; // text shown in the menu bar
    items: CustomMenuItemDescriptor[];// initial items (more can be added later)
    }

    // Validator callback — controls whether an item is enabled
    // Return true → item is enabled
    // Return false → item is disabled (greyed out, not clickable)
    // Return null → use the editor's built-in enabled/disabled logic
    type MenuValidator = (itemId: string) => boolean | null;

    // Action callback — called when the user clicks an item
    // Return true → action is handled; the editor's built-in action is suppressed
    // Return false (or void) → the editor's built-in action also runs
    type MenuAction = (itemId: string) => boolean | void;

    Removes a top-level menu title from the menu bar. The menu and all its items remain registered and can be restored with showMenu().

    gMenuAPI.hideMenu('menutitle-help');
    

    Restores a previously hidden menu title to the menu bar.

    gMenuAPI.showMenu('menutitle-help');
    

    Prevents a menu item from appearing when its menu is opened. The item is not destroyed; call showItem() to restore it.

    gMenuAPI.hideItem('menutitle-file_Save_as_Template');
    

    Restores a previously hidden menu item.

    gMenuAPI.showItem('menutitle-file_Save_as_Template');
    

    Adds a custom item to an existing menu.

    Parameter Type Description
    menuTitleId string The menu to add the item to
    descriptor CustomMenuItemDescriptor Label and shortcut text
    position MenuItemPosition Where to insert the item (default: 'end')
    // Append to the bottom of the File menu
    gMenuAPI.addCustomItem(
    'menutitle-file',
    { title: 'Publish_to_CMS', shortcut: '' }
    );

    // Insert after "Save as…"
    gMenuAPI.addCustomItem(
    'menutitle-file',
    { title: 'Publish_to_CMS', shortcut: '' },
    { after: 'menutitle-file_Save_as' }
    );

    // Insert before "Save as Template"
    gMenuAPI.addCustomItem(
    'menutitle-file',
    { title: 'Publish_to_CMS', shortcut: '' },
    { before: 'menutitle-file_Save_as_Template' }
    );

    The item's ID is computed from the menu title ID and the item title:

    "menutitle-file" + "_" + "Publish_to_CMS""menutitle-file_Publish_to_CMS"
    

    Use this ID when registering a validator or action for the item.

    Important: Custom items are disabled by default. You must register a validator that returns true for the item to be clickable.
    See registerValidator().

    Adding a separator

    Use '---' as the title to insert a separator line:

    gMenuAPI.addCustomItem('menutitle-file', { title: '---', shortcut: '' });
    

    Adds a new menu title to the menu bar. Subsequent calls to addCustomItem(), registerValidator(), and registerAction() work the same way for custom menus as for built-in menus.

    gMenuAPI.addCustomTopLevelMenu({
    menuTitleId: 'menutitle-myapp',
    label: 'My App',
    items: [
    { title: 'Settings', shortcut: '' },
    { title: '---', shortcut: '' },
    { title: 'About', shortcut: '' }
    ]
    });

    Item IDs for the above example:

    • menutitle-myapp_Settings
    • menutitle-myapp_About

    A validator is called each time the menu opens, just before the item is rendered. It determines whether the item appears enabled (clickable) or disabled (greyed out).

    Registers a validator for an item.

    // Always enabled
    gMenuAPI.registerValidator('menutitle-file_Publish_to_CMS', () => true);

    // Enabled only when a condition is met
    gMenuAPI.registerValidator('menutitle-file_Publish_to_CMS', () => {
    return myApp.isDocumentSaved();
    });

    // Defer to the editor's built-in logic (no-op validator)
    gMenuAPI.registerValidator('menutitle-edit_Undo', () => null);

    For built-in items a registered validator replaces the editor's built-in enabled/disabled logic. Return null to defer back to the editor.


    Removes a previously registered validator. The editor's built-in logic resumes.

    gMenuAPI.unregisterValidator('menutitle-file_Publish_to_CMS');
    

    An action is called when the user clicks an enabled menu item.

    Registers an action for an item.

    // Handle a custom item
    gMenuAPI.registerAction('menutitle-file_Publish_to_CMS', (id) => {
    myApp.publish();
    return true; // handled; suppress any built-in action
    });

    // Intercept a built-in item — run before the editor's action
    gMenuAPI.registerAction('menutitle-file_Save', (id) => {
    myApp.onBeforeSave();
    return false; // also run the editor's built-in Save
    });

    // Replace a built-in item entirely
    gMenuAPI.registerAction('menutitle-file_New', (id) => {
    if (!myApp.confirmDiscard()) return true; // cancelled; suppress built-in
    return false; // confirmed; run built-in
    });

    Removes a previously registered action. The editor's built-in action resumes.

    gMenuAPI.unregisterAction('menutitle-file_Publish_to_CMS');
    

    document.addEventListener('typograph_editor_ready', () => {

    // --- Customize the File menu ---

    // Remove items that are not relevant in this integration
    gMenuAPI.hideItem('menutitle-file_Save_as_Template');
    gMenuAPI.hideItem('menutitle-file_Save_as_Clip');

    // Add a Publish item after "Save as…"
    gMenuAPI.addCustomItem(
    'menutitle-file',
    { title: 'Publish_to_CMS', shortcut: '' },
    { after: 'menutitle-file_Save_as' }
    );
    gMenuAPI.registerValidator('menutitle-file_Publish_to_CMS',
    () => myApp.canPublish()
    );
    gMenuAPI.registerAction('menutitle-file_Publish_to_CMS', () => {
    myApp.publish();
    return true;
    });

    // Intercept New — ask for confirmation first
    gMenuAPI.registerAction('menutitle-file_New', () => {
    if (!confirm('Discard the current document?')) return true;
    return false; // run built-in new-document flow
    });

    // --- Hide the Help menu ---
    gMenuAPI.hideMenu('menutitle-help');

    // --- Add a custom top-level menu ---
    gMenuAPI.addCustomTopLevelMenu({
    menuTitleId: 'menutitle-myapp',
    label: 'My App',
    items: [
    { title: 'Preferences', shortcut: '' },
    { title: '---', shortcut: '' },
    { title: 'About', shortcut: '' }
    ]
    });

    gMenuAPI.registerValidator('menutitle-myapp_Preferences', () => true);
    gMenuAPI.registerAction('menutitle-myapp_Preferences', () => {
    myApp.openPreferences();
    return true;
    });

    gMenuAPI.registerValidator('menutitle-myapp_About', () => true);
    gMenuAPI.registerAction('menutitle-myapp_About', () => {
    myApp.showAbout();
    return true;
    });
    });

    If no validator is registered for an item, the editor's built-in logic runs. Built-in logic returns false for any item ID it does not recognise, so custom items will be greyed out and non-clickable until you call registerValidator().

    The Action API intercepts menu item clicks. If a built-in item also has a keyboard shortcut (e.g. ⌘S for Save), the shortcut invokes the built-in action directly and does not go through a registered action callback. Validator callbacks are also not called on keyboard invocations.

    Some View menu items change their label depending on document state, e.g. the same item alternates between Show Rulers and Hide Rulers. Both labels produce different item IDs:

    • menutitle-view_Show_Rulers
    • menutitle-view_Hide_Rulers

    To hide this item in all states, call hideItem() for both IDs. The same applies for Show_Guides / Hide_Guides and Show_Frames / Hide_Frames.

    Choose a prefix that identifies your integration to avoid collisions with built-in IDs and with other integrations, for example menutitle-mycompany.


    Label Item ID
    New menutitle-file_New
    Open menutitle-file_Open
    Open locale… menutitle-file_Open_locale
    Save menutitle-file_Save
    Save as… menutitle-file_Save_as
    Save as Template menutitle-file_Save_as_Template
    Save as Clip menutitle-file_Save_as_Clip
    Label Item ID
    Undo menutitle-edit_Undo
    Redo menutitle-edit_Redo
    Cut menutitle-edit_Cut
    Copy menutitle-edit_Copy
    Paste menutitle-edit_Paste
    Delete menutitle-edit_Delete
    Step and Repeat… menutitle-edit_Step_and_Repeat
    Label Item ID
    All menutitle-select_All
    All Shapes menutitle-select_All_Shapes
    All Images menutitle-select_All_Images
    All Text menutitle-select_All_Text
    Convert to Line menutitle-select_Convert_to_Line
    Convert to Rect menutitle-select_Convert_to_Rect
    Convert to Rounded Rect menutitle-select_Convert_to_Rounded_Rect
    Convert to Circle menutitle-select_Convert_to_Circel
    Convert to Image menutitle-select_Convert_to_Image
    Convert to Text menutitle-select_Convert_to_Text
    Convert to Path menutitle-select_Convert_to_Path
    Label Item ID
    Zoom In menutitle-view_Zoom_In
    Zoom Out menutitle-view_Zoom_Out
    Fit Page in Window menutitle-view_Fit_Page_in_Window
    Actual Size menutitle-view_Actual_Size
    Show / Hide Rulers menutitle-view_Show_Rulers / menutitle-view_Hide_Rulers
    Show / Hide Guides menutitle-view_Show_Guides / menutitle-view_Hide_Guides
    Show / Hide Frames menutitle-view_Show_Frames / menutitle-view_Hide_Frames
    Show / Hide Tab Ruler menutitle-view_Show_Tab_Ruler / menutitle-view_Hide_Tab_Ruler
    Label Item ID
    New Page menutitle-page_New_Page
    Duplicate Page menutitle-page_Duplicate_Page
    Delete Page menutitle-page_Delete_Page
    Scale… menutitle-page_Scale
    Split spread menutitle-page_Split_spread
    Label Item ID
    Bring to Front menutitle-arrange_Bring_to_Front
    Send to Back menutitle-arrange_Send_to_Back
    Bring Forward menutitle-arrange_Bring_Forward
    Send Backward menutitle-arrange_Send_Backward
    Group menutitle-arrange_Group
    Ungroup menutitle-arrange_Ungroup
    Label Item ID
    Rectangle menutitle-insert_Rectangle
    Rounded Rectangle menutitle-insert_Rounded_Rectange
    Text Box menutitle-insert_Text_Box
    Table menutitle-insert_Table
    Smart Fields… menutitle-insert_Smart_Fields
    Fill with Placeholder Text menutitle-insert_Fill_with_Placeholder_Text
    Add Autolayout… menutitle-insert_Add_Autolayout
    Add Autosize… menutitle-insert_Add_Autosize
    Add Text variable… menutitle-insert_Add_Text_variable
    Add Image placeholder… menutitle-insert_Add_Image_placeholder
    Label Item ID
    Help Center menutitle-help_Help_Center
    Contact Support menutitle-help_Contact_Support
    Request Feature menutitle-help_Request_Feature
    Report a Bug menutitle-help_Report_a_Bug

    This document covers the public Menu API. For questions or integration support, contact the Typograph team.