Skip to content

feat: useHotkeySequences hooks#80

Open
KevinVandy wants to merge 3 commits intomainfrom
hotkeysequences
Open

feat: useHotkeySequences hooks#80
KevinVandy wants to merge 3 commits intomainfrom
hotkeysequences

Conversation

@KevinVandy
Copy link
Member

@KevinVandy KevinVandy commented Mar 24, 2026

🎯 Changes

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Multi-sequence hotkey APIs added across React/Preact/Vue/Solid/Svelte/Angular, plus a Svelte element attachment helper
    • Support for dynamic, variable-length sequence lists
  • Behavior Change

    • Disabling a sequence now keeps it visible in devtools while suppressing execution; toggling enabled updates registrations in-place
  • Examples

    • New demo apps for React, Preact, Solid, Svelte, Vue, and Angular
  • Documentation

    • Expanded guides & reference pages across all frameworks
  • Tests

    • New cross-framework test suites validating multi-sequence behavior
  • Chores

    • Changeset entries marking minor releases for affected packages

@github-actions
Copy link
Contributor

github-actions bot commented Mar 24, 2026

🚀 Changeset Version Preview

6 package(s) bumped directly, 0 bumped as dependents.

🟨 Minor bumps

Package Version Reason
@tanstack/angular-hotkeys 0.6.0 → 0.7.0 Changeset
@tanstack/preact-hotkeys 0.6.0 → 0.7.0 Changeset
@tanstack/react-hotkeys 0.6.0 → 0.7.0 Changeset
@tanstack/solid-hotkeys 0.6.0 → 0.7.0 Changeset
@tanstack/svelte-hotkeys 0.6.0 → 0.7.0 Changeset
@tanstack/vue-hotkeys 0.6.0 → 0.7.0 Changeset

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 24, 2026

Open in StackBlitz

@tanstack/angular-hotkeys

npm i https://pkg.pr.new/@tanstack/angular-hotkeys@80

@tanstack/hotkeys

npm i https://pkg.pr.new/@tanstack/hotkeys@80

@tanstack/hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/hotkeys-devtools@80

@tanstack/preact-hotkeys

npm i https://pkg.pr.new/@tanstack/preact-hotkeys@80

@tanstack/preact-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/preact-hotkeys-devtools@80

@tanstack/react-hotkeys

npm i https://pkg.pr.new/@tanstack/react-hotkeys@80

@tanstack/react-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/react-hotkeys-devtools@80

@tanstack/solid-hotkeys

npm i https://pkg.pr.new/@tanstack/solid-hotkeys@80

@tanstack/solid-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/solid-hotkeys-devtools@80

@tanstack/svelte-hotkeys

npm i https://pkg.pr.new/@tanstack/svelte-hotkeys@80

@tanstack/vue-hotkeys

npm i https://pkg.pr.new/@tanstack/vue-hotkeys@80

@tanstack/vue-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/vue-hotkeys-devtools@80

commit: afec5a4

@coderabbitai
Copy link

coderabbitai bot commented Mar 24, 2026

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: efa73896-fc73-4914-8290-fe28359b1091

📥 Commits

Reviewing files that changed from the base of the PR and between 4767bbb and afec5a4.

