or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdkey-checking.mdkey-recording.mdmain-hook.mdscope-management.md

main-hook.mddocs/

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

```