Custom Keyboard Shortcuts
useOnKeyboardEvents binds your own keyboard shortcuts to a diagram. The standard editor shortcuts (delete, select-all, copy, cut, paste, undo, and redo) already come from the diagram's built-in interactions, listed in The Diagram Component. Use this hook when your app needs shortcuts beyond those defaults.
A complete example
Click a card to select it, then nudge it with the arrow keys or cycle its priority with P. Toggle Built-in shortcuts in the panel to switch the defaults on and off; the custom shortcuts keep working either way.
Registering shortcuts
useOnKeyboardEvents takes one argument: a record that maps shortcut strings to handler functions. Each handler receives the keyboard event when its shortcut fires.
import { useOnKeyboardEvents } from '@joint/react-plus';
function Shortcuts() {
useOnKeyboardEvents({
enter: () => submit(),
'ctrl+s command+s': (event) => {
event.preventDefault();
save();
},
});
return null;
}
Call the hook from a component rendered inside a <Diagram>. It throws when there is no diagram ancestor.
While the user is typing in a form field (an input, select, textarea, or contentEditable element), the diagram keyboard stays quiet, so none of your shortcuts fire there. This guard is built in and you cannot turn it off from React.
Shortcut syntax
Shortcut strings accept a few forms:
- single keys, such as
enter,escape, orup - combinations with modifiers, such as
ctrl+sorctrl+alt+t - several shortcuts on one handler, separated by spaces, such as
up down left right - a specific event type with a prefix, such as
keydown:aorkeyup:escape
To cover both platforms with one handler, list the Windows and macOS variants together, for example ctrl+c command+c.
useOnKeyboardEvents({
enter: onConfirm, // single key
'ctrl+alt+t': openTools, // modifier combination
'up down left right': onArrowKey, // several shortcuts, one handler
'keyup:escape': onCancel, // a specific event type
'ctrl+c command+c': onCopy, // Windows and macOS together
});
Handlers stay current
The subscription is set up once and reads the latest handler each time a shortcut fires, so an inline record is fine and needs no useMemo or useCallback. The hook only re-subscribes when the set of shortcut strings changes, not when a handler function changes.
Preventing browser defaults
When you bind a key the browser already claims, such as ctrl+s or ctrl+p, call event.preventDefault() inside the handler so the browser action does not run alongside yours.
useOnKeyboardEvents({
'ctrl+s command+s': (event) => {
event.preventDefault();
save();
},
});
Custom and built-in shortcuts share one keyboard
Custom shortcuts and the built-in ones run on the same diagram keyboard, so they coexist without extra setup. The example shows this: turning the built-in shortcuts off leaves the arrow keys and P working.
To bind a key that a default already uses, switch off the matching built-in first so the two do not both fire. The interactions prop controls this: interactions={{ commandManager: false }} frees the undo and redo chords, interactions={{ clipboard: false }} frees copy, cut, and paste, and interactions={{ selection: false }} frees Delete, Backspace, Escape, and Ctrl/Cmd+A (this one also turns off click and drag selection, since selection has no shortcut-only flag). To clear them all at once, interactions={{ keyboard: false }} turns off every built-in shortcut. See The Diagram Component for the full set of flags.
Where shortcuts come from
useOnKeyboardEvents is for the shortcuts your app defines. The built-in editor shortcuts are listed in The Diagram Component, and each feature also documents its own: Selection, Undo & Redo, and Copy & Paste.