Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/plural-sequences.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@tanstack/react-hotkeys': minor
'@tanstack/preact-hotkeys': minor
'@tanstack/vue-hotkeys': minor
'@tanstack/solid-hotkeys': minor
'@tanstack/svelte-hotkeys': minor
'@tanstack/angular-hotkeys': minor
---

Add plural sequence APIs (`useHotkeySequences`, `createHotkeySequences`, `createHotkeySequencesAttachment`, `injectHotkeySequences`) and align `enabled` across adapters: disabled registrations stay in the manager for devtools, only core dispatch is skipped, and toggling `enabled` updates handles via `setOptions` instead of churning unregister/register.
76 changes: 76 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,14 @@
{
"label": "UseHotkeySequenceOptions",
"to": "framework/react/reference/interfaces/UseHotkeySequenceOptions"
},
{
"label": "useHotkeySequences",
"to": "framework/react/reference/functions/useHotkeySequences"
},
{
"label": "UseHotkeySequenceDefinition",
"to": "framework/react/reference/interfaces/UseHotkeySequenceDefinition"
}
]
},
Expand All @@ -665,6 +673,14 @@
{
"label": "UseHotkeySequenceOptions",
"to": "framework/preact/reference/interfaces/UseHotkeySequenceOptions"
},
{
"label": "useHotkeySequences",
"to": "framework/preact/reference/functions/useHotkeySequences"
},
{
"label": "UseHotkeySequenceDefinition",
"to": "framework/preact/reference/interfaces/UseHotkeySequenceDefinition"
}
]
},
Expand All @@ -678,6 +694,14 @@
{
"label": "CreateHotkeySequenceOptions",
"to": "framework/solid/reference/interfaces/CreateHotkeySequenceOptions"
},
{
"label": "createHotkeySequences",
"to": "framework/solid/reference/functions/createHotkeySequences"
},
{
"label": "CreateHotkeySequenceDefinition",
"to": "framework/solid/reference/interfaces/CreateHotkeySequenceDefinition"
}
]
},
Expand All @@ -691,6 +715,14 @@
{
"label": "InjectHotkeySequenceOptions",
"to": "framework/angular/reference/interfaces/InjectHotkeySequenceOptions"
},
{
"label": "injectHotkeySequences",
"to": "framework/angular/reference/functions/injectHotkeySequences"
},
{
"label": "InjectHotkeySequenceDefinition",
"to": "framework/angular/reference/interfaces/InjectHotkeySequenceDefinition"
}
]
},
Expand All @@ -704,6 +736,14 @@
{
"label": "UseHotkeySequenceOptions",
"to": "framework/vue/reference/interfaces/UseHotkeySequenceOptions"
},
{
"label": "useHotkeySequences",
"to": "framework/vue/reference/functions/useHotkeySequences"
},
{
"label": "UseHotkeySequenceDefinition",
"to": "framework/vue/reference/interfaces/UseHotkeySequenceDefinition"
}
]
},
Expand All @@ -721,6 +761,18 @@
{
"label": "CreateHotkeySequenceOptions",
"to": "framework/svelte/reference/interfaces/CreateHotkeySequenceOptions"
},
{
"label": "createHotkeySequences",
"to": "framework/svelte/reference/functions/createHotkeySequences"
},
{
"label": "createHotkeySequencesAttachment",
"to": "framework/svelte/reference/functions/createHotkeySequencesAttachment"
},
{
"label": "CreateHotkeySequenceDefinition",
"to": "framework/svelte/reference/interfaces/CreateHotkeySequenceDefinition"
}
]
}
Expand Down Expand Up @@ -1200,6 +1252,10 @@
"label": "useHotkeySequence",
"to": "framework/react/examples/useHotkeySequence"
},
{
"label": "useHotkeySequences",
"to": "framework/react/examples/useHotkeySequences"
},
{
"label": "useHotkeyRecorder",
"to": "framework/react/examples/useHotkeyRecorder"
Expand Down Expand Up @@ -1233,6 +1289,10 @@
"label": "useHotkeySequence",
"to": "framework/preact/examples/useHotkeySequence"
},
{
"label": "useHotkeySequences",
"to": "framework/preact/examples/useHotkeySequences"
},
{
"label": "useHotkeyRecorder",
"to": "framework/preact/examples/useHotkeyRecorder"
Expand Down Expand Up @@ -1266,6 +1326,10 @@
"label": "createHotkeySequence",
"to": "framework/solid/examples/createHotkeySequence"
},
{
"label": "createHotkeySequences",
"to": "framework/solid/examples/createHotkeySequences"
},
{
"label": "createHotkeyRecorder",
"to": "framework/solid/examples/createHotkeyRecorder"
Expand Down Expand Up @@ -1299,6 +1363,10 @@
"label": "injectHotkeySequence",
"to": "framework/angular/examples/injectHotkeySequence"
},
{
"label": "injectHotkeySequences",
"to": "framework/angular/examples/injectHotkeySequences"
},
{
"label": "injectHotkeyRecorder",
"to": "framework/angular/examples/injectHotkeyRecorder"
Expand Down Expand Up @@ -1332,6 +1400,10 @@
"label": "useHotkeySequence",
"to": "framework/vue/examples/useHotkeySequence"
},
{
"label": "useHotkeySequences",
"to": "framework/vue/examples/useHotkeySequences"
},
{
"label": "useHotkeyRecorder",
"to": "framework/vue/examples/useHotkeyRecorder"
Expand Down Expand Up @@ -1365,6 +1437,10 @@
"label": "createHotkeySequence",
"to": "framework/svelte/examples/create-hotkey-sequence"
},
{
"label": "createHotkeySequences",
"to": "framework/svelte/examples/create-hotkey-sequences"
},
{
"label": "createHotkeyRecorder",
"to": "framework/svelte/examples/create-hotkey-recorder"
Expand Down
2 changes: 2 additions & 0 deletions docs/framework/angular/guides/hotkeys.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ For reactive state, pass an accessor function as the third argument.

### `enabled`

When `enabled` is false, the hotkey **stays registered** (visible in devtools); only the callback is suppressed.

```ts
import { Component, signal } from '@angular/core'
import { injectHotkey } from '@tanstack/angular-hotkeys'
Expand Down
31 changes: 31 additions & 0 deletions docs/framework/angular/guides/sequences.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,35 @@ export class AppComponent {
}
```

## Many sequences at once

Use `injectHotkeySequences` when you want several sequences (or a list built from data) in one injection context, instead of many `injectHotkeySequence` calls.

```ts
import { Component } from '@angular/core'
import { injectHotkeySequences } from '@tanstack/angular-hotkeys'

@Component({ standalone: true, template: `` })
export class AppComponent {
constructor() {
injectHotkeySequences([
{
sequence: ['G', 'G'],
callback: () =>
window.scrollTo({ top: 0, behavior: 'smooth' }),
},
{
sequence: ['D', 'D'],
callback: () => console.log('delete line'),
options: { timeout: 500 },
},
])
}
}
```

Options merge like `injectHotkeys`: `provideHotkeys` defaults, then `commonOptions`, then each definition’s `options`.

## Sequence Options

```ts
Expand All @@ -32,6 +61,8 @@ injectHotkeySequence(['G', 'G'], callback, {

### Reactive `enabled`

When disabled, the sequence **stays registered** (visible in devtools); only execution is suppressed.

```ts
import { Component, signal } from '@angular/core'
import { injectHotkeySequence } from '@tanstack/angular-hotkeys'
Expand Down
4 changes: 3 additions & 1 deletion docs/framework/angular/reference/functions/injectHotkey.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function injectHotkey(
options): void;
```

Defined in: [injectHotkey.ts:83](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L83)
Defined in: [injectHotkey.ts:86](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L86)

Angular inject-based API for registering a keyboard hotkey.

Expand All @@ -23,6 +23,8 @@ containing the hotkey string and parsed hotkey.
Call in an injection context (e.g. constructor or field initializer).
Uses effect() to track reactive dependencies and update registration
when options or the callback change.
`enabled: false` keeps the registration (visible in devtools) and only suppresses firing; the same
handle is updated instead of unregistering and re-registering when identity is unchanged.

## Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function injectHotkeySequence(
options): void;
```

Defined in: [injectHotkeySequence.ts:48](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequence.ts#L48)
Defined in: [injectHotkeySequence.ts:58](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequence.ts#L58)

Angular inject-based API for registering a keyboard shortcut sequence (Vim-style).

Expand Down Expand Up @@ -40,7 +40,8 @@ Function to call when the sequence is completed

### options

Options for the sequence behavior (or getter function)
Options for the sequence behavior (or getter function). `enabled: false` still registers
the sequence (visible in devtools); only execution is suppressed.

[`InjectHotkeySequenceOptions`](../interfaces/InjectHotkeySequenceOptions.md) | () => [`InjectHotkeySequenceOptions`](../interfaces/InjectHotkeySequenceOptions.md)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: injectHotkeySequences
title: injectHotkeySequences
---

# Function: injectHotkeySequences()

```ts
function injectHotkeySequences(sequences, commonOptions): void;
```

Defined in: [injectHotkeySequences.ts:51](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequences.ts#L51)

Angular inject-based API for registering multiple keyboard shortcut sequences at once (Vim-style).

Uses the singleton SequenceManager. Call in an injection context (e.g. constructor).
Uses `effect()` to track reactive dependencies when definitions or options are getters.

Options are merged in this order:
provideHotkeys defaults < commonOptions < per-definition options

Definitions with an empty `sequence` are skipped. Disabled sequences (`enabled: false`)
remain registered so they stay visible in devtools; the core manager suppresses execution.

## Parameters

### sequences

Array of sequence definitions, or getter returning them

[`InjectHotkeySequenceDefinition`](../interfaces/InjectHotkeySequenceDefinition.md)[] | () => [`InjectHotkeySequenceDefinition`](../interfaces/InjectHotkeySequenceDefinition.md)[]

### commonOptions

Shared options for all sequences, or getter

[`InjectHotkeySequenceOptions`](../interfaces/InjectHotkeySequenceOptions.md) | () => [`InjectHotkeySequenceOptions`](../interfaces/InjectHotkeySequenceOptions.md)

## Returns

`void`

## Example

```ts
@Component({ ... })
export class VimComponent {
constructor() {
injectHotkeySequences([
{ sequence: ['G', 'G'], callback: () => this.goTop() },
{ sequence: ['D', 'D'], callback: () => this.deleteLine() },
])
}
}
```
2 changes: 2 additions & 0 deletions docs/framework/angular/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ title: "@tanstack/angular-hotkeys"
- [HotkeysProviderOptions](interfaces/HotkeysProviderOptions.md)
- [InjectHotkeyDefinition](interfaces/InjectHotkeyDefinition.md)
- [InjectHotkeyOptions](interfaces/InjectHotkeyOptions.md)
- [InjectHotkeySequenceDefinition](interfaces/InjectHotkeySequenceDefinition.md)
- [InjectHotkeySequenceOptions](interfaces/InjectHotkeySequenceOptions.md)

## Variables
Expand All @@ -30,5 +31,6 @@ title: "@tanstack/angular-hotkeys"
- [injectHotkeysContext](functions/injectHotkeysContext.md)
- [injectHotkeySequence](functions/injectHotkeySequence.md)
- [injectHotkeySequenceRecorder](functions/injectHotkeySequenceRecorder.md)
- [injectHotkeySequences](functions/injectHotkeySequences.md)
- [injectKeyHold](functions/injectKeyHold.md)
- [provideHotkeys](functions/provideHotkeys.md)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: InjectHotkeyOptions

# Interface: InjectHotkeyOptions

Defined in: [injectHotkey.ts:16](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L16)
Defined in: [injectHotkey.ts:17](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L17)

## Extends

Expand All @@ -19,7 +19,7 @@ Defined in: [injectHotkey.ts:16](https://github.com/TanStack/hotkeys/blob/main/p
optional target: HTMLElement | Document | Window | null;
```

Defined in: [injectHotkey.ts:24](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L24)
Defined in: [injectHotkey.ts:25](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkey.ts#L25)

The DOM element to attach the event listener to.
Can be a direct DOM element, an accessor (for reactive targets that become
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
id: InjectHotkeySequenceDefinition
title: InjectHotkeySequenceDefinition
---

# Interface: InjectHotkeySequenceDefinition

Defined in: [injectHotkeySequences.ts:14](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequences.ts#L14)

A single sequence definition for use with `injectHotkeySequences`.

## Properties

### callback

```ts
callback: HotkeyCallback;
```

Defined in: [injectHotkeySequences.ts:18](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequences.ts#L18)

The function to call when the sequence is completed

***

### options?

```ts
optional options:
| InjectHotkeySequenceOptions
| () => InjectHotkeySequenceOptions;
```

Defined in: [injectHotkeySequences.ts:20](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequences.ts#L20)

Per-sequence options (merged on top of commonOptions)

***

### sequence

```ts
sequence: HotkeySequence | () => HotkeySequence;
```

Defined in: [injectHotkeySequences.ts:16](https://github.com/TanStack/hotkeys/blob/main/packages/angular-hotkeys/src/injectHotkeySequences.ts#L16)

Array of hotkey strings that form the sequence
Loading
Loading