typescriptbeginner
useKeyboardShortcut Hook
Register global keyboard shortcuts with modifier keys, preventing defaults, and cleanup on unmount.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useEffect, useCallback } from 'react';
type ModifierKey = 'ctrl' | 'alt' | 'shift' | 'meta';
interface ShortcutOptions {
key: string;
modifiers?: ModifierKey[];
preventDefault?: boolean;
enabled?: boolean;
}
function useKeyboardShortcut(
options: ShortcutOptions,
callback: (e: KeyboardEvent) => void,
) {
const {
key,
modifiers = [],
preventDefault = true,
enabled = true,
} = options;
const handler = useCallback(
(e: KeyboardEvent) => {
if (!enabled) return;
const modMatch =
(!modifiers.includes('ctrl') || e.ctrlKey || e.metaKey) &&
(!modifiers.includes('meta') || e.metaKey) &&
(!modifiers.includes('alt') || e.altKey) &&
(!modifiers.includes('shift') || e.shiftKey);
if (e.key.toLowerCase() === key.toLowerCase() && modMatch) {
if (preventDefault) e.preventDefault();
callback(e);
}
},
[key, modifiers, preventDefault, enabled, callback],
);
useEffect(() => {
if (!enabled) return;
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, [handler, enabled]);
}
// Usage Example
function App() {
useKeyboardShortcut(
{ key: 'k', modifiers: ['ctrl'] },
() => console.log('Open search'),
);
useKeyboardShortcut(
{ key: 's', modifiers: ['ctrl'] },
() => console.log('Save'),
);
useKeyboardShortcut(
{ key: 'Escape' },
() => console.log('Close modal'),
);
return <div>Press Ctrl+K to search, Ctrl+S to save</div>;
}
export { useKeyboardShortcut };Use Cases
- Command palette shortcuts
- Save/undo keyboard commands
- Modal dismiss with Escape
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptbeginner
usePrevious Hook
Track the previous value of any state or prop using a ref-based hook for comparison logic.
Best for: Detecting value changes
#hooks#state
typescriptintermediate
React Custom Hook for Data Fetching
A reusable useFetch hook with loading states, error handling, caching, and abort support.
Best for: Reusable data fetching across components
#react#hooks
typescriptintermediate
React Form Validation Hook
A type-safe form validation hook with field-level errors, dirty tracking, and submit handling.
Best for: Type-safe form handling without libraries
#react#forms
typescriptintermediate
React Portal Modal Component
Build an accessible modal dialog using React portals with focus trapping and keyboard handling.
Best for: Accessible modal dialogs with focus management
#react#portal