Keyboard shortcuts in MenuBar
MenuBar displays a shortcut hint next to each menu item, but the framework does not automatically wire that hint to a key handler. You provide the handler yourself.
Goal
Wire Ctrl+N, Ctrl+O, Ctrl+S to menu actions, with the hints visible in the menu and a single keyboard handler at the document level.
Centralise the action map
Pulling the actions into a small map lets you reference them from both the menu config and the key handler:
const actions = {
new: () => newDoc(),
open: () => openDoc(),
save: () => save(),
};Build the menu
import { Body } from '@jimka/typescript-ui/core';
import { MenuBar } from '@jimka/typescript-ui/component/menubar';
const bar = MenuBar([
{ label: 'File', items: [
{ text: 'New', shortcut: 'Ctrl+N', action: actions.new },
{ text: 'Open', shortcut: 'Ctrl+O', action: actions.open },
{ separator: true },
{ text: 'Save', shortcut: 'Ctrl+S', action: actions.save },
]},
]);
Body.getInstance().addComponent(bar);Wire the keyboard handler
Use a single keydown listener at the document level. Match the modifier set explicitly so combinations like Ctrl+Shift+N don't accidentally trigger Ctrl+N:
function onlyCtrl(e: KeyboardEvent): boolean {
return (e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey;
}
window.addEventListener('keydown', (e: KeyboardEvent) => {
if (!onlyCtrl(e)) return;
switch (e.key.toLowerCase()) {
case 'n': e.preventDefault(); actions.new(); break;
case 'o': e.preventDefault(); actions.open(); break;
case 's': e.preventDefault(); actions.save(); break;
}
});metaKey covers macOS ⌘. The e.preventDefault() call stops the browser's default behaviour (e.g. Ctrl+S opening the page-save dialog).
Larger apps
For more than a handful of shortcuts, consider:
- A registry that the menu config and the key handler both read from — keeps shortcut text and key handler in lockstep.
- Scope-aware bindings — e.g. only fire
Ctrl+Swhen a particular panel has focus.
The framework intentionally stays out of this; the shortcut field is just a label.