Skip to content

Commit 7328e36

Browse files
kadeangellautofix-ci[bot]KevinVandy
authored
feat: sequence-manager feature parody with hotkey-manager (#21)
* fix: add ignoreInputs support to SequenceManager and useHotkeySequence SequenceManager never checked the ignoreInputs option, so keyboard sequences like G+A and G+G would fire even when the user was typing in input, textarea, select, or contentEditable elements. Two issues were fixed: 1. SequenceManager (#handleKeyDown) now checks ignoreInputs before matching keys. A new #isInputElement() method mirrors the same logic from HotkeyManager. The ignoreInputs default is resolved at registration time using the first step of the sequence — Ctrl/Meta combos and Escape default to false (fire in inputs), while single keys and Shift/Alt combos default to true (ignored in inputs). 2. useHotkeySequence React hook was silently dropping the ignoreInputs option — it only forwarded timeout and platform to manager.register(). Now ignoreInputs is extracted, forwarded, and included in the effect dependency array. Added tests covering: single-key sequences ignored in input/textarea/ contentEditable by default, Mod sequences firing in inputs by default, explicit ignoreInputs: true/false overrides, and button-type inputs not being treated as text inputs. * changeset * changeset update: patch bump, not minor bump * ci: apply automated fixes * rewrite hotkey-sequence stuff * add sequences to devtools * update changeset * ci: apply automated fixes * fix solid target override fixes #34 --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Kevin Van Cott <kevinvandy656@gmail.com>
1 parent 37dc9c7 commit 7328e36

52 files changed

Lines changed: 3626 additions & 1689 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/red-pens-taste.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@tanstack/hotkeys': minor
3+
'@tanstack/react-hotkeys': minor
4+
'@tanstack/solid-hotkeys': minor
5+
'@tanstack/hotkeys-devtools': minor
6+
'@tanstack/solid-hotkeys-devtools': minor
7+
'@tanstack/react-hotkeys-devtools': minor
8+
---
9+
10+
feat: overhaul sequence-manager and hooks to be in feature parity with hotkey-manager.

docs/framework/react/reference/functions/useHotkeySequence.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function useHotkeySequence(
1212
options): void;
1313
```
1414

15-
Defined in: [useHotkeySequence.ts:50](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L50)
15+
Defined in: [useHotkeySequence.ts:61](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L61)
1616

1717
React hook for registering a keyboard shortcut sequence (Vim-style).
1818

docs/framework/react/reference/interfaces/UseHotkeySequenceOptions.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ title: UseHotkeySequenceOptions
55

66
# Interface: UseHotkeySequenceOptions
77

8-
Defined in: [useHotkeySequence.ts:10](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L10)
8+
Defined in: [useHotkeySequence.ts:12](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L12)
99

1010
## Extends
1111

12-
- `Omit`\<`SequenceOptions`, `"enabled"`\>
12+
- `Omit`\<`SequenceOptions`, `"target"`\>
1313

1414
## Properties
1515

16-
### enabled?
16+
### target?
1717

1818
```ts
19-
optional enabled: boolean;
19+
optional target:
20+
| HTMLElement
21+
| Document
22+
| Window
23+
| RefObject<HTMLElement | null>
24+
| null;
2025
```
2126

22-
Defined in: [useHotkeySequence.ts:15](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L15)
27+
Defined in: [useHotkeySequence.ts:21](https://github.com/TanStack/hotkeys/blob/main/packages/react-hotkeys/src/useHotkeySequence.ts#L21)
2328

24-
Whether the sequence is enabled. Defaults to true.
29+
The DOM element to attach the event listener to.
30+
Can be a React ref, direct DOM element, or null.
31+
Defaults to document.

docs/framework/solid/reference/functions/createHotkeySequence.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function createHotkeySequence(
1212
options): void;
1313
```
1414

15-
Defined in: [createHotkeySequence.ts:50](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L50)
15+
Defined in: [createHotkeySequence.ts:54](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L54)
1616

1717
SolidJS primitive for registering a keyboard shortcut sequence (Vim-style).
1818

docs/framework/solid/reference/interfaces/CreateHotkeySequenceOptions.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,21 @@ title: CreateHotkeySequenceOptions
55

66
# Interface: CreateHotkeySequenceOptions
77

8-
Defined in: [createHotkeySequence.ts:10](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L10)
8+
Defined in: [createHotkeySequence.ts:11](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L11)
99

1010
## Extends
1111

12-
- `Omit`\<`SequenceOptions`, `"enabled"`\>
12+
- `Omit`\<`SequenceOptions`, `"target"`\>
1313

1414
## Properties
1515

16-
### enabled?
16+
### target?
1717

1818
```ts
19-
optional enabled: boolean;
19+
optional target: HTMLElement | Document | Window | null;
2020
```
2121

22-
Defined in: [createHotkeySequence.ts:15](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L15)
22+
Defined in: [createHotkeySequence.ts:19](https://github.com/TanStack/hotkeys/blob/main/packages/solid-hotkeys/src/createHotkeySequence.ts#L19)
2323

24-
Whether the sequence is enabled. Defaults to true.
24+
The DOM element to attach the event listener to.
25+
Can be a direct DOM element, an accessor, or null. Defaults to document.

docs/reference/classes/HotkeyManager.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: HotkeyManager
55

66
# Class: HotkeyManager
77

8-
Defined in: [hotkey-manager.ts:166](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L166)
8+
Defined in: [hotkey-manager.ts:140](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L140)
99

1010
Singleton manager for hotkey registrations.
1111

@@ -34,7 +34,7 @@ unregister()
3434
readonly registrations: Store<Map<string, HotkeyRegistration>>;
3535
```
3636

37-
Defined in: [hotkey-manager.ts:188](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L188)
37+
Defined in: [hotkey-manager.ts:162](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L162)
3838

3939
The TanStack Store containing all hotkey registrations.
4040
Use this to subscribe to registration changes or access current registrations.
@@ -63,7 +63,7 @@ for (const [id, reg] of manager.registrations.state) {
6363
destroy(): void;
6464
```
6565

66-
Defined in: [hotkey-manager.ts:836](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L836)
66+
Defined in: [hotkey-manager.ts:698](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L698)
6767

6868
Destroys the manager and removes all listeners.
6969

@@ -79,7 +79,7 @@ Destroys the manager and removes all listeners.
7979
getRegistrationCount(): number;
8080
```
8181

82-
Defined in: [hotkey-manager.ts:807](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L807)
82+
Defined in: [hotkey-manager.ts:669](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L669)
8383

8484
Gets the number of registered hotkeys.
8585

@@ -95,7 +95,7 @@ Gets the number of registered hotkeys.
9595
isRegistered(hotkey, target?): boolean;
9696
```
9797
98-
Defined in: [hotkey-manager.ts:818](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L818)
98+
Defined in: [hotkey-manager.ts:680](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L680)
9999
100100
Checks if a specific hotkey is registered.
101101
@@ -111,7 +111,7 @@ The hotkey string to check
111111
112112
Optional target element to match (if provided, both hotkey and target must match)
113113
114-
`Document` | `Window` | `HTMLElement`
114+
`HTMLElement` | `Document` | `Window`
115115
116116
#### Returns
117117
@@ -130,7 +130,7 @@ register(
130130
options): HotkeyRegistrationHandle;
131131
```
132132
133-
Defined in: [hotkey-manager.ts:251](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L251)
133+
Defined in: [hotkey-manager.ts:225](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L225)
134134
135135
Registers a hotkey handler and returns a handle for updating the registration.
136136
@@ -186,7 +186,7 @@ handle.unregister()
186186
triggerRegistration(id): boolean;
187187
```
188188
189-
Defined in: [hotkey-manager.ts:771](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L771)
189+
Defined in: [hotkey-manager.ts:633](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L633)
190190
191191
Triggers a registration's callback programmatically from devtools.
192192
Creates a synthetic KeyboardEvent and invokes the callback.
@@ -213,7 +213,7 @@ True if the registration was found and triggered
213213
static getInstance(): HotkeyManager;
214214
```
215215
216-
Defined in: [hotkey-manager.ts:209](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L209)
216+
Defined in: [hotkey-manager.ts:183](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L183)
217217
218218
Gets the singleton instance of HotkeyManager.
219219
@@ -229,7 +229,7 @@ Gets the singleton instance of HotkeyManager.
229229
static resetInstance(): void;
230230
```
231231
232-
Defined in: [hotkey-manager.ts:219](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L219)
232+
Defined in: [hotkey-manager.ts:193](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/hotkey-manager.ts#L193)
233233
234234
Resets the singleton instance. Useful for testing.
235235

docs/reference/classes/SequenceManager.md

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,20 @@ title: SequenceManager
55

66
# Class: SequenceManager
77

8-
Defined in: [sequence.ts:79](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L79)
8+
Defined in: [sequence-manager.ts:148](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L148)
99

10-
Manages keyboard sequence matching for Vim-style shortcuts.
10+
## Properties
1111

12-
This class allows registering multi-key sequences like 'g g' or 'd d'
13-
that trigger callbacks when the full sequence is pressed within
14-
a configurable timeout.
15-
16-
## Example
12+
### registrations
1713

1814
```ts
19-
const matcher = SequenceManager.getInstance()
15+
readonly registrations: Store<Map<string, SequenceRegistrationView>>;
16+
```
2017

21-
// Register 'g g' to go to top
22-
const unregister = matcher.register(['G', 'G'], (event, context) => {
23-
scrollToTop()
24-
}, { timeout: 500 })
18+
Defined in: [sequence-manager.ts:155](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L155)
2519

26-
// Later, to unregister:
27-
unregister()
28-
```
20+
The TanStack Store containing sequence registration views for devtools.
21+
Subscribe to this to observe registration changes.
2922

3023
## Methods
3124

@@ -35,7 +28,7 @@ unregister()
3528
destroy(): void;
3629
```
3730

38-
Defined in: [sequence.ts:300](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L300)
31+
Defined in: [sequence-manager.ts:597](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L597)
3932

4033
Destroys the manager and removes all listeners.
4134

@@ -51,7 +44,7 @@ Destroys the manager and removes all listeners.
5144
getRegistrationCount(): number;
5245
```
5346

54-
Defined in: [sequence.ts:293](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L293)
47+
Defined in: [sequence-manager.ts:590](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L590)
5548

5649
Gets the number of registered sequences.
5750

@@ -67,10 +60,10 @@ Gets the number of registered sequences.
6760
register(
6861
sequence,
6962
callback,
70-
options): () => void;
63+
options): SequenceRegistrationHandle;
7164
```
7265

73-
Defined in: [sequence.ts:118](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L118)
66+
Defined in: [sequence-manager.ts:201](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L201)
7467

7568
Registers a hotkey sequence handler.
7669

@@ -96,31 +89,52 @@ Options for the sequence behavior
9689

9790
#### Returns
9891

99-
A function to unregister the sequence
92+
[`SequenceRegistrationHandle`](../interfaces/SequenceRegistrationHandle.md)
93+
94+
A handle to update or unregister the sequence
95+
96+
***
97+
98+
### resetAll()
10099

101100
```ts
102-
(): void;
101+
resetAll(): void;
103102
```
104103

105-
##### Returns
104+
Defined in: [sequence-manager.ts:532](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L532)
105+
106+
Resets all sequence progress.
107+
108+
#### Returns
106109

107110
`void`
108111

109112
***
110113

111-
### resetAll()
114+
### triggerSequence()
112115

113116
```ts
114-
resetAll(): void;
117+
triggerSequence(id): boolean;
115118
```
116119

117-
Defined in: [sequence.ts:283](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L283)
120+
Defined in: [sequence-manager.ts:546](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L546)
118121

119-
Resets all sequence progress.
122+
Triggers a sequence's callback programmatically from devtools.
123+
Creates a synthetic KeyboardEvent from the last key in the sequence.
124+
125+
#### Parameters
126+
127+
##### id
128+
129+
`string`
130+
131+
The registration ID to trigger
120132

121133
#### Returns
122134

123-
`void`
135+
`boolean`
136+
137+
True if the registration was found and triggered
124138

125139
***
126140

@@ -130,7 +144,7 @@ Resets all sequence progress.
130144
static getInstance(): SequenceManager;
131145
```
132146

133-
Defined in: [sequence.ts:93](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L93)
147+
Defined in: [sequence-manager.ts:176](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L176)
134148

135149
Gets the singleton instance of SequenceManager.
136150

@@ -146,7 +160,7 @@ Gets the singleton instance of SequenceManager.
146160
static resetInstance(): void;
147161
```
148162

149-
Defined in: [sequence.ts:103](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L103)
163+
Defined in: [sequence-manager.ts:186](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L186)
150164

151165
Resets the singleton instance. Useful for testing.
152166

docs/reference/functions/createSequenceMatcher.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ title: createSequenceMatcher
99
function createSequenceMatcher(sequence, options): object;
1010
```
1111

12-
Defined in: [sequence.ts:332](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence.ts#L332)
12+
Defined in: [sequence-manager.ts:636](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/sequence-manager.ts#L636)
1313

1414
Creates a simple sequence matcher for one-off use.
1515

16+
This is a low-level helper that does not support ignoreInputs, target,
17+
or other HotkeyOptions. Callers must handle input filtering themselves
18+
if attaching to document.
19+
1620
## Parameters
1721

1822
### sequence

docs/reference/functions/formatForDisplay.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: formatForDisplay
99
function formatForDisplay(hotkey, options): string;
1010
```
1111

12-
Defined in: [format.ts:61](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/format.ts#L61)
12+
Defined in: [format.ts:77](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/format.ts#L77)
1313

1414
Formats a hotkey for display in a user interface.
1515

docs/reference/functions/formatHotkey.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: formatHotkey
99
function formatHotkey(parsed): string;
1010
```
1111

12-
Defined in: [format.ts:23](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/format.ts#L23)
12+
Defined in: [format.ts:39](https://github.com/TanStack/hotkeys/blob/main/packages/hotkeys/src/format.ts#L39)
1313

1414
Converts a ParsedHotkey back to a hotkey string.
1515

0 commit comments

Comments
 (0)