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;
hideMenu(menuTitleId: string): voidRemoves 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');
showMenu(menuTitleId: string): voidRestores a previously hidden menu title to the menu bar.
gMenuAPI.showMenu('menutitle-help');
hideItem(itemId: string): voidPrevents 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');
showItem(itemId: string): voidRestores a previously hidden menu item.
gMenuAPI.showItem('menutitle-file_Save_as_Template');
addCustomItem(menuTitleId, descriptor, position?): voidAdds 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
truefor the item to be clickable.
SeeregisterValidator().
Adding a separator
Use '---' as the title to insert a separator line:
gMenuAPI.addCustomItem('menutitle-file', { title: '---', shortcut: '' });
addCustomTopLevelMenu(descriptor): voidAdds 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_Settingsmenutitle-myapp_AboutA 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).
registerValidator(itemId, fn: MenuValidator): voidRegisters 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.
unregisterValidator(itemId: string): voidRemoves 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.
registerAction(itemId, fn: MenuAction): voidRegisters 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
});
unregisterAction(itemId: string): voidRemoves 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_Rulersmenutitle-view_Hide_RulersTo 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.
menutitle-file)| 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 |
menutitle-edit)| 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 |
menutitle-select)| 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 |
menutitle-view)| 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 |
menutitle-page)| 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 |
menutitle-arrange)| 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 |
menutitle-insert)| 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 |
menutitle-help)| 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.