JAVASCRIPT
Implement Global Keyboard Shortcuts with `useKeyboardShortcut`
Create a `useKeyboardShortcut` React hook to easily define and manage global keyboard combinations, enhancing user experience with efficient keyboard navigation and quick actions.
import { useEffect, useRef, useCallback } from 'react';
const useKeyboardShortcut = (keys, callback, options = {}) => {
const { event = 'keydown', target = document, preventDefault = true } = options;
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback; // Update callback if it changes
}, [callback]);
const handleKeyPress = useCallback((event) => {
// Check if all specified keys are pressed
const allKeysPressed = keys.every(key => {
if (key === 'control' || key === 'ctrl') return event.ctrlKey;
if (key === 'shift') return event.shiftKey;
if (key === 'alt') return event.altKey;
if (key === 'meta') return event.metaKey; // Command key on Mac, Windows key on Windows
return event.key.toLowerCase() === key.toLowerCase();
});
if (allKeysPressed) {
if (preventDefault) {
event.preventDefault();
}
callbackRef.current(event);
}
}, [keys, preventDefault, event, target]); // Re-run if keys or options change
useEffect(() => {
if (target && target.addEventListener) {
target.addEventListener(event, handleKeyPress);
return () => {
target.removeEventListener(event, handleKeyPress);
};
}
}, [target, event, handleKeyPress]);
};
// Example Usage:
// function MyShortcutComponent() {
// useKeyboardShortcut(['shift', 's'], () => alert('Shift + S pressed!'), { preventDefault: true });
// useKeyboardShortcut(['escape'], () => console.log('Escape pressed!'), { event: 'keyup' });
//
// return (
// <div>
// Press Shift + S to see an alert.
// Check console for Escape key (on keyup).
// </div>
// );
// }
How it works: The `useKeyboardShortcut` hook simplifies the process of attaching event listeners for specific key combinations. It accepts an array of `keys` (e.g., `['control', 'c']`), a `callback` function, and optional `options` like the `event` type (`keydown` or `keyup`), `target` element (defaults to `document`), and `preventDefault` behavior. The hook efficiently manages event listeners, ensuring they are added and removed correctly, and updates the callback dynamically using `useRef` to prevent stale closures.