📒 Files selected for processing (91)
  • .changeset/plural-sequences.md
  • docs/framework/angular/guides/hotkeys.md
  • docs/framework/angular/guides/sequences.md
  • docs/framework/angular/reference/functions/injectHotkey.md
  • docs/framework/angular/reference/functions/injectHotkeySequence.md
  • docs/framework/angular/reference/functions/injectHotkeySequences.md
  • docs/framework/angular/reference/interfaces/InjectHotkeyOptions.md
  • docs/framework/angular/reference/interfaces/InjectHotkeySequenceOptions.md
  • docs/framework/preact/guides/hotkeys.md
  • docs/framework/preact/guides/sequences.md
  • docs/framework/preact/reference/functions/useHotkey.md
  • docs/framework/preact/reference/functions/useHotkeySequence.md
  • docs/framework/preact/reference/functions/useHotkeySequences.md
  • docs/framework/preact/reference/functions/useHotkeys.md
  • docs/framework/react/guides/hotkeys.md
  • docs/framework/react/guides/sequences.md
  • docs/framework/react/reference/functions/useHotkey.md
  • docs/framework/react/reference/functions/useHotkeySequence.md
  • docs/framework/react/reference/functions/useHotkeySequences.md
  • docs/framework/react/reference/functions/useHotkeys.md
  • docs/framework/solid/guides/hotkeys.md
  • docs/framework/solid/guides/sequences.md
  • docs/framework/svelte/guides/hotkeys.md
  • docs/framework/svelte/guides/sequences.md
  • docs/framework/svelte/reference/functions/createHotkey.md
  • docs/framework/svelte/reference/functions/createHotkeyAttachment.md
  • docs/framework/svelte/reference/functions/createHotkeySequence.md
  • docs/framework/svelte/reference/functions/createHotkeySequenceAttachment.md
  • docs/framework/svelte/reference/interfaces/CreateHotkeyOptions.md
  • docs/framework/svelte/reference/interfaces/CreateHotkeySequenceOptions.md
  • docs/framework/vue/guides/hotkeys.md
  • docs/framework/vue/guides/sequences.md
  • docs/reference/classes/HotkeyManager.md
  • docs/reference/functions/getHotkeyManager.md
  • docs/reference/interfaces/HotkeyOptions.md
  • docs/reference/interfaces/HotkeyRegistration.md
  • docs/reference/interfaces/HotkeyRegistrationHandle.md
  • docs/reference/interfaces/SequenceOptions.md
  • examples/angular/injectHotkeySequence/src/app/app.component.html
  • examples/angular/injectHotkeySequence/src/app/app.component.ts
  • examples/angular/injectHotkeySequence/src/styles.css
  • examples/angular/injectHotkeySequences/src/app/app.component.html
  • examples/angular/injectHotkeySequences/src/app/app.component.ts
  • examples/angular/injectHotkeySequences/src/styles.css
  • examples/preact/useHotkeySequence/src/index.css
  • examples/preact/useHotkeySequence/src/index.tsx
  • examples/preact/useHotkeySequences/src/index.css
  • examples/preact/useHotkeySequences/src/index.tsx
  • examples/react/useHotkeySequence/src/index.css
  • examples/react/useHotkeySequence/src/index.tsx
  • examples/react/useHotkeySequences/src/index.css
  • examples/react/useHotkeySequences/src/index.tsx
  • examples/solid/createHotkeySequence/src/index.css
  • examples/solid/createHotkeySequence/src/index.tsx
  • examples/solid/createHotkeySequences/src/index.css
  • examples/solid/createHotkeySequences/src/index.tsx
  • examples/svelte/create-hotkey-sequence/src/App.svelte
  • examples/svelte/create-hotkey-sequence/src/index.css
  • examples/svelte/create-hotkey-sequences/src/App.svelte
  • examples/svelte/create-hotkey-sequences/src/index.css
  • examples/vue/useHotkeySequence/src/App.vue
  • examples/vue/useHotkeySequence/src/index.css
  • examples/vue/useHotkeySequences/src/App.vue
  • examples/vue/useHotkeySequences/src/index.css
  • packages/angular-hotkeys/src/injectHotkey.ts
  • packages/angular-hotkeys/src/injectHotkeySequence.ts
  • packages/angular-hotkeys/src/injectHotkeySequences.ts
  • packages/hotkeys/src/hotkey-manager.ts
  • packages/hotkeys/tests/sequence-manager.test.ts
  • packages/preact-hotkeys/src/useHotkey.ts
  • packages/preact-hotkeys/src/useHotkeySequence.ts
  • packages/preact-hotkeys/src/useHotkeySequences.ts
  • packages/preact-hotkeys/src/useHotkeys.ts
  • packages/preact-hotkeys/tests/useHotkey.test.tsx
  • packages/preact-hotkeys/tests/useHotkeySequences.test.tsx
  • packages/preact-hotkeys/tests/useHotkeys.test.tsx
  • packages/react-hotkeys/src/useHotkey.ts
  • packages/react-hotkeys/src/useHotkeySequence.ts
  • packages/react-hotkeys/src/useHotkeySequences.ts
  • packages/react-hotkeys/src/useHotkeys.ts
  • packages/react-hotkeys/tests/useHotkey.test.tsx
  • packages/react-hotkeys/tests/useHotkeySequences.test.tsx
  • packages/react-hotkeys/tests/useHotkeys.test.tsx
  • packages/solid-hotkeys/src/createHotkey.ts
  • packages/solid-hotkeys/src/createHotkeySequence.ts
  • packages/solid-hotkeys/tests/createHotkeySequences.test.tsx
  • packages/solid-hotkeys/tests/createHotkeys.test.tsx
  • packages/svelte-hotkeys/src/createHotkey.svelte.ts
  • packages/svelte-hotkeys/src/createHotkeySequence.svelte.ts
  • packages/vue-hotkeys/src/useHotkey.ts
  • packages/vue-hotkeys/src/useHotkeySequence.ts
 ______________________________________________________________
< Your function has more side effects than my caffeine intake. >
 --------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
📝 Walkthrough

Walkthrough

Adds plural hotkey-sequence registration APIs across frameworks: useHotkeySequences (React/Preact/Vue), createHotkeySequences (+ attachment) (Solid/Svelte), and injectHotkeySequences (Angular). Includes implementations, tests, docs, examples, and package exports exposing the new APIs.

Changes

