0
# Main Hotkey Hook
1
2
The primary hook for binding keyboard shortcuts to callback functions with extensive customization options including scopes, focus trapping, form element handling, and event lifecycle control.
3
4
## Capabilities
5
6
### useHotkeys Hook
7
8
The main hook for handling keyboard shortcuts in React components.
9
10
```typescript { .api }
11
/**
12
* Hook for binding keyboard shortcuts to callback functions
13
* @param keys - Key or array of keys to listen for (e.g., 'ctrl+k', ['ctrl+k', 'cmd+k'])
14
* @param callback - Function called when hotkey is triggered
15
* @param options - Configuration options or dependency array
16
* @param dependencies - Dependency array for callback memoization (if options is used for configuration)
17
* @returns RefObject for optional focus trapping
18
*/
19
function useHotkeys<T extends HTMLElement>(
20
keys: Keys,
21
callback: HotkeyCallback,
22
options?: OptionsOrDependencyArray,
23
dependencies?: OptionsOrDependencyArray
24
): React.RefObject<T>;
25
26
type Keys = string | readonly string[];
27
type HotkeyCallback = (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => void;
28
type OptionsOrDependencyArray = Options | DependencyList;
29
```
30
31
**Usage Examples:**
32
33
```typescript
34
import { useHotkeys } from 'react-hotkeys-hook';
35
36
// Basic usage with dependency array
37
const [count, setCount] = useState(0);
38
useHotkeys('ctrl+k', () => setCount(c => c + 1), [count]);
39
40
// Multiple key combinations
41
useHotkeys(['ctrl+k', 'cmd+k'], () => console.log('Works on both platforms'));
42
43
// With options object
44
useHotkeys('enter', handleSubmit, {
45
enabled: isFormValid,
46
enableOnFormTags: ['input', 'textarea'],
47
preventDefault: true
48
});
49
50
// Focus trapping with ref
51
const ref = useHotkeys<HTMLDivElement>('escape', handleClose);
52
return <div ref={ref} tabIndex={-1}>Content</div>;
53
54
// Key sequences
55
useHotkeys('g>i', () => console.log('Vi-style sequence'), {
56
sequenceTimeoutMs: 2000
57
});
58
```
59
60
## Configuration Options
61
62
### Options Interface
63
64
Complete configuration object for customizing hotkey behavior.
65
66
```typescript { .api }
67
interface Options {
68
/** Enable/disable hotkey conditionally (default: true) */
69
enabled?: Trigger;
70
/** Enable hotkeys on form tags (default: false) */
71
enableOnFormTags?: readonly FormTags[] | boolean;
72
/** Enable hotkeys on contentEditable elements (default: false) */
73
enableOnContentEditable?: boolean;
74
/** Ignore events based on condition (default: undefined) */
75
ignoreEventWhen?: (e: KeyboardEvent) => boolean;
76
/** Character to split keys in combinations (default: '+') */
77
splitKey?: string;
78
/** Character to separate different hotkeys (default: ',') */
79
delimiter?: string;
80
/** Scope restriction for hotkey (default: undefined) */
81
scopes?: Scopes;
82
/** Trigger on keyup event (default: undefined) */
83
keyup?: boolean;
84
/** Trigger on keydown event (default: true) */
85
keydown?: boolean;
86
/** Prevent default browser behavior (default: false) */
87
preventDefault?: Trigger;
88
/** Description for documentation (default: undefined) */
89
description?: string;
90
/** Custom document to listen on (default: false) */
91
document?: Document;
92
/** Ignore modifiers when matching (default: false) */
93
ignoreModifiers?: boolean;
94
/** Event listener options (default: undefined) */
95
eventListenerOptions?: EventListenerOptions;
96
/** Use key instead of code for matching (default: false) */
97
useKey?: boolean;
98
/** Timeout for key sequences (default: 1000ms) */
99
sequenceTimeoutMs?: number;
100
/** Character for key sequences (default: '>') */
101
sequenceSplitKey?: string;
102
}
103
104
type Trigger = boolean | ((keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean);
105
type Scopes = string | readonly string[];
106
type FormTags = 'input' | 'textarea' | 'select' | 'INPUT' | 'TEXTAREA' | 'SELECT';
107
```
108
109
**Configuration Examples:**
110
111
```typescript
112
// Conditional enabling
113
useHotkeys('ctrl+s', handleSave, {
114
enabled: isDirty && !isSaving,
115
preventDefault: true
116
});
117
118
// Function-based enabling
119
useHotkeys('delete', handleDelete, {
120
enabled: (e, hotkey) => selectedItems.length > 0,
121
preventDefault: (e, hotkey) => e.target.tagName !== 'INPUT'
122
});
123
124
// Form element handling
125
useHotkeys('enter', handleSubmit, {
126
enableOnFormTags: ['input', 'textarea'],
127
enableOnContentEditable: true
128
});
129
130
// Scope-based organization
131
useHotkeys('ctrl+n', createNew, {
132
scopes: ['editor', 'global']
133
});
134
135
// Custom event options
136
useHotkeys('ctrl+z', handleUndo, {
137
eventListenerOptions: { passive: false },
138
keyup: true,
139
keydown: false
140
});
141
```
142
143
## Advanced Features
144
145
### Key Sequences
146
147
Support for multi-key sequences like vi-style commands.
148
149
```typescript
150
// Vi-style navigation
151
useHotkeys('g>g', () => scrollToTop(), {
152
sequenceTimeoutMs: 1500,
153
sequenceSplitKey: '>'
154
});
155
156
// Complex sequences
157
useHotkeys('ctrl+k>ctrl+c', () => openCommandPalette(), {
158
description: 'Open command palette'
159
});
160
```
161
162
### Focus Trapping
163
164
Limit hotkeys to specific elements using refs.
165
166
```typescript
167
const modalRef = useHotkeys<HTMLDivElement>('escape', closeModal);
168
169
return (
170
<div ref={modalRef} tabIndex={-1} className="modal">
171
{/* Escape key only works when this element or its children are focused */}
172
</div>
173
);
174
```
175
176
### Event Lifecycle Control
177
178
Fine-grained control over when hotkeys trigger.
179
180
```typescript
181
// Only on keyup
182
useHotkeys('space', handlePause, {
183
keyup: true,
184
keydown: false
185
});
186
187
// Both keyup and keydown
188
useHotkeys('shift', handleToggle, {
189
keyup: true,
190
keydown: true
191
});
192
```
193
194
## Types
195
196
### Callback and Event Types
197
198
```typescript { .api }
199
type HotkeyCallback = (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => void;
200
201
interface HotkeysEvent extends KeyboardModifiers {
202
keys?: readonly string[];
203
scopes?: Scopes;
204
description?: string;
205
isSequence?: boolean;
206
}
207
208
interface KeyboardModifiers {
209
alt?: boolean;
210
ctrl?: boolean;
211
meta?: boolean;
212
shift?: boolean;
213
mod?: boolean;
214
useKey?: boolean;
215
}
216
```
217
218
### Event Listener Options
219
220
```typescript { .api }
221
type EventListenerOptions =
222
| {
223
capture?: boolean;
224
once?: boolean;
225
passive?: boolean;
226
signal?: AbortSignal;
227
}
228
| boolean; // useCapture
229
```