React Quick Start
This guide shows how to use @keekuun/keymaster-react to register keyboard shortcuts in React projects, with basic examples.
Installation
💡 Version Notice: The documentation shows the latest version (v0.5.0). If you need a specific version, check the Version Management documentation or all versions on npm.
Install Latest Version
npm install @keekuun/keymaster-react
# or
pnpm add @keekuun/keymaster-reactInstall Specific Version
If you need a specific version (e.g., 0.1.0), specify the version:
npm install @keekuun/keymaster-react@0.1.0
# or
pnpm add @keekuun/keymaster-react@0.1.0⚠️ Note: If using an older version, some APIs in the documentation may not be available. Check the README for that version (on the npm package page) or the Version Management documentation.
Basic Example: Save Shortcut Ctrl+S
The following example shows how to bind save logic to Ctrl+S in an editor component:
import React from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';
function Editor() {
useKeyBinding(
'ctrl+s',
() => {
// Execute save logic here, e.g., call API / update local state
console.log('Saved successfully');
},
{ preventDefault: true }, // Prevent browser's default save page behavior
);
return <textarea placeholder="Type here, then press Ctrl+S to save"></textarea>;
}
export default Editor;To verify the behavior in your application, simply mount the Editor component to the page, then press Ctrl+S in the browser to observe the console output or whether your actual save logic is triggered.
Try it out:
Multiple Shortcuts
You can also call useKeyBinding multiple times in the same component to bind different behaviors to different shortcuts:
import React from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';
function Editor() {
useKeyBinding(
'ctrl+s',
() => {
saveContent();
},
{ preventDefault: true },
);
useKeyBinding('ctrl+z', () => {
undo();
});
useKeyBinding('ctrl+shift+z', () => {
redo();
});
return <textarea />;
}Interactive Demo:
Advanced APIs
Scoped Shortcuts (scopedElement)
When you need to bind shortcuts within a specific element scope (e.g., editors, dialogs), you can use the scopedElement option:
import React, { useRef } from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';
function Editor() {
const editorRef = useRef<HTMLTextAreaElement>(null);
// Only works within the editor area
useKeyBinding(
'ctrl+s',
() => {
console.log('Save editor content');
},
{
scopedElement: editorRef.current,
preventDefault: true,
},
);
return <textarea ref={editorRef} placeholder="Press Ctrl+S to save" />;
}Or use the convenient useScopedKeyBinding Hook:
import { useScopedKeyBinding } from '@keekuun/keymaster-react';
const containerRef = useRef<HTMLDivElement>(null);
useScopedKeyBinding(
'ctrl+k',
() => {
console.log('Only works within container');
},
containerRef,
);Interactive Demo:
Editor Mode
Editor mode automatically handles common shortcut conflicts, especially suitable for code editors, rich text editors, and similar scenarios:
import { useEditorKeyBinding } from '@keekuun/keymaster-react';
function CodeEditor() {
const editorRef = useRef<HTMLTextAreaElement>(null);
// Editor mode automatically prevents default behavior
useEditorKeyBinding(
'ctrl+s',
() => {
saveCode();
},
editorRef.current,
);
useEditorKeyBinding(
'ctrl+z',
() => {
undo();
},
editorRef.current,
);
return <textarea ref={editorRef} />;
}Interactive Demo:
Electron Mode
In Electron applications, you can use useElectronKeyBinding to adapt shortcut coordination between the main process and renderer process:
import { useElectronKeyBinding } from '@keekuun/keymaster-react';
function ElectronApp() {
useElectronKeyBinding(
'ctrl+alt+r',
() => {
// Your Electron logic here, e.g. via bridge / ipc
window.electron?.ipcRenderer?.send('shortcut:reload');
},
{
electronHook: ({ parsed, processInfo, versions }) => {
console.log('[electron shortcut]', parsed, processInfo, versions);
// return false here if you want to stop further handling
return true;
},
},
);
return <div>Electron App</div>;
}Electron Hook (electronHook)
When using Electron mode, you can optionally provide an electronHook to collect environment information or intercept handling:
useElectronKeyBinding('ctrl+alt+r', handler, {
electronHook: ({ event, parsed, processInfo, versions }) => {
// custom logging / monitoring
if (!versions?.electron) return false; // cancel handling if environment is unexpected
return true;
},
});Interactive Demo:
Electron Mode Demo
Electron mode adapts to desktop application scenarios, allowing you to extend or intercept Electron-specific behaviors via electronHook.
Current Environment:Browser Environment (Demo Only)
Try these shortcuts (will trigger hook in Electron environment):
Last triggered:None
Shortcut Combination Management
Use KeyBindingManager to manage a group of related shortcut bindings:
import { useEffect } from 'react';
import { createKeyBindingManager, isValidShortcut, formatShortcut } from '@keekuun/keymaster-react';
function Editor() {
useEffect(() => {
const manager = createKeyBindingManager();
// Chain register multiple shortcuts
manager
.register('ctrl+s', () => save(), { preventDefault: true })
.register('ctrl+z', () => undo())
.register('ctrl+shift+z', () => redo());
// Automatically clean up all bindings when component unmounts
return () => manager.dispose();
}, []);
return <textarea />;
}Utility functions:
isValidShortcut(shortcut): Check if shortcut format is validformatShortcut(shortcut): Format shortcut string (normalize case)
Interactive Demo:
API Overview
useKeyBinding(shortcut, handler, options?)
shortcut:string- Shortcut string, e.g.,"ctrl+s","ctrl+shift+z"handler:(event: KeyboardEvent) => void- Callback triggered when matching shortcut is detectedoptions:KeymasterBindingOptions(optional)preventDefault?: boolean- Whether to callevent.preventDefault()after triggerstopPropagation?: boolean- Whether to callevent.stopPropagation()after triggerscopedElement?: HTMLElement | null- Scoped element, shortcut only works within elementeditorMode?: boolean- Editor mode, automatically handles shortcut conflictselectronMode?: boolean- Electron mode, adapts for Electron applications