React hook for handling keyboard shortcuts in components in a declarative way
npx @tessl/cli install tessl/npm-react-hotkeys-hook@5.1.0React Hotkeys Hook is a React hook library for handling keyboard shortcuts in components in a declarative way. It enables developers to easily bind keyboard combinations (like ctrl+k, meta+s) to callback functions within React components, supporting advanced features like scopes for grouping hotkeys, focus trapping to limit hotkeys to specific elements, configurable behavior for form elements and content-editable areas, flexible options for keyup/keydown event handling, and key sequence support for vi-style command patterns.
npm install react-hotkeys-hookimport { useHotkeys, HotkeysProvider, useHotkeysContext, isHotkeyPressed, useRecordHotkeys } from "react-hotkeys-hook";For CommonJS:
const { useHotkeys, HotkeysProvider, useHotkeysContext, isHotkeyPressed, useRecordHotkeys } = require("react-hotkeys-hook");import { useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
export const ExampleComponent = () => {
const [count, setCount] = useState(0);
// Basic hotkey binding
useHotkeys('ctrl+k', () => setCount(count + 1), [count]);
// Multiple key combinations for cross-platform support
useHotkeys(['ctrl+s', 'cmd+s'], () => console.log('Save'));
// Key sequences (vi-style)
useHotkeys('g>i', () => console.log('Go to inbox'));
return (
<p>
Pressed {count} times. Try Ctrl+K, Ctrl/Cmd+S, or g>i
</p>
);
};React Hotkeys Hook is built around several key components:
useHotkeys): Primary hook for binding keyboard shortcuts to callbacks with extensive configuration optionsHotkeysProvider component and useHotkeysContext hook for organizing hotkeys into groups and controlling their active stateuseRecordHotkeys hook for capturing keyboard input to discover key combinationsisHotkeyPressed utility for checking if keys are currently pressedPrimary hook for binding keyboard shortcuts to callback functions with extensive customization options including scopes, focus trapping, form element handling, and event lifecycle control.
function useHotkeys<T extends HTMLElement>(
keys: Keys,
callback: HotkeyCallback,
options?: OptionsOrDependencyArray,
dependencies?: OptionsOrDependencyArray
): React.RefObject<T>;
type Keys = string | readonly string[];
type HotkeyCallback = (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => void;
type OptionsOrDependencyArray = Options | DependencyList;Context-based system for organizing hotkeys into groups and controlling their active state across an application, enabling complex hotkey hierarchies and conditional activation.
function HotkeysProvider({
initiallyActiveScopes,
children
}: {
initiallyActiveScopes?: string[];
children: ReactNode;
}): JSX.Element;
function useHotkeysContext(): HotkeysContextType;
interface HotkeysContextType {
hotkeys: ReadonlyArray<Hotkey>;
activeScopes: string[];
toggleScope: (scope: string) => void;
enableScope: (scope: string) => void;
disableScope: (scope: string) => void;
}Hook for recording keyboard input to discover key combinations, useful for hotkey configuration interfaces and debugging.
function useRecordHotkeys(useKey?: boolean): [
Set<string>,
{
start: () => void;
stop: () => void;
resetKeys: () => void;
isRecording: boolean;
}
];Utility function for checking if specified keys are currently pressed, enabling conditional logic based on keyboard state.
function isHotkeyPressed(key: string | readonly string[], delimiter?: string): boolean;import type { RefObject, DependencyList, ReactNode } from 'react';
type Keys = string | readonly string[];
type HotkeyCallback = (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => void;
type OptionsOrDependencyArray = Options | DependencyList;
interface Options {
enabled?: Trigger;
enableOnFormTags?: readonly FormTags[] | boolean;
enableOnContentEditable?: boolean;
ignoreEventWhen?: (e: KeyboardEvent) => boolean;
splitKey?: string;
delimiter?: string;
scopes?: Scopes;
keyup?: boolean;
keydown?: boolean;
preventDefault?: Trigger;
description?: string;
document?: Document;
ignoreModifiers?: boolean;
eventListenerOptions?: EventListenerOptions;
useKey?: boolean;
sequenceTimeoutMs?: number;
sequenceSplitKey?: string;
}
interface Hotkey extends KeyboardModifiers {
keys?: readonly string[];
scopes?: Scopes;
description?: string;
isSequence?: boolean;
}
interface KeyboardModifiers {
alt?: boolean;
ctrl?: boolean;
meta?: boolean;
shift?: boolean;
mod?: boolean;
useKey?: boolean;
}
type Trigger = boolean | ((keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean);
type Scopes = string | readonly string[];
type FormTags = 'input' | 'textarea' | 'select' | 'INPUT' | 'TEXTAREA' | 'SELECT';
type HotkeysEvent = Hotkey;
type EventListenerOptions =
| {
capture?: boolean;
once?: boolean;
passive?: boolean;
signal?: AbortSignal;
}
| boolean; // useCapture