Cohort / File(s) Summary
Changeset & Docs Config
\.changeset/plural-sequences.md, docs/config.json
Added changeset and navigation entries for plural-sequence APIs and examples across all frameworks.
React — API, Tests, Docs, Example
packages/react-hotkeys/src/useHotkeySequences.ts, packages/react-hotkeys/src/index.ts, packages/react-hotkeys/tests/useHotkeySequences.test.tsx, docs/framework/react/*, examples/react/useHotkeySequences/*
New useHotkeySequences hook, re-exported in package index, tests, docs, and a full React example app.
Preact — API, Tests, Docs, Example
packages/preact-hotkeys/src/useHotkeySequences.ts, packages/preact-hotkeys/src/index.ts, packages/preact-hotkeys/tests/*, docs/framework/preact/*, examples/preact/useHotkeySequences/*
New useHotkeySequences hook (Preact), package export, tests, docs, and example.
Vue — API, Docs, Example
packages/vue-hotkeys/src/useHotkeySequences.ts, packages/vue-hotkeys/src/index.ts, docs/framework/vue/*, examples/vue/useHotkeySequences/*
New useHotkeySequences composable with ref/getter support, package export, docs, and example.
Solid — API, Tests, Docs, Example
packages/solid-hotkeys/src/createHotkeySequences.ts, packages/solid-hotkeys/src/index.ts, packages/solid-hotkeys/tests/*, docs/framework/solid/*, examples/solid/createHotkeySequences/*
New createHotkeySequences primitive, re-exported, tests, docs, and Solid example.
Svelte — API, Docs, Example
packages/svelte-hotkeys/src/createHotkeySequences.svelte.ts, packages/svelte-hotkeys/src/index.ts, docs/framework/svelte/*, examples/svelte/create-hotkey-sequences/*
Added createHotkeySequences and createHotkeySequencesAttachment, package export, docs, and Svelte example (component + app).
Angular — API, Docs, Example
packages/angular-hotkeys/src/injectHotkeySequences.ts, packages/angular-hotkeys/src/index.ts, docs/framework/angular/*, examples/angular/injectHotkeySequences/*
New injectHotkeySequences injection-based API, re-exported, docs, and full Angular example project.
Documentation pages & Interfaces
docs/framework/*/reference/interfaces/*, docs/framework/*/reference/functions/*
Added reference pages and interface docs (*HotkeySequenceDefinition, function references) across frameworks.
Examples & Tooling configs
examples/*/*/package.json, examples/*/*/vite.config.ts, examples/*/*/tsconfig.json, examples/*/*/index.html, examples/*/*/src/*
Added per-framework example projects (source, CSS, configs, build/dev scripts, and tooling).

Sequence Diagram(s)

sequenceDiagram
    participant Component as Framework Component / Hook
    participant FrameworkLifecycle as Framework Lifecycle (effect/watch/createEffect)
    participant SequenceManager as SequenceManager (singleton)
    participant Target as Target (document | element)

    Component->>FrameworkLifecycle: provide definitions + commonOptions
    FrameworkLifecycle->>FrameworkLifecycle: resolve getters/refs\nmerge options (provider < common < per-definition)
    FrameworkLifecycle->>SequenceManager: diff registrations\nregister/unregister handles (with target)
    SequenceManager->>Target: attach listeners to target
    Target->>SequenceManager: key events
    SequenceManager->>SequenceManager: detect sequence match\ninvoke callback
    SequenceManager->>Component: callback runs (updates state)
    FrameworkLifecycle->>SequenceManager: on update -> update callbacks/options or re-register
    Component->>FrameworkLifecycle: unmount/destroy
    FrameworkLifecycle->>SequenceManager: unregister remaining handles
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through code and docs so neat,

many sequences now register in one beat.
React, Vue, Solid, Svelte, Preact, Angular too—
one call, many chords, a rabbit's review! 🎩✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description uses the template structure but leaves the '🎯 Changes' section empty, providing no meaningful context about what was added or why. The checklist items are unchecked, indicating incomplete preparation. Fill in the 'Changes' section with a summary of the new useHotkeySequences APIs added across frameworks and their purpose. Mark completed checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: useHotkeySequences hooks' clearly and concisely summarizes the main feature addition—the introduction of plural hotkey sequence registration APIs across multiple frameworks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotkeysequences

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can customize the tone of the review comments and chat replies.

Configure the tone_instructions setting to customize the tone of the review comments and chat replies. For example, you can set the tone to Act like a strict teacher, Act like a pirate and more.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (3)
docs/framework/preact/guides/sequences.md (1)

38-38: Optional: add a commonOptions example snippet.

Since this line explains second-argument precedence, adding a tiny example with useHotkeySequences(definitions, commonOptions) would make the behavior immediately actionable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/framework/preact/guides/sequences.md` at line 38, Add a short example
demonstrating the second-argument precedence for useHotkeySequences so readers
can see how HotkeysProvider defaults, the second-argument commonOptions, and
each definition’s options merge (e.g., show calling
useHotkeySequences(definitions, commonOptions) with one shared option overridden
by a per-definition options entry). Refer to useHotkeySequences,
HotkeysProvider, commonOptions, definitions, and each definition’s options in
the example so it clearly shows the precedence order in practice.
examples/angular/injectHotkeySequences/src/app/app.component.html (1)

72-74: Announce triggered sequence updates to assistive tech.

At Line 73, this status changes dynamically; adding aria-live="polite" improves screen-reader feedback.

♿ Suggested tweak
-      <div class="info-box success"><strong>Triggered:</strong> {{ seq }}</div>
+      <div class="info-box success" aria-live="polite">
+        <strong>Triggered:</strong> {{ seq }}
+      </div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/angular/injectHotkeySequences/src/app/app.component.html` around
lines 72 - 74, The dynamic "Triggered" status rendered via the lastSequence()
template binding (as seq) should announce updates to assistive tech; add
aria-live="polite" to the div with class "info-box success" that displays {{ seq
}} so screen readers are notified of changes without interrupting. Target the
template block using lastSequence() / seq and update that div to include the
aria-live attribute.
packages/angular-hotkeys/src/injectHotkeySequences.ts (1)

106-110: Inconsistent enabled handling compared to other framework implementations.

The Angular implementation skips registration when enabled: false at lines 106-110, and always passes enabled: true when registering (line 158). Other framework implementations (React, Vue, Solid, Preact, Svelte) pass the resolved enabled value through to setOptions() or the registration call, allowing the underlying manager to handle enable/disable state.

This inconsistency means:

  • Angular: Toggling enabled causes unregister/re-register cycles
  • Other frameworks: Toggling enabled updates the existing handle via setOptions()

Consider aligning with other frameworks by passing the enabled value through to the handle:

♻️ Suggested alignment with other frameworks
-      const { enabled = true, ...sequenceOpts } = mergedOptions
+      const { enabled = true, target, ...restOptions } = mergedOptions

-      if (!enabled || resolvedSequence.length === 0) {
+      if (resolvedSequence.length === 0) {
         continue
       }

+      const resolvedTarget =
+        target ?? (typeof document !== 'undefined' ? document : null)
+
+      if (!resolvedTarget) {
+        continue
+      }
+
+      const sequenceOpts = { ...restOptions, enabled }

And when registering:

       const handle = manager.register(p.resolvedSequence, p.def.callback, {
         ...p.sequenceOpts,
-        enabled: true,
         target: p.resolvedTarget,
       })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/angular-hotkeys/src/injectHotkeySequences.ts` around lines 106 -
110, The Angular implementation currently destructures enabled from
mergedOptions and skips registration when enabled is false (using const {
enabled = true, ...sequenceOpts } = mergedOptions and continue), and later
always registers with enabled: true; instead, preserve and pass the resolved
enabled value through like other frameworks: do not early-continue on enabled
=== false (still register the sequence handle), and when calling the
registration or setOptions helper (the code path that currently uses
sequenceOpts/registration call), include enabled (the actual resolved enabled)
rather than hardcoding true so the manager can toggle state via
setOptions/update instead of unregistering/re-registering; adjust uses of
mergedOptions, sequenceOpts, and the register/setOptions call accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/framework/angular/guides/sequences.md`:
- Around line 28-48: The example is missing the import for the Angular decorator
used: add an import for Component from '@angular/core' at the top of the snippet
so the `@Component` decorator on AppComponent resolves; keep the existing import
of injectHotkeySequences from '@tanstack/angular-hotkeys' and the AppComponent
class/constructor unchanged.

In `@examples/angular/injectHotkeySequences/src/app/app.component.ts`:
- Line 12: The history property uses the bracket-array form which violates the
lint rule; change its type to the generic form by replacing any occurrences of
string[] with Array<string> (e.g., update history = signal<string[]>([]) to
history = signal<Array<string>>([]) and adjust any other annotations or uses of
history in the AppComponent class accordingly).

In `@examples/angular/injectHotkeySequences/src/app/app.config.ts`:
- Around line 1-6: The file currently imports provideHotkeys but doesn't use it
and pulls in ApplicationConfig as a value import; change the ApplicationConfig
import to a type-only import (import type { ApplicationConfig }) and add
provideHotkeys(...) into the providers array of the exported appConfig so the
example demonstrates hotkey setup; reference the symbols ApplicationConfig,
provideHotkeys, appConfig and provideZoneChangeDetection when making these
edits.

In `@examples/angular/injectHotkeySequences/src/styles.css`:
- Around line 22-27: Remove the duplicate margin declaration in the CSS rule for
selector "header p": delete the earlier "margin: 0" and keep the later "margin:
0 auto" so only one margin declaration remains in the "header p" rule to satisfy
Stylelint and avoid redundancy.

In `@examples/preact/useHotkeySequences/src/index.css`:
- Around line 26-30: The CSS block for the selector "header p" contains a
duplicate margin declaration; remove the redundant "margin: 0;" so the rule only
keeps the intended layout declaration ("margin: 0 auto") in the header p rule to
avoid dead code and ensure the paragraph is centered horizontally.

In `@examples/react/useHotkeySequences/src/index.css`:
- Around line 26-31: The CSS selector "header p" contains a duplicate margin
declaration: remove the redundant "margin: 0" so only "margin: 0 auto" remains
(or consolidate into a single margin rule) within the header p block to satisfy
Stylelint and prevent the overwritten property.

In `@examples/solid/createHotkeySequences/src/index.css`:
- Around line 22-27: The selector "header p" contains a duplicated margin
declaration; remove the redundant "margin: 0" so only the intended "margin: 0
auto" remains (or merge them into a single "margin: 0 auto") alongside the
existing "max-width: 500px" and other properties to satisfy Stylelint and avoid
the overridden rule.

In `@examples/solid/createHotkeySequences/src/index.tsx`:
- Around line 3-8: Reorder the named imports to satisfy the ESLint sort-imports
rule: in the first import list swap createSignal and Show so Show comes before
createSignal, and in the second import list reorder the three symbols so
HotkeysProvider appears before createHotkey and createHotkeySequences
(preserving the relative order between the two create* names).

In `@examples/svelte/create-hotkey-sequences/README.md`:
- Around line 16-19: Update the recreate command in the README so the generated
project name matches the example directory: replace the erroneous
"create-hotkey" token in the shell command with "create-hotkey-sequences" (the
command string in the README's recreate example).

In `@examples/svelte/create-hotkey-sequences/src/index.css`:
- Around line 26-31: The CSS rule for the selector "header p" contains a
duplicate margin declaration; remove the redundant "margin: 0;" and keep the
intended "margin: 0 auto;" in the header p rule (locate the header p block in
index.css) so only a single margin declaration remains and the stylelint error
is resolved.

In `@examples/vue/useHotkeySequences/src/index.css`:
- Around line 26-31: The CSS rule for selector "header p" contains a duplicate
margin declaration; remove the redundant "margin: 0;" and keep a single
consolidated margin declaration (e.g., "margin: 0 auto;") in the "header p" rule
so there is no overridden/unused property.

In `@packages/solid-hotkeys/tests/createHotkeySequences.test.tsx`:
- Around line 2-10: Reorder and split the imports to satisfy ESLint rules:
alphabetize named members inside each import, move type-only imports to
top-level "import type" statements, and place the "solid-js" import before the
relative module import. Specifically, convert "type
CreateHotkeySequenceDefinition" and "type Component" to top-level import type
lines, alphabetize members in the vitest import (afterEach, beforeEach,
describe, expect, it, vi) and in the `@tanstack/hotkeys` import (SequenceManager),
ensure "createSignal" and "Component" from "solid-js" are imported before
"../src/createHotkeySequences", and keep "render" from
"@solidjs/testing-library" ordered appropriately.

---

Nitpick comments:
In `@docs/framework/preact/guides/sequences.md`:
- Line 38: Add a short example demonstrating the second-argument precedence for
useHotkeySequences so readers can see how HotkeysProvider defaults, the
second-argument commonOptions, and each definition’s options merge (e.g., show
calling useHotkeySequences(definitions, commonOptions) with one shared option
overridden by a per-definition options entry). Refer to useHotkeySequences,
HotkeysProvider, commonOptions, definitions, and each definition’s options in
the example so it clearly shows the precedence order in practice.

In `@examples/angular/injectHotkeySequences/src/app/app.component.html`:
- Around line 72-74: The dynamic "Triggered" status rendered via the
lastSequence() template binding (as seq) should announce updates to assistive
tech; add aria-live="polite" to the div with class "info-box success" that
displays {{ seq }} so screen readers are notified of changes without
interrupting. Target the template block using lastSequence() / seq and update
that div to include the aria-live attribute.

In `@packages/angular-hotkeys/src/injectHotkeySequences.ts`:
- Around line 106-110: The Angular implementation currently destructures enabled
from mergedOptions and skips registration when enabled is false (using const {
enabled = true, ...sequenceOpts } = mergedOptions and continue), and later
always registers with enabled: true; instead, preserve and pass the resolved
enabled value through like other frameworks: do not early-continue on enabled
=== false (still register the sequence handle), and when calling the
registration or setOptions helper (the code path that currently uses
sequenceOpts/registration call), include enabled (the actual resolved enabled)
rather than hardcoding true so the manager can toggle state via
setOptions/update instead of unregistering/re-registering; adjust uses of
mergedOptions, sequenceOpts, and the register/setOptions call accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 216e776a-35f5-4f4b-97a0-20356289fa95

📥 Commits

Reviewing files that changed from the base of the PR and between d058c76 and 1f650ae.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (95)
  • .changeset/plural-sequences.md
  • docs/config.json
  • docs/framework/angular/guides/sequences.md
  • docs/framework/angular/reference/functions/injectHotkeySequences.md
  • docs/framework/angular/reference/index.md
  • docs/framework/angular/reference/interfaces/InjectHotkeySequenceDefinition.md
  • docs/framework/preact/guides/sequences.md
  • docs/framework/preact/reference/functions/useHotkeySequences.md
  • docs/framework/preact/reference/index.md
  • docs/framework/preact/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/react/guides/sequences.md
  • docs/framework/react/reference/functions/useHotkeySequences.md
  • docs/framework/react/reference/index.md
  • docs/framework/react/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/solid/guides/sequences.md
  • docs/framework/solid/reference/functions/createHotkeySequences.md
  • docs/framework/solid/reference/index.md
  • docs/framework/solid/reference/interfaces/CreateHotkeySequenceDefinition.md
  • docs/framework/svelte/guides/sequences.md
  • docs/framework/svelte/reference/functions/createHotkeySequences.md
  • docs/framework/svelte/reference/functions/createHotkeySequencesAttachment.md
  • docs/framework/svelte/reference/index.md
  • docs/framework/svelte/reference/interfaces/CreateHotkeySequenceDefinition.md
  • docs/framework/vue/guides/sequences.md
  • docs/framework/vue/quick-start.md
  • docs/framework/vue/reference/functions/useHotkeySequences.md
  • docs/framework/vue/reference/index.md
  • docs/framework/vue/reference/interfaces/UseHotkeySequenceDefinition.md
  • examples/angular/injectHotkeySequences/angular.json
  • examples/angular/injectHotkeySequences/package.json
  • examples/angular/injectHotkeySequences/src/app/app.component.css
  • examples/angular/injectHotkeySequences/src/app/app.component.html
  • examples/angular/injectHotkeySequences/src/app/app.component.ts
  • examples/angular/injectHotkeySequences/src/app/app.config.ts
  • examples/angular/injectHotkeySequences/src/index.html
  • examples/angular/injectHotkeySequences/src/main.ts
  • examples/angular/injectHotkeySequences/src/styles.css
  • examples/angular/injectHotkeySequences/tsconfig.json
  • examples/preact/useHotkeySequences/eslint.config.js
  • examples/preact/useHotkeySequences/index.html
  • examples/preact/useHotkeySequences/package.json
  • examples/preact/useHotkeySequences/src/index.css
  • examples/preact/useHotkeySequences/src/index.tsx
  • examples/preact/useHotkeySequences/tsconfig.json
  • examples/preact/useHotkeySequences/vite.config.ts
  • examples/react/useHotkeySequences/eslint.config.js
  • examples/react/useHotkeySequences/index.html
  • examples/react/useHotkeySequences/package.json
  • examples/react/useHotkeySequences/src/index.css
  • examples/react/useHotkeySequences/src/index.tsx
  • examples/react/useHotkeySequences/tsconfig.json
  • examples/react/useHotkeySequences/vite.config.ts
  • examples/solid/createHotkeySequences/index.html
  • examples/solid/createHotkeySequences/package.json
  • examples/solid/createHotkeySequences/src/index.css
  • examples/solid/createHotkeySequences/src/index.tsx
  • examples/solid/createHotkeySequences/tsconfig.json
  • examples/solid/createHotkeySequences/vite.config.ts
  • examples/svelte/create-hotkey-sequences/.gitignore
  • examples/svelte/create-hotkey-sequences/.npmrc
  • examples/svelte/create-hotkey-sequences/README.md
  • examples/svelte/create-hotkey-sequences/index.html
  • examples/svelte/create-hotkey-sequences/package.json
  • examples/svelte/create-hotkey-sequences/src/App.svelte
  • examples/svelte/create-hotkey-sequences/src/Root.svelte
  • examples/svelte/create-hotkey-sequences/src/index.css
  • examples/svelte/create-hotkey-sequences/src/main.ts
  • examples/svelte/create-hotkey-sequences/static/robots.txt
  • examples/svelte/create-hotkey-sequences/svelte.config.js
  • examples/svelte/create-hotkey-sequences/tsconfig.json
  • examples/svelte/create-hotkey-sequences/vite.config.ts
  • examples/vue/useHotkeySequences/eslint.config.js
  • examples/vue/useHotkeySequences/index.html
  • examples/vue/useHotkeySequences/package.json
  • examples/vue/useHotkeySequences/src/App.vue
  • examples/vue/useHotkeySequences/src/index.css
  • examples/vue/useHotkeySequences/src/index.ts
  • examples/vue/useHotkeySequences/src/vue.d.ts
  • examples/vue/useHotkeySequences/tsconfig.json
  • examples/vue/useHotkeySequences/vite.config.ts
  • packages/angular-hotkeys/src/index.ts
  • packages/angular-hotkeys/src/injectHotkeySequences.ts
  • packages/preact-hotkeys/src/index.ts
  • packages/preact-hotkeys/src/useHotkeySequences.ts
  • packages/preact-hotkeys/tests/useHotkeySequences.test.tsx
  • packages/react-hotkeys/src/index.ts
  • packages/react-hotkeys/src/useHotkeySequences.ts
  • packages/react-hotkeys/tests/useHotkeySequences.test.tsx
  • packages/solid-hotkeys/src/createHotkeySequences.ts
  • packages/solid-hotkeys/src/index.ts
  • packages/solid-hotkeys/tests/createHotkeySequences.test.tsx
  • packages/svelte-hotkeys/src/createHotkeySequences.svelte.ts
  • packages/svelte-hotkeys/src/index.ts
  • packages/vue-hotkeys/src/index.ts
  • packages/vue-hotkeys/src/useHotkeySequences.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/angular/injectHotkeySequences/src/app/app.component.html`:
- Line 112: Escape the '>' in arrow functions inside the HTML example: replace
each arrow token "=>" in the callback expressions with "=&gt;" so the snippets
like "callback: () => scrollToTop()" become "callback: () =&gt; scrollToTop()";
apply the same change for the other occurrences referenced (lines containing the
callback arrow at the sequence entries on the same block).
- Line 112: The code example uses uppercase sequence ['G','G'] but the
docs/table describe lowercase "g g" (Vim semantics: gg -> top); update the
sequence in the example (the object containing "sequence: ['G','G'], callback:
() => scrollToTop()") to use lowercase ['g','g'] so the example matches the
table and expected behavior.

In `@examples/angular/injectHotkeySequences/src/app/app.config.ts`:
- Around line 1-3: Reorder the imports so the regular imports come before the
type-only import: place the existing `import { provideZoneChangeDetection } from
'@angular/core'` and `import { provideHotkeys } from
'@tanstack/angular-hotkeys'` first, and then move the type import `import type {
ApplicationConfig } from '@angular/core'` after them to satisfy the project's
`import/order` ESLint rule; update any references to `ApplicationConfig`,
`provideZoneChangeDetection`, or `provideHotkeys` accordingly.

In `@packages/solid-hotkeys/tests/createHotkeySequences.test.tsx`:
- Around line 5-8: The import order violates ESLint import/order: move all value
imports (createSignal from 'solid-js' and createHotkeySequences from
'../src/createHotkeySequences') before type-only imports, and group type imports
together (Component from 'solid-js' and CreateHotkeySequenceDefinition from
'../src/createHotkeySequences'); update the import statements so value imports
appear first then type imports to satisfy the rule.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f44e66a4-e2be-4fcf-8ae7-ad91880b1242

📥 Commits

Reviewing files that changed from the base of the PR and between 1f650ae and 4767bbb.

📒 Files selected for processing (27)
  • .changeset/plural-sequences.md
  • docs/framework/angular/guides/sequences.md
  • docs/framework/angular/reference/functions/injectHotkeySequences.md
  • docs/framework/angular/reference/interfaces/InjectHotkeySequenceDefinition.md
  • docs/framework/preact/reference/functions/useHotkeySequences.md
  • docs/framework/preact/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/react/reference/functions/useHotkeySequences.md
  • docs/framework/react/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/solid/reference/functions/createHotkeySequences.md
  • docs/framework/solid/reference/interfaces/CreateHotkeySequenceDefinition.md
  • docs/framework/svelte/reference/functions/createHotkeySequences.md
  • docs/framework/svelte/reference/functions/createHotkeySequencesAttachment.md
  • docs/framework/svelte/reference/interfaces/CreateHotkeySequenceDefinition.md
  • docs/framework/vue/reference/functions/useHotkeySequences.md
  • docs/framework/vue/reference/interfaces/UseHotkeySequenceDefinition.md
  • examples/angular/injectHotkeySequences/src/app/app.component.html
  • examples/angular/injectHotkeySequences/src/app/app.component.ts
  • examples/angular/injectHotkeySequences/src/app/app.config.ts
  • examples/angular/injectHotkeySequences/src/styles.css
  • examples/preact/useHotkeySequences/src/index.css
  • examples/react/useHotkeySequences/src/index.css
  • examples/solid/createHotkeySequences/src/index.css
  • examples/solid/createHotkeySequences/src/index.tsx
  • examples/svelte/create-hotkey-sequences/README.md
  • examples/svelte/create-hotkey-sequences/src/index.css
  • examples/vue/useHotkeySequences/src/index.css
  • packages/solid-hotkeys/tests/createHotkeySequences.test.tsx
✅ Files skipped from review due to trivial changes (23)
  • docs/framework/angular/guides/sequences.md
  • docs/framework/preact/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/svelte/reference/functions/createHotkeySequences.md
  • docs/framework/react/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/svelte/reference/functions/createHotkeySequencesAttachment.md
  • docs/framework/angular/reference/interfaces/InjectHotkeySequenceDefinition.md
  • .changeset/plural-sequences.md
  • examples/svelte/create-hotkey-sequences/README.md
  • docs/framework/react/reference/functions/useHotkeySequences.md
  • docs/framework/angular/reference/functions/injectHotkeySequences.md
  • docs/framework/vue/reference/interfaces/UseHotkeySequenceDefinition.md
  • docs/framework/svelte/reference/interfaces/CreateHotkeySequenceDefinition.md
  • examples/react/useHotkeySequences/src/index.css
  • docs/framework/solid/reference/functions/createHotkeySequences.md
  • examples/solid/createHotkeySequences/src/index.tsx
  • examples/angular/injectHotkeySequences/src/styles.css
  • examples/preact/useHotkeySequences/src/index.css
  • docs/framework/preact/reference/functions/useHotkeySequences.md
  • docs/framework/vue/reference/functions/useHotkeySequences.md
  • docs/framework/solid/reference/interfaces/CreateHotkeySequenceDefinition.md
  • examples/solid/createHotkeySequences/src/index.css
  • examples/svelte/create-hotkey-sequences/src/index.css
  • examples/vue/useHotkeySequences/src/index.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/angular/injectHotkeySequences/src/app/app.component.ts


// In constructor or injection context:
injectHotkeySequences([
{{ '{' }} sequence: ['G', 'G'], callback: () => scrollToTop() {{ '}' }},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Escape arrow function > characters in the code example.

The > in arrow functions should be escaped as &gt; for strict HTML compliance within the <pre> block. You've already escaped @ as &#64; on line 108, but the > characters on lines 112, 115, 118, and 121 also need escaping.

🔧 Proposed fix
 injectHotkeySequences([
-  { sequence: ['G', 'G'], callback: () => scrollToTop() },
+  { sequence: ['G', 'G'], callback: () =&gt; scrollToTop() },
   {
     sequence: ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown'],
-    callback: () => activateCheatMode(),
+    callback: () =&gt; activateCheatMode(),
     options: { timeout: 1500 },
   },
-  { sequence: ['C', 'I', 'W'], callback: () => changeInnerWord() },
-  { sequence: ['Shift+R', 'Shift+T'], callback: () => doSomething() },
+  { sequence: ['C', 'I', 'W'], callback: () =&gt; changeInnerWord() },
+  { sequence: ['Shift+R', 'Shift+T'], callback: () =&gt; doSomething() },
 ])

Also applies to: 115-115, 118-118, 121-121

🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 112-112: Special characters must be escaped : [ > ].

(spec-char-escape)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/angular/injectHotkeySequences/src/app/app.component.html` at line
112, Escape the '>' in arrow functions inside the HTML example: replace each
arrow token "=>" in the callback expressions with "=&gt;" so the snippets like
"callback: () => scrollToTop()" become "callback: () =&gt; scrollToTop()"; apply
the same change for the other occurrences referenced (lines containing the
callback arrow at the sequence entries on the same block).

⚠️ Potential issue | 🟡 Minor

Fix inconsistency between table and code example.

The table at lines 22-24 shows g g (lowercase) for "Go to top", but the code example uses ['G', 'G'] (uppercase). In Vim semantics, gg goes to top and G goes to bottom. The code example should use ['g', 'g'] to match the documented behavior.

📝 Proposed fix
 injectHotkeySequences([
-  { sequence: ['G', 'G'], callback: () => scrollToTop() },
+  { sequence: ['g', 'g'], callback: () => scrollToTop() },
   {
🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 112-112: Special characters must be escaped : [ > ].

(spec-char-escape)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/angular/injectHotkeySequences/src/app/app.component.html` at line
112, The code example uses uppercase sequence ['G','G'] but the docs/table
describe lowercase "g g" (Vim semantics: gg -> top); update the sequence in the
example (the object containing "sequence: ['G','G'], callback: () =>
scrollToTop()") to use lowercase ['g','g'] so the example matches the table and
expected behavior.

Comment on lines +1 to +3
import type { ApplicationConfig } from '@angular/core'
import { provideZoneChangeDetection } from '@angular/core'
import { provideHotkeys } from '@tanstack/angular-hotkeys'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix import order to satisfy ESLint.

The type import from @angular/core should be placed after regular imports per the project's import/order rule.

📝 Proposed fix
-import type { ApplicationConfig } from '@angular/core'
 import { provideZoneChangeDetection } from '@angular/core'
 import { provideHotkeys } from '@tanstack/angular-hotkeys'
+import type { ApplicationConfig } from '@angular/core'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import type { ApplicationConfig } from '@angular/core'
import { provideZoneChangeDetection } from '@angular/core'
import { provideHotkeys } from '@tanstack/angular-hotkeys'
import { provideZoneChangeDetection } from '@angular/core'
import { provideHotkeys } from '@tanstack/angular-hotkeys'
import type { ApplicationConfig } from '@angular/core'
🧰 Tools
🪛 ESLint

[error] 1-1: @angular/core type import should occur after import of @tanstack/angular-hotkeys

(import/order)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/angular/injectHotkeySequences/src/app/app.config.ts` around lines 1
- 3, Reorder the imports so the regular imports come before the type-only
import: place the existing `import { provideZoneChangeDetection } from
'@angular/core'` and `import { provideHotkeys } from
'@tanstack/angular-hotkeys'` first, and then move the type import `import type {
ApplicationConfig } from '@angular/core'` after them to satisfy the project's
`import/order` ESLint rule; update any references to `ApplicationConfig`,
`provideZoneChangeDetection`, or `provideHotkeys` accordingly.

Comment on lines +5 to +8
import { createSignal } from 'solid-js'
import type { Component } from 'solid-js'
import { createHotkeySequences } from '../src/createHotkeySequences'
import type { CreateHotkeySequenceDefinition } from '../src/createHotkeySequences'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Import order still violates ESLint import/order rule.

The value import from ../src/createHotkeySequences (line 7) should occur before the type import from solid-js (line 6). Group all value imports together, then all type imports.

Proposed fix
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
 import { render } from '@solidjs/testing-library'
 import { SequenceManager } from '@tanstack/hotkeys'
 import { createSignal } from 'solid-js'
-import type { Component } from 'solid-js'
 import { createHotkeySequences } from '../src/createHotkeySequences'
+import type { Component } from 'solid-js'
 import type { CreateHotkeySequenceDefinition } from '../src/createHotkeySequences'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { createSignal } from 'solid-js'
import type { Component } from 'solid-js'
import { createHotkeySequences } from '../src/createHotkeySequences'
import type { CreateHotkeySequenceDefinition } from '../src/createHotkeySequences'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { render } from '@solidjs/testing-library'
import { SequenceManager } from '@tanstack/hotkeys'
import { createSignal } from 'solid-js'
import { createHotkeySequences } from '../src/createHotkeySequences'
import type { Component } from 'solid-js'
import type { CreateHotkeySequenceDefinition } from '../src/createHotkeySequences'
🧰 Tools
🪛 ESLint

[error] 7-7: ../src/createHotkeySequences import should occur before type import of solid-js

(import/order)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/solid-hotkeys/tests/createHotkeySequences.test.tsx` around lines 5 -
8, The import order violates ESLint import/order: move all value imports
(createSignal from 'solid-js' and createHotkeySequences from
'../src/createHotkeySequences') before type-only imports, and group type imports
together (Component from 'solid-js' and CreateHotkeySequenceDefinition from
'../src/createHotkeySequences'); update the import statements so value imports
appear first then type imports to satisfy the rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant