Skip to content

feat: add lit dapater packages#59

Open
fredericbahr wants to merge 3 commits intoTanStack:mainfrom
fredericbahr:feat-lit-adapter
Open

feat: add lit dapater packages#59
fredericbahr wants to merge 3 commits intoTanStack:mainfrom
fredericbahr:feat-lit-adapter

Conversation

@fredericbahr
Copy link

@fredericbahr fredericbahr commented Mar 9, 2026

🎯 Changes

Add Lit Adapter for Hotkeys

✅ 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

    • Introduced @tanstack/lit-hotkeys package with Lit framework support for keyboard hotkey management.
    • Added decorators for binding keyboard shortcuts and sequences to component methods.
    • Added reactive controllers for lifecycle-managed hotkey registration.
  • Examples

    • Added two example projects demonstrating basic hotkey usage and keyboard sequence patterns (e.g., Vim-style key combinations).
  • Documentation

    • Added comprehensive README and CHANGELOG for the new lit-hotkeys package.
  • Tests

    • Added test suite covering hotkey registration, state management, and event handling.

@fredericbahr fredericbahr changed the title feat: add lit dapater packages Draft: feat: add lit dapater packages Mar 9, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c2183d968

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}

// Register the hotkey
registration = manager.register(sequence, descriptor as HotkeyCallback, {

Choose a reason for hiding this comment

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

P1 Badge Register the decorated method instead of the descriptor object

hotkeySequence currently passes descriptor to manager.register as if it were a callback, but SequenceManager later invokes registration.callback(event, context), so sequence matches will fail at runtime with a non-function callback. This should register the method function (typically descriptor.value) bound to the current element instance, otherwise @hotkeySequence is effectively broken.

Useful? React with 👍 / 👎.

proto.disconnectedCallback = function () {
originalDisconnected.call(this)

if (registration.isActive) {

Choose a reason for hiding this comment

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

P1 Badge Check registration exists before reading isActive on teardown

connectedCallback can return before registration is created (for example when target resolves to null, or in environments without document), but disconnectedCallback always reads registration.isActive. In those cases teardown throws because registration is undefined, so components that intentionally skip registration crash on disconnect.

Useful? React with 👍 / 👎.

const originalConnected = proto.connectedCallback
const originalDisconnected = proto.disconnectedCallback

let registration: HotkeyRegistrationHandle

Choose a reason for hiding this comment

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

P1 Badge Track hotkey registration per element instance

The registration handle is stored in decorator closure state on the prototype, so all instances of a decorated component share one mutable handle. When multiple instances mount, later mounts overwrite earlier handles; unmounting one instance can unregister another instance’s hotkey and leak the first one. Store registrations on this (or a WeakMap keyed by instance) so lifecycle cleanup is instance-safe.

Useful? React with 👍 / 👎.

@KevinVandy KevinVandy changed the title Draft: feat: add lit dapater packages feat: add lit dapater packages Mar 16, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 16, 2026

Open in StackBlitz

@tanstack/angular-hotkeys

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

@tanstack/hotkeys

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

@tanstack/hotkeys-devtools

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

@tanstack/lit-hotkeys

npm i https://pkg.pr.new/TanStack/hotkeys/@tanstack/lit-hotkeys@59

@tanstack/preact-hotkeys

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

@tanstack/preact-hotkeys-devtools

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

@tanstack/react-hotkeys

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

@tanstack/react-hotkeys-devtools

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

@tanstack/solid-hotkeys

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

@tanstack/solid-hotkeys-devtools

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

@tanstack/svelte-hotkeys

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

@tanstack/vue-hotkeys

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

@tanstack/vue-hotkeys-devtools

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

commit: 73d9560

@changeset-bot
Copy link

changeset-bot bot commented Mar 16, 2026

⚠️ No Changeset found

Latest commit: d4c8760

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

Introduces a new @tanstack/lit-hotkeys package providing Lit element controllers and decorators for integrating TanStack hotkeys. Includes two example projects demonstrating basic hotkey and hotkey-sequence functionality, comprehensive test coverage, configuration files, and documentation. Adds minor dependency override at root level.

Changes

Cohort / File(s) Summary
Example: hotkey-sequence
examples/lit/hotkey-sequence/.gitignore, examples/lit/hotkey-sequence/index.html, examples/lit/hotkey-sequence/package.json, examples/lit/hotkey-sequence/tsconfig.json, examples/lit/hotkey-sequence/src/app.ts, examples/lit/hotkey-sequence/src/index.css
New Lit demo project showcasing Vim-style keyboard sequences, fun sequence handlers, history tracking, and sequence-based interaction patterns. Includes HTML entry, package config, TypeScript setup, styled component with state management, and CSS styling.
Example: hotkey
examples/lit/hotkey/index.html, examples/lit/hotkey/package.json, examples/lit/hotkey/tsconfig.json, examples/lit/hotkey/src/app.ts, examples/lit/hotkey/src/index.css
New Lit demo project demonstrating hotkey patterns: basic shortcuts, conditional hotkeys, number keys, navigation, function keys, multi-modifier combinations, and scoped hotkeys within a modal editor. Includes HTML setup, package config, TypeScript configuration, full component implementation with counter state, and comprehensive styling.
Package core: controllers & decorators
packages/lit-hotkeys/src/constants.ts, packages/lit-hotkeys/src/controllers/hotkey.ts, packages/lit-hotkeys/src/controllers/hotkey-sequence.ts, packages/lit-hotkeys/src/controllers/held-keys.ts, packages/lit-hotkeys/src/controllers/key-hold.ts, packages/lit-hotkeys/src/controllers/index.ts, packages/lit-hotkeys/src/decorators/hotkey.ts, packages/lit-hotkeys/src/decorators/hotkey-sequence.ts, packages/lit-hotkeys/src/decorators/index.ts, packages/lit-hotkeys/src/index.ts
Core library implementation with two ReactiveControllers (HotkeyController, HotkeySequenceController) managing hotkey registration/unregistration lifecycle, two method decorators (@hotkey, @hotkeySequence) wrapping controllers for LitElement integration, default options, and barrel exports.
Package configuration & documentation
packages/lit-hotkeys/package.json, packages/lit-hotkeys/tsconfig.json, packages/lit-hotkeys/tsconfig.docs.json, packages/lit-hotkeys/tsdown.config.ts, packages/lit-hotkeys/vitest.config.ts, packages/lit-hotkeys/eslint.config.js, packages/lit-hotkeys/CHANGELOG.md, packages/lit-hotkeys/README.md
Project metadata, TypeScript configurations for build and docs, tsdown bundler setup (ESM/CJS, sourcemaps, type definitions), Vitest test runner config, ESLint extension, and documentation including changelog with version history and feature overview with TanStack ecosystem context.
Package tests
packages/lit-hotkeys/tests/useHotkey.test.tsx
React hook test suite (useHotkey) covering registration lifecycle, hotkey matching, event type variations, state closure correctness, enabled flag synchronization, and target resolution with HotkeyManager isolation between tests.
Root configuration
package.json
Adds pnpm dependency override pinning rolldown to version 1.0.0-rc.8.

Sequence Diagram

sequenceDiagram
    participant LitEl as LitElement<br/>(with `@hotkey`)
    participant Decorator as `@hotkey`<br/>Decorator
    participant Controller as HotkeyController
    participant Manager as HotkeyManager
    participant Browser as Browser<br/>KeyEvent
    
    LitEl->>Decorator: Class decorated with `@hotkey`
    LitEl->>LitEl: connectedCallback()
    LitEl->>Decorator: hostConnected triggered
    Decorator->>Controller: new HotkeyController(...)
    Decorator->>LitEl: addController(controller)
    Controller->>Manager: registerHotkey(hotkey, target, callback)
    Manager->>Manager: Store registration handle
    
    Browser->>Manager: KeyboardEvent fires
    Manager->>Manager: Match hotkey pattern
    Manager->>Controller: Invoke callback
    Controller->>LitEl: Execute decorated method
    
    LitEl->>LitEl: disconnectedCallback()
    Controller->>Manager: unregisterHotkey()
    Manager->>Manager: Remove registration handle
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A web of hotkeys, lit with Lit so bright,
Controllers dancing through the React-less night,
Decorators bind the keys to element's soul,
Sequences unfold, Vim-blessed and whole,
From ctrl\+s to gg, your shortcuts take flight! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'feat: add lit dapater packages' has a typo ('dapater' should be 'adapter') and is related to the main change, but the typo makes it less professional and clear. Correct the typo in the title from 'dapater' to 'adapter' to improve clarity: 'feat: add lit adapter packages'.
Description check ❓ Inconclusive The PR description follows the template structure with the required sections, but the 'Changes' section is incomplete with only a brief title 'Add Lit Adapter for Hotkeys' and no detailed explanation of what was changed or why, and all checklist items are unchecked. Complete the 'Changes' section with detailed descriptions of the modifications, and check relevant checklist items to indicate completion of required steps.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

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: 9

🧹 Nitpick comments (7)
examples/lit/hotkey-sequence/src/index.css (2)

137-149: Add explicit keyboard focus styling for buttons.

You already style hover; adding :focus-visible keeps keyboard navigation clear and consistent.

Suggested patch
 button:hover {
   background: `#0052a3`;
 }
+
+button:focus-visible {
+  outline: 2px solid `#0066cc`;
+  outline-offset: 2px;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/lit/hotkey-sequence/src/index.css` around lines 137 - 149, Add
explicit keyboard focus styling for the existing button rules: implement a
focus-visible style for the button selector (e.g., target button:focus-visible)
that provides a clear outline or box-shadow and visible contrast (and optionally
include a fallback button:focus for browsers without focus-visible) so keyboard
users see focused state consistent with the hover state; update the rules near
the existing button and button:hover selectors to include these focus styles
while keeping current colors and rounded corners.

93-97: Increase hint text contrast for readability.

This hint style is quite low-contrast at small size; darkening it a bit improves legibility without changing layout.

Suggested patch
 .hint {
   font-size: 12px;
-  color: `#888`;
+  color: `#666`;
   font-style: italic;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/lit/hotkey-sequence/src/index.css` around lines 93 - 97, The .hint
rule in examples/lit/hotkey-sequence/src/index.css uses a low-contrast color
(`#888`) that reduces readability at small sizes; update the .hint CSS rule to use
a darker color (for example `#666` or `#444`) to improve contrast while keeping
font-size and font-style the same so layout is unaffected.
examples/lit/hotkey-sequence/package.json (1)

14-14: Update dependency to use workspace protocol to ensure example consumes local package.

The example currently uses "@tanstack/lit-hotkeys": "^0.4.0", which may resolve to a published version from npm rather than the local workspace package. To dogfood current branch changes, use workspace:* or workspace:^ instead.

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

In `@examples/lit/hotkey-sequence/package.json` at line 14, Update the dependency
entry for "@tanstack/lit-hotkeys" in the example's package.json to use the
workspace protocol so it consumes the local package instead of the published npm
version; replace the version string "^0.4.0" with a workspace spec such as
"workspace:*" (or "workspace:^" if you want caret behavior) to ensure the
example dogfoods the local package.
examples/lit/hotkey/src/app.ts (1)

410-420: Arrow function property vs method for hotkey handlers.

Using arrow function class properties (like _handleSaving) with decorators can have subtle differences from regular methods. The decorator accesses descriptor?.value which may be undefined for arrow function properties since they're initialized in the constructor, not defined on the prototype.

The fallback host[propertyKey] on line 52 of the decorator handles this, but it's worth noting the inconsistency across handlers (some use arrow functions, some use methods).

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

In `@examples/lit/hotkey/src/app.ts` around lines 410 - 420, The _handleSaving
handler is defined as an arrow function property which may not appear on the
prototype for the hotkey decorator to inspect (descriptor?.value can be
undefined); convert _handleSaving into a normal class method (e.g., private
_handleSaving(event: KeyboardEvent, ctx: HotkeyCallbackContext) { ... }) so the
decorator can access it via the descriptor, and update any usages that relied on
lexical binding (if necessary bind in constructor or use the decorator
fallback). Ensure consistency with other handlers by making them methods too so
the decorator's descriptor-based logic works uniformly.
packages/lit-hotkeys/src/decorators/hotkey.ts (1)

29-32: Default options are replaced, not merged.

When a user passes partial options like { requireReset: true }, the entire HOTKEY_DEFAULT_OPTIONS object is replaced rather than merged. This means other sensible defaults (e.g., preventDefault: true) won't apply unless explicitly provided.

Consider spreading defaults:

♻️ Proposed fix to merge defaults
 export function hotkey(
   hotkey: RegisterableHotkey,
-  options: HotkeyOptions = HOTKEY_DEFAULT_OPTIONS,
+  options: Partial<HotkeyOptions> = {},
 ) {
+  const mergedOptions: HotkeyOptions = { ...HOTKEY_DEFAULT_OPTIONS, ...options }
   return function <T extends HotkeyCallback>(
     ...
         const controller: HotkeyController = new HotkeyController(
           this,
           hotkey,
           callback,
-          options,
+          mergedOptions,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/src/decorators/hotkey.ts` around lines 29 - 32, The
hotkey function currently replaces HOTKEY_DEFAULT_OPTIONS when callers pass
partial HotkeyOptions; update the function to merge defaults with provided
options so missing keys keep defaults (e.g., combine HOTKEY_DEFAULT_OPTIONS and
the incoming options before using them). Locate the hotkey function and ensure
you merge HOTKEY_DEFAULT_OPTIONS with the parameter named options (or set a
mergedOptions local variable) so flags like preventDefault remain true unless
explicitly overridden; keep the parameter type HotkeyOptions and use the merged
result throughout the function.
packages/lit-hotkeys/src/controllers/hotkey-sequence.ts (1)

48-78: Consider the same default options merging pattern.

Similar to the @hotkey decorator, the constructor uses options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS which replaces rather than merges. When users provide partial options like { timeout: 500 }, other defaults won't apply.

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

In `@packages/lit-hotkeys/src/controllers/hotkey-sequence.ts` around lines 48 -
78, The current logic in hostConnected relies on this.options but the
constructor used options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS which overwrites
defaults; instead merge user options with HOTKEY_SEQUENCE_DEFAULT_OPTIONS so
missing defaults remain (use something like mergedOptions = {
...HOTKEY_SEQUENCE_DEFAULT_OPTIONS, ...this.options }), then use mergedOptions
when extracting enabled/target and when passing options to manager.register;
update references in hostConnected (replace uses of this.options with
mergedOptions) and ensure target resolution and optionsWithoutTarget are derived
from the merged object.
packages/lit-hotkeys/src/decorators/hotkey-sequence.ts (1)

34-37: Inconsistency: descriptor is required here but optional in @hotkey.

In hotkey.ts line 36, descriptor is TypedPropertyDescriptor<T> | undefined, allowing the decorator to work on both methods and class field properties. Here it's required, which may cause issues when decorating arrow function class fields.

♻️ Proposed fix for consistency
   return function <T extends HotkeyCallback>(
     proto: LitElement,
     methodName: string,
-    descriptor: TypedPropertyDescriptor<T>,
+    descriptor?: TypedPropertyDescriptor<T>,
   ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/src/decorators/hotkey-sequence.ts` around lines 34 - 37,
The decorator's inner function currently requires descriptor but should accept
an optional descriptor to match `@hotkey` and support arrow-function class fields;
change the signature in the returned function to accept descriptor?:
TypedPropertyDescriptor<T> | undefined (or descriptor:
TypedPropertyDescriptor<T> | undefined) and then update any code that
reads/writes descriptor.value or descriptor.initializer to safely handle
descriptor being undefined (create/assign a proper descriptor when decorating a
class field or use proto[methodName] fallback). Ensure the returned function
(the decorator in hotkey-sequence.ts) mirrors the optional descriptor handling
used in hotkey.ts so both method and field/arrow-function decorations work
consistently.
🤖 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/lit/hotkey/package.json`:
- Around line 13-15: Replace the external semver for the internal package
`@tanstack/lit-hotkeys` in the example package.json (currently "^0.4.0") with the
workspace protocol "workspace:*" so pnpm resolves the local package; make the
same change for the other lit example's package.json (the hotkey-sequence
example) to ensure both use "workspace:*" for `@tanstack/lit-hotkeys`.

In `@examples/lit/hotkey/src/app.ts`:
- Around line 523-528: The hotkey decorator value and the displayed lastHotkey
are inconsistent in the _f4 handler: `@hotkey`('Meta+F4') registers Meta+F4 but
the handler sets this.lastHotkey = 'Alt+F4' (method _f4), causing UI confusion;
fix by making the two match—either change the decorator on _f4 to
`@hotkey`('Alt+F4') to match the UI and alert text, or update this.lastHotkey and
the alert text to 'Meta+F4' so they consistently reflect the registered hotkey.

In `@packages/lit-hotkeys/CHANGELOG.md`:
- Around line 1-111: The CHANGELOG.md currently has the wrong package header
"@tanstack/react-hotkeys" and mismatched entries for this package; update the
file (CHANGELOG.md) to target "lit-hotkeys" by replacing the title string and
regenerating or replacing the changelog content with the correct lit-hotkeys
release history, ensuring the top-level header reads "lit-hotkeys" (or the
package's exact name) and entries correspond to lit-hotkeys releases rather than
`@tanstack/react-hotkeys`.

In `@packages/lit-hotkeys/src/controllers/hotkey-sequence.ts`:
- Line 72: Remove the debug console.log call that prints 'optionsWithoutTarget'
in the HotkeySequence controller (the line referencing this.sequence and
optionsWithoutTarget); locate the statement in the hotkey-sequence.ts
implementation (inside the HotkeySequence class / relevant method where
this.sequence and optionsWithoutTarget are used) and delete that console.log so
no debug output remains in production.

In `@packages/lit-hotkeys/src/controllers/hotkey.ts`:
- Around line 47-74: HOTKEY_DEFAULT_OPTIONS must be made server-safe by removing
any module-scope reference to document (e.g., change the default target from
document to undefined or null in packages/lit-hotkeys/src/constants.ts) and keep
hostConnected() as the place that chooses document at runtime; then ensure
hostConnected() uses the existing runtime check ('target' in this.options ?
(this.options.target ?? null) : typeof document !== "undefined" ? document :
null) to lazily resolve to document only when typeof document !== "undefined" so
that HOTKEY_DEFAULT_OPTIONS, HotkeyOptions, and the hostConnected() logic no
longer import a browser global at module load (adjust HotkeyOptions type if
needed to allow undefined/null for options.target).

In `@packages/lit-hotkeys/src/index.ts`:
- Line 4: The comment "// React-specific exports" is stale and misleading for
this Lit-focused package; update that comment in
packages/lit-hotkeys/src/index.ts by replacing the exact string "//
React-specific exports" with a Lit-appropriate comment such as "// Lit-specific
exports" or "// Exports for Lit / LitElement consumers" so the comment
accurately reflects the package intent and exports.

In `@packages/lit-hotkeys/tsconfig.json`:
- Around line 2-4: The package tsconfig is missing experimental decorators which
breaks compilation of the legacy decorator syntax used by `@hotkey` and
`@hotkeySequence` (they use TypedPropertyDescriptor parameters); open the
packages/lit-hotkeys tsconfig (the object containing
"extends"/"include"/"exclude") and add "experimentalDecorators": true under
compilerOptions so TypeScript accepts legacy decorators; ensure the
compilerOptions section exists (create it if needed) and keep other options
intact.

In `@packages/lit-hotkeys/vitest.config.ts`:
- Around line 2-6: The vitest config incorrectly imports and applies the React
Vite plugin; remove the import statement "import react from
'@vitejs/plugin-react'" and remove the react() entry from the plugins array in
the default export (the plugins field in the defineConfig block) so the Lit
package's tests do not load React-specific tooling; if a Lit-specific Vite
plugin is required, add that instead, otherwise leave plugins empty or only
include plugins actually declared in this package.json.

---

Nitpick comments:
In `@examples/lit/hotkey-sequence/package.json`:
- Line 14: Update the dependency entry for "@tanstack/lit-hotkeys" in the
example's package.json to use the workspace protocol so it consumes the local
package instead of the published npm version; replace the version string
"^0.4.0" with a workspace spec such as "workspace:*" (or "workspace:^" if you
want caret behavior) to ensure the example dogfoods the local package.

In `@examples/lit/hotkey-sequence/src/index.css`:
- Around line 137-149: Add explicit keyboard focus styling for the existing
button rules: implement a focus-visible style for the button selector (e.g.,
target button:focus-visible) that provides a clear outline or box-shadow and
visible contrast (and optionally include a fallback button:focus for browsers
without focus-visible) so keyboard users see focused state consistent with the
hover state; update the rules near the existing button and button:hover
selectors to include these focus styles while keeping current colors and rounded
corners.
- Around line 93-97: The .hint rule in
examples/lit/hotkey-sequence/src/index.css uses a low-contrast color (`#888`) that
reduces readability at small sizes; update the .hint CSS rule to use a darker
color (for example `#666` or `#444`) to improve contrast while keeping font-size and
font-style the same so layout is unaffected.

In `@examples/lit/hotkey/src/app.ts`:
- Around line 410-420: The _handleSaving handler is defined as an arrow function
property which may not appear on the prototype for the hotkey decorator to
inspect (descriptor?.value can be undefined); convert _handleSaving into a
normal class method (e.g., private _handleSaving(event: KeyboardEvent, ctx:
HotkeyCallbackContext) { ... }) so the decorator can access it via the
descriptor, and update any usages that relied on lexical binding (if necessary
bind in constructor or use the decorator fallback). Ensure consistency with
other handlers by making them methods too so the decorator's descriptor-based
logic works uniformly.

In `@packages/lit-hotkeys/src/controllers/hotkey-sequence.ts`:
- Around line 48-78: The current logic in hostConnected relies on this.options
but the constructor used options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS which
overwrites defaults; instead merge user options with
HOTKEY_SEQUENCE_DEFAULT_OPTIONS so missing defaults remain (use something like
mergedOptions = { ...HOTKEY_SEQUENCE_DEFAULT_OPTIONS, ...this.options }), then
use mergedOptions when extracting enabled/target and when passing options to
manager.register; update references in hostConnected (replace uses of
this.options with mergedOptions) and ensure target resolution and
optionsWithoutTarget are derived from the merged object.

In `@packages/lit-hotkeys/src/decorators/hotkey-sequence.ts`:
- Around line 34-37: The decorator's inner function currently requires
descriptor but should accept an optional descriptor to match `@hotkey` and support
arrow-function class fields; change the signature in the returned function to
accept descriptor?: TypedPropertyDescriptor<T> | undefined (or descriptor:
TypedPropertyDescriptor<T> | undefined) and then update any code that
reads/writes descriptor.value or descriptor.initializer to safely handle
descriptor being undefined (create/assign a proper descriptor when decorating a
class field or use proto[methodName] fallback). Ensure the returned function
(the decorator in hotkey-sequence.ts) mirrors the optional descriptor handling
used in hotkey.ts so both method and field/arrow-function decorations work
consistently.

In `@packages/lit-hotkeys/src/decorators/hotkey.ts`:
- Around line 29-32: The hotkey function currently replaces
HOTKEY_DEFAULT_OPTIONS when callers pass partial HotkeyOptions; update the
function to merge defaults with provided options so missing keys keep defaults
(e.g., combine HOTKEY_DEFAULT_OPTIONS and the incoming options before using
them). Locate the hotkey function and ensure you merge HOTKEY_DEFAULT_OPTIONS
with the parameter named options (or set a mergedOptions local variable) so
flags like preventDefault remain true unless explicitly overridden; keep the
parameter type HotkeyOptions and use the merged result throughout the function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1535cb6b-4154-4a0a-8ada-e423d6cf8f8a

📥 Commits

Reviewing files that changed from the base of the PR and between 75ce7c8 and d4c8760.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (31)
  • examples/lit/hotkey-sequence/.gitignore
  • examples/lit/hotkey-sequence/index.html
  • examples/lit/hotkey-sequence/package.json
  • examples/lit/hotkey-sequence/src/app.ts
  • examples/lit/hotkey-sequence/src/index.css
  • examples/lit/hotkey-sequence/tsconfig.json
  • examples/lit/hotkey/index.html
  • examples/lit/hotkey/package.json
  • examples/lit/hotkey/src/app.ts
  • examples/lit/hotkey/src/index.css
  • examples/lit/hotkey/tsconfig.json
  • package.json
  • packages/lit-hotkeys/CHANGELOG.md
  • packages/lit-hotkeys/README.md
  • packages/lit-hotkeys/eslint.config.js
  • packages/lit-hotkeys/package.json
  • packages/lit-hotkeys/src/constants.ts
  • packages/lit-hotkeys/src/controllers/held-keys.ts
  • packages/lit-hotkeys/src/controllers/hotkey-sequence.ts
  • packages/lit-hotkeys/src/controllers/hotkey.ts
  • packages/lit-hotkeys/src/controllers/index.ts
  • packages/lit-hotkeys/src/controllers/key-hold.ts
  • packages/lit-hotkeys/src/decorators/hotkey-sequence.ts
  • packages/lit-hotkeys/src/decorators/hotkey.ts
  • packages/lit-hotkeys/src/decorators/index.ts
  • packages/lit-hotkeys/src/index.ts
  • packages/lit-hotkeys/tests/useHotkey.test.tsx
  • packages/lit-hotkeys/tsconfig.docs.json
  • packages/lit-hotkeys/tsconfig.json
  • packages/lit-hotkeys/tsdown.config.ts
  • packages/lit-hotkeys/vitest.config.ts

Comment on lines +13 to +15
"dependencies": {
"@tanstack/lit-hotkeys": "^0.4.0",
"lit": "^3.3.1"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "All `@tanstack` dependency pins in examples:"
rg -nP '"@tanstack/[^"]+"\s*:\s*"[^"]+"' examples -g '**/package.json'

echo
echo "Lit example manifests specifically:"
for f in examples/lit/hotkey/package.json examples/lit/hotkey-sequence/package.json; do
  echo "---- $f"
  rg -nP '"@tanstack/lit-hotkeys"\s*:\s*"[^"]+"' "$f" || true
done

Repository: TanStack/hotkeys

Length of output: 7199


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Root package.json workspaces definition ==="
cat -n package.json | head -30

echo
echo "=== Check for workspace: protocol usage in examples ==="
rg -n 'workspace:\*' examples -g '**/package.json' || echo "No workspace:* found in examples"

echo
echo "=== Check root monorepo structure ==="
ls -la | grep -E 'package|npm|yarn'

echo
echo "=== Check for pnpm-workspace.yaml ==="
test -f pnpm-workspace.yaml && cat pnpm-workspace.yaml || echo "No pnpm-workspace.yaml"

echo
echo "=== Check for lerna.json ==="
test -f lerna.json && cat lerna.json || echo "No lerna.json"

Repository: TanStack/hotkeys

Length of output: 3154


Use workspace dependency protocol for the internal package in this example.

Both lit examples use ^0.4.0, which is also an older version than other framework examples (^0.4.1). In this pnpm monorepo with preferWorkspacePackages: true configured, dependencies should explicitly use the workspace:* protocol to guarantee local package resolution.

🔧 Proposed fix
   "dependencies": {
-    "@tanstack/lit-hotkeys": "^0.4.0",
+    "@tanstack/lit-hotkeys": "workspace:*",
     "lit": "^3.3.1"
   },

Apply the same fix to examples/lit/hotkey-sequence/package.json.

📝 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
"dependencies": {
"@tanstack/lit-hotkeys": "^0.4.0",
"lit": "^3.3.1"
"dependencies": {
"@tanstack/lit-hotkeys": "workspace:*",
"lit": "^3.3.1"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/lit/hotkey/package.json` around lines 13 - 15, Replace the external
semver for the internal package `@tanstack/lit-hotkeys` in the example
package.json (currently "^0.4.0") with the workspace protocol "workspace:*" so
pnpm resolves the local package; make the same change for the other lit
example's package.json (the hotkey-sequence example) to ensure both use
"workspace:*" for `@tanstack/lit-hotkeys`.

Comment on lines +523 to +528
@hotkey('Meta+F4')
private _f4 = () => {
this.lastHotkey = 'Alt+F4'
this.functionKeyCount++
alert('Alt+F4 pressed (normally closes window)')
}
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

Mismatch between decorator key and lastHotkey assignment.

Line 523 uses @hotkey('Meta+F4') but line 525 sets this.lastHotkey = 'Alt+F4'. The UI at line 181 displays "Alt+F4" but the actual hotkey registered is Meta+F4. This inconsistency could confuse users.

🐛 Proposed fix
-  `@hotkey`('Meta+F4')
+  `@hotkey`('Alt+F4')
   private _f4 = () => {
     this.lastHotkey = 'Alt+F4'
📝 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
@hotkey('Meta+F4')
private _f4 = () => {
this.lastHotkey = 'Alt+F4'
this.functionKeyCount++
alert('Alt+F4 pressed (normally closes window)')
}
`@hotkey`('Alt+F4')
private _f4 = () => {
this.lastHotkey = 'Alt+F4'
this.functionKeyCount++
alert('Alt+F4 pressed (normally closes window)')
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/lit/hotkey/src/app.ts` around lines 523 - 528, The hotkey decorator
value and the displayed lastHotkey are inconsistent in the _f4 handler:
`@hotkey`('Meta+F4') registers Meta+F4 but the handler sets this.lastHotkey =
'Alt+F4' (method _f4), causing UI confusion; fix by making the two match—either
change the decorator on _f4 to `@hotkey`('Alt+F4') to match the UI and alert text,
or update this.lastHotkey and the alert text to 'Meta+F4' so they consistently
reflect the registered hotkey.

Comment on lines +1 to +111
# @tanstack/react-hotkeys

## 0.4.0

### Minor Changes

- add angular adapter and upgrade packages ([#31](https://github.com/TanStack/hotkeys/pull/31))

### Patch Changes

- Updated dependencies [[`c173ed0`](https://github.com/TanStack/hotkeys/commit/c173ed079c6b0f282c9cf8dcb6d9523408eca5a0)]:
- @tanstack/hotkeys@0.4.0

## 0.3.3

### Patch Changes

- Updated dependencies [[`029f473`](https://github.com/TanStack/hotkeys/commit/029f4733e5e7ed8739cf17125d327c626e4bb1d0)]:
- @tanstack/hotkeys@0.3.3

## 0.3.2

### Patch Changes

- Updated dependencies [[`67decce`](https://github.com/TanStack/hotkeys/commit/67decced89ce5dc874c5559fefb46096e76e560b)]:
- @tanstack/hotkeys@0.3.2

## 0.3.1

### Patch Changes

- Updated dependencies [[`762cabf`](https://github.com/TanStack/hotkeys/commit/762cabfd6e765f6ced1efdacbbf296ead0a5a080)]:
- @tanstack/hotkeys@0.3.1

## 0.3.0

### Minor Changes

- feat: overhaul sequence-manager and hooks to be in feature parity with hotkey-manager. ([#21](https://github.com/TanStack/hotkeys/pull/21))

### Patch Changes

- Updated dependencies [[`7328e36`](https://github.com/TanStack/hotkeys/commit/7328e360f0e99b5374fb97c07e0f2a500d8e5b9c)]:
- @tanstack/hotkeys@0.3.0

## 0.2.0

### Minor Changes

- feat: upgrade tanstack store version ([#35](https://github.com/TanStack/hotkeys/pull/35))

### Patch Changes

- Updated dependencies [[`8ae6b64`](https://github.com/TanStack/hotkeys/commit/8ae6b64ef10b53186c367f594f81ecdec15071d7)]:
- @tanstack/hotkeys@0.2.0

## 0.1.3

### Patch Changes

- Updated dependencies [[`26a74d8`](https://github.com/TanStack/hotkeys/commit/26a74d8e3279766a5cddbc7e7f146af0557cfbb9)]:
- @tanstack/hotkeys@0.1.3

## 0.1.2

### Patch Changes

- Updated dependencies [[`54f550f`](https://github.com/TanStack/hotkeys/commit/54f550f1d2e47084ea11411d465780ede19fbdfa)]:
- @tanstack/hotkeys@0.1.2

## 0.1.1

### Patch Changes

- Updated dependencies [[`56d50ba`](https://github.com/TanStack/hotkeys/commit/56d50ba4595a7609b13a36376afdc46ba92fab29)]:
- @tanstack/hotkeys@0.1.1

## 0.1.0

### Minor Changes

- feat: smarter ignoreInputs default ([#10](https://github.com/TanStack/hotkeys/pull/10))

### Patch Changes

- Updated dependencies [[`8d4ad42`](https://github.com/TanStack/hotkeys/commit/8d4ad423b9c6de4f406505b08e7547a9112ceb41)]:
- @tanstack/hotkeys@0.1.0

## 0.0.3

### Patch Changes

- fix: rerun register when options.enabled is changed ([`3ada864`](https://github.com/TanStack/hotkeys/commit/3ada864e07d6a6fe46dd95162592b29e681f52d1))

## 0.0.2

### Patch Changes

- feat: initial release ([`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613))

- Updated dependencies [[`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613)]:
- @tanstack/hotkeys@0.0.2

## 0.0.1

### Patch Changes

- feat: TanStack Hotkeys ([#5](https://github.com/TanStack/hotkeys/pull/5))

- Updated dependencies [[`e16b529`](https://github.com/TanStack/hotkeys/commit/e16b52983d4bf4ba249668591e8fc7133fcf8b85)]:
- @tanstack/hotkeys@0.0.1
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

This changelog appears to target the wrong package and should be regenerated.

On Line 1, the title is @tanstack/react-hotkeys while this file is for packages/lit-hotkeys. The entries also look mismatched for lit-hotkeys history. Please regenerate or replace with the correct lit-hotkeys changelog content before release.

🔧 Minimal immediate fix for the header
-# `@tanstack/react-hotkeys`
+# `@tanstack/lit-hotkeys`
📝 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
# @tanstack/react-hotkeys
## 0.4.0
### Minor Changes
- add angular adapter and upgrade packages ([#31](https://github.com/TanStack/hotkeys/pull/31))
### Patch Changes
- Updated dependencies [[`c173ed0`](https://github.com/TanStack/hotkeys/commit/c173ed079c6b0f282c9cf8dcb6d9523408eca5a0)]:
- @tanstack/hotkeys@0.4.0
## 0.3.3
### Patch Changes
- Updated dependencies [[`029f473`](https://github.com/TanStack/hotkeys/commit/029f4733e5e7ed8739cf17125d327c626e4bb1d0)]:
- @tanstack/hotkeys@0.3.3
## 0.3.2
### Patch Changes
- Updated dependencies [[`67decce`](https://github.com/TanStack/hotkeys/commit/67decced89ce5dc874c5559fefb46096e76e560b)]:
- @tanstack/hotkeys@0.3.2
## 0.3.1
### Patch Changes
- Updated dependencies [[`762cabf`](https://github.com/TanStack/hotkeys/commit/762cabfd6e765f6ced1efdacbbf296ead0a5a080)]:
- @tanstack/hotkeys@0.3.1
## 0.3.0
### Minor Changes
- feat: overhaul sequence-manager and hooks to be in feature parity with hotkey-manager. ([#21](https://github.com/TanStack/hotkeys/pull/21))
### Patch Changes
- Updated dependencies [[`7328e36`](https://github.com/TanStack/hotkeys/commit/7328e360f0e99b5374fb97c07e0f2a500d8e5b9c)]:
- @tanstack/hotkeys@0.3.0
## 0.2.0
### Minor Changes
- feat: upgrade tanstack store version ([#35](https://github.com/TanStack/hotkeys/pull/35))
### Patch Changes
- Updated dependencies [[`8ae6b64`](https://github.com/TanStack/hotkeys/commit/8ae6b64ef10b53186c367f594f81ecdec15071d7)]:
- @tanstack/hotkeys@0.2.0
## 0.1.3
### Patch Changes
- Updated dependencies [[`26a74d8`](https://github.com/TanStack/hotkeys/commit/26a74d8e3279766a5cddbc7e7f146af0557cfbb9)]:
- @tanstack/hotkeys@0.1.3
## 0.1.2
### Patch Changes
- Updated dependencies [[`54f550f`](https://github.com/TanStack/hotkeys/commit/54f550f1d2e47084ea11411d465780ede19fbdfa)]:
- @tanstack/hotkeys@0.1.2
## 0.1.1
### Patch Changes
- Updated dependencies [[`56d50ba`](https://github.com/TanStack/hotkeys/commit/56d50ba4595a7609b13a36376afdc46ba92fab29)]:
- @tanstack/hotkeys@0.1.1
## 0.1.0
### Minor Changes
- feat: smarter ignoreInputs default ([#10](https://github.com/TanStack/hotkeys/pull/10))
### Patch Changes
- Updated dependencies [[`8d4ad42`](https://github.com/TanStack/hotkeys/commit/8d4ad423b9c6de4f406505b08e7547a9112ceb41)]:
- @tanstack/hotkeys@0.1.0
## 0.0.3
### Patch Changes
- fix: rerun register when options.enabled is changed ([`3ada864`](https://github.com/TanStack/hotkeys/commit/3ada864e07d6a6fe46dd95162592b29e681f52d1))
## 0.0.2
### Patch Changes
- feat: initial release ([`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613))
- Updated dependencies [[`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613)]:
- @tanstack/hotkeys@0.0.2
## 0.0.1
### Patch Changes
- feat: TanStack Hotkeys ([#5](https://github.com/TanStack/hotkeys/pull/5))
- Updated dependencies [[`e16b529`](https://github.com/TanStack/hotkeys/commit/e16b52983d4bf4ba249668591e8fc7133fcf8b85)]:
- @tanstack/hotkeys@0.0.1
# `@tanstack/lit-hotkeys`
## 0.4.0
### Minor Changes
- add angular adapter and upgrade packages ([`#31`](https://github.com/TanStack/hotkeys/pull/31))
### Patch Changes
- Updated dependencies [[`c173ed0`](https://github.com/TanStack/hotkeys/commit/c173ed079c6b0f282c9cf8dcb6d9523408eca5a0)]:
- `@tanstack/hotkeys`@0.4.0
## 0.3.3
### Patch Changes
- Updated dependencies [[`029f473`](https://github.com/TanStack/hotkeys/commit/029f4733e5e7ed8739cf17125d327c626e4bb1d0)]:
- `@tanstack/hotkeys`@0.3.3
## 0.3.2
### Patch Changes
- Updated dependencies [[`67decce`](https://github.com/TanStack/hotkeys/commit/67decced89ce5dc874c5559fefb46096e76e560b)]:
- `@tanstack/hotkeys`@0.3.2
## 0.3.1
### Patch Changes
- Updated dependencies [[`762cabf`](https://github.com/TanStack/hotkeys/commit/762cabfd6e765f6ced1efdacbbf296ead0a5a080)]:
- `@tanstack/hotkeys`@0.3.1
## 0.3.0
### Minor Changes
- feat: overhaul sequence-manager and hooks to be in feature parity with hotkey-manager. ([`#21`](https://github.com/TanStack/hotkeys/pull/21))
### Patch Changes
- Updated dependencies [[`7328e36`](https://github.com/TanStack/hotkeys/commit/7328e360f0e99b5374fb97c07e0f2a500d8e5b9c)]:
- `@tanstack/hotkeys`@0.3.0
## 0.2.0
### Minor Changes
- feat: upgrade tanstack store version ([`#35`](https://github.com/TanStack/hotkeys/pull/35))
### Patch Changes
- Updated dependencies [[`8ae6b64`](https://github.com/TanStack/hotkeys/commit/8ae6b64ef10b53186c367f594f81ecdec15071d7)]:
- `@tanstack/hotkeys`@0.2.0
## 0.1.3
### Patch Changes
- Updated dependencies [[`26a74d8`](https://github.com/TanStack/hotkeys/commit/26a74d8e3279766a5cddbc7e7f146af0557cfbb9)]:
- `@tanstack/hotkeys`@0.1.3
## 0.1.2
### Patch Changes
- Updated dependencies [[`54f550f`](https://github.com/TanStack/hotkeys/commit/54f550f1d2e47084ea11411d465780ede19fbdfa)]:
- `@tanstack/hotkeys`@0.1.2
## 0.1.1
### Patch Changes
- Updated dependencies [[`56d50ba`](https://github.com/TanStack/hotkeys/commit/56d50ba4595a7609b13a36376afdc46ba92fab29)]:
- `@tanstack/hotkeys`@0.1.1
## 0.1.0
### Minor Changes
- feat: smarter ignoreInputs default ([`#10`](https://github.com/TanStack/hotkeys/pull/10))
### Patch Changes
- Updated dependencies [[`8d4ad42`](https://github.com/TanStack/hotkeys/commit/8d4ad423b9c6de4f406505b08e7547a9112ceb41)]:
- `@tanstack/hotkeys`@0.1.0
## 0.0.3
### Patch Changes
- fix: rerun register when options.enabled is changed ([`3ada864`](https://github.com/TanStack/hotkeys/commit/3ada864e07d6a6fe46dd95162592b29e681f52d1))
## 0.0.2
### Patch Changes
- feat: initial release ([`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613))
- Updated dependencies [[`341d167`](https://github.com/TanStack/hotkeys/commit/341d16731f09709a463343852ae4c0e1b6bc6613)]:
- `@tanstack/hotkeys`@0.0.2
## 0.0.1
### Patch Changes
- feat: TanStack Hotkeys ([`#5`](https://github.com/TanStack/hotkeys/pull/5))
- Updated dependencies [[`e16b529`](https://github.com/TanStack/hotkeys/commit/e16b52983d4bf4ba249668591e8fc7133fcf8b85)]:
- `@tanstack/hotkeys`@0.0.1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/CHANGELOG.md` around lines 1 - 111, The CHANGELOG.md
currently has the wrong package header "@tanstack/react-hotkeys" and mismatched
entries for this package; update the file (CHANGELOG.md) to target "lit-hotkeys"
by replacing the title string and regenerating or replacing the changelog
content with the correct lit-hotkeys release history, ensuring the top-level
header reads "lit-hotkeys" (or the package's exact name) and entries correspond
to lit-hotkeys releases rather than `@tanstack/react-hotkeys`.

this.host as unknown as object,
)

console.log('optionsWithoutTarget', this.sequence, optionsWithoutTarget)
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

Remove debug console.log statement.

This appears to be a debug artifact that should be removed before merging.

🧹 Proposed fix
-    console.log('optionsWithoutTarget', this.sequence, optionsWithoutTarget)
-
     this._registration = manager.register(this.sequence, boundCallback, {
📝 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
console.log('optionsWithoutTarget', this.sequence, optionsWithoutTarget)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/src/controllers/hotkey-sequence.ts` at line 72, Remove
the debug console.log call that prints 'optionsWithoutTarget' in the
HotkeySequence controller (the line referencing this.sequence and
optionsWithoutTarget); locate the statement in the hotkey-sequence.ts
implementation (inside the HotkeySequence class / relevant method where
this.sequence and optionsWithoutTarget are used) and delete that console.log so
no debug output remains in production.

Comment on lines +47 to +74
private options: HotkeyOptions = HOTKEY_DEFAULT_OPTIONS,
) {}

/**
* Registers the hotkey with the global manager when the host is connected to the DOM.
* Skips registration if no target is available (e.g. no document or options.target is null).
*/
hostConnected(): void {
const manager: HotkeyManager = getHotkeyManager()

const platform = this.options.platform ?? detectPlatform()
const hotkeyString: Hotkey =
typeof this.hotkey === 'string'
? this.hotkey
: (formatHotkey(
rawHotkeyToParsedHotkey(this.hotkey, platform),
) as Hotkey)

const resolvedTarget =
'target' in this.options
? (this.options.target ?? null)
: typeof document !== 'undefined'
? document
: null

if (!resolvedTarget) {
return
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Resolve the default target lazily to keep SSR imports from crashing.

Line 47 defaults to HOTKEY_DEFAULT_OPTIONS, and packages/lit-hotkeys/src/constants.ts:3-13 currently defines target: document at module scope. On the server, importing this controller will throw before Lines 68-70 reach the typeof document guard. Keep the shared defaults free of browser globals and choose document inside hostConnected() only when it actually exists.

🐛 Proposed fix

Update packages/lit-hotkeys/src/constants.ts so the shared defaults stay server-safe:

 export const HOTKEY_DEFAULT_OPTIONS: HotkeyOptions = {
   enabled: true,
   preventDefault: true,
   stopPropagation: true,
   eventType: 'keydown',
   requireReset: false,
   ignoreInputs: undefined,
-  target: document,
+  target: undefined,
   platform: undefined,
   conflictBehavior: 'warn',
 }

Then resolve the fallback target lazily in this file:

-    const resolvedTarget =
-      'target' in this.options
-        ? (this.options.target ?? null)
-        : typeof document !== 'undefined'
-          ? document
-          : null
+    const resolvedTarget =
+      this.options.target !== undefined
+        ? this.options.target
+        : typeof document !== 'undefined'
+          ? document
+          : null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/src/controllers/hotkey.ts` around lines 47 - 74,
HOTKEY_DEFAULT_OPTIONS must be made server-safe by removing any module-scope
reference to document (e.g., change the default target from document to
undefined or null in packages/lit-hotkeys/src/constants.ts) and keep
hostConnected() as the place that chooses document at runtime; then ensure
hostConnected() uses the existing runtime check ('target' in this.options ?
(this.options.target ?? null) : typeof document !== "undefined" ? document :
null) to lazily resolve to document only when typeof document !== "undefined" so
that HOTKEY_DEFAULT_OPTIONS, HotkeyOptions, and the hostConnected() logic no
longer import a browser global at module load (adjust HotkeyOptions type if
needed to allow undefined/null for options.target).

// Re-export everything from the core package
export * from '@tanstack/hotkeys'

// React-specific exports
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 stale adapter comment (“React-specific exports”).

This package is Lit-focused; the current comment is misleading.

Suggested patch
-// React-specific exports
+// Lit-specific exports
 export * from './decorators'
 export * from './controllers'
📝 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
// React-specific exports
// Lit-specific exports
export * from './decorators'
export * from './controllers'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/src/index.ts` at line 4, The comment "// React-specific
exports" is stale and misleading for this Lit-focused package; update that
comment in packages/lit-hotkeys/src/index.ts by replacing the exact string "//
React-specific exports" with a Lit-appropriate comment such as "// Lit-specific
exports" or "// Exports for Lit / LitElement consumers" so the comment
accurately reflects the package intent and exports.

Comment on lines +3 to +6
import { renderHook, act } from '@testing-library/react'
import { HotkeyManager } from '@tanstack/hotkeys'
import { useHotkey } from '../src/useHotkey'
import { useState, useRef } from 'react'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

fd '^useHotkey\.(ts|tsx)$' packages/lit-hotkeys/src || true
rg -n --glob 'packages/lit-hotkeys/tests/**' "@testing-library/react|renderHook|from \"react\"|from 'react'" || true

Repository: TanStack/hotkeys

Length of output: 1099


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List contents of lit-hotkeys src directory
echo "=== Lit package source structure ==="
find packages/lit-hotkeys/src -type f -name "*.ts" -o -name "*.tsx" 2>/dev/null | head -20

echo ""
echo "=== All test files in lit-hotkeys tests ==="
find packages/lit-hotkeys/tests -type f -name "*.test.*" -o -name "*.spec.*" 2>/dev/null

echo ""
echo "=== Contents of lit-hotkeys package.json ==="
cat packages/lit-hotkeys/package.json | grep -A 20 '"dependencies"\|"devDependencies"\|"peerDependencies"' | head -30

Repository: TanStack/hotkeys

Length of output: 901


Replace this test file with Lit controller and decorator integration tests.

The test file imports and uses React testing utilities (@testing-library/react, renderHook, useState, useRef) to test a non-existent useHotkey hook, but packages/lit-hotkeys/src/ only contains Lit controllers and decorators (hotkey.ts, hotkey-sequence.ts, key-hold.ts, held-keys.ts). The test is fundamentally misaligned with the package purpose and will fail on import. Write tests for the actual Lit surface instead.

🧰 Tools
🪛 ESLint

[error] 3-3: Member 'act' of the import declaration should be sorted alphabetically.

(sort-imports)


[error] 6-6: react import should occur before import of ../src/useHotkey

(import/order)


[error] 6-6: Member 'useRef' of the import declaration should be sorted alphabetically.

(sort-imports)

Comment on lines +2 to +4
"extends": "../../tsconfig.json",
"include": ["src", "vitest.config.ts", "tests"],
"exclude": ["eslint.config.js"]
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm decorator compiler flag presence/absence
echo "Checking decorator compiler flags..."
rg -nP '"experimentalDecorators"\s*:' tsconfig.json packages/lit-hotkeys/tsconfig.json || true

# 2) Find legacy decorator typing patterns in lit-hotkeys sources
echo "Searching for legacy decorator signatures..."
rg -nP --type=ts 'TypedPropertyDescriptor|MethodDecorator|PropertyDecorator|ClassDecorator' packages/lit-hotkeys/src || true

# 3) Find decorator usage sites
echo "Searching for decorator usage..."
rg -nP --type=ts '^\s*@\w+' packages/lit-hotkeys/src || true

Repository: TanStack/hotkeys

Length of output: 370


🏁 Script executed:

# Check root tsconfig for experimentalDecorators
cat tsconfig.json | head -20

# Inspect the decorator implementations
echo "=== hotkey.ts ==="
cat packages/lit-hotkeys/src/decorators/hotkey.ts

echo ""
echo "=== hotkey-sequence.ts ==="
cat packages/lit-hotkeys/src/decorators/hotkey-sequence.ts

Repository: TanStack/hotkeys

Length of output: 4992


🏁 Script executed:

# Get full root tsconfig
cat tsconfig.json

# Also check the package tsconfig
echo ""
echo "=== packages/lit-hotkeys/tsconfig.json ==="
cat packages/lit-hotkeys/tsconfig.json

Repository: TanStack/hotkeys

Length of output: 1041


Enable legacy decorators in this package tsconfig.

This package uses legacy decorator syntax (@hotkey, @hotkeySequence) with TypedPropertyDescriptor parameters in the decorator implementations. Without experimentalDecorators: true, TypeScript will fail to compile or type-check these decorators. Add it under compilerOptions.

🔧 Proposed fix
 {
   "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "experimentalDecorators": true
+  },
   "include": ["src", "vitest.config.ts", "tests"],
   "exclude": ["eslint.config.js"]
 }
📝 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
"extends": "../../tsconfig.json",
"include": ["src", "vitest.config.ts", "tests"],
"exclude": ["eslint.config.js"]
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"experimentalDecorators": true
},
"include": ["src", "vitest.config.ts", "tests"],
"exclude": ["eslint.config.js"]
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/tsconfig.json` around lines 2 - 4, The package tsconfig
is missing experimental decorators which breaks compilation of the legacy
decorator syntax used by `@hotkey` and `@hotkeySequence` (they use
TypedPropertyDescriptor parameters); open the packages/lit-hotkeys tsconfig (the
object containing "extends"/"include"/"exclude") and add
"experimentalDecorators": true under compilerOptions so TypeScript accepts
legacy decorators; ensure the compilerOptions section exists (create it if
needed) and keep other options intact.

Comment on lines +2 to +6
import react from '@vitejs/plugin-react'
import packageJson from './package.json' with { type: 'json' }

export default defineConfig({
plugins: [react()],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if packages/lit-hotkeys exists and examine package.json
cd packages/lit-hotkeys 2>/dev/null && ls -la || echo "Directory check"

# Look at the package.json
fd "package.json" packages/lit-hotkeys -x cat {}

Repository: TanStack/hotkeys

Length of output: 928


🏁 Script executed:

# Check vitest.config.ts in lit-hotkeys
fd "vitest.config.ts" packages/lit-hotkeys -x cat -n {}

Repository: TanStack/hotkeys

Length of output: 545


🏁 Script executed:

# Check if `@vitejs/plugin-react` is referenced anywhere in lit-hotkeys package
rg "@vitejs/plugin-react" packages/lit-hotkeys/

Repository: TanStack/hotkeys

Length of output: 138


🏁 Script executed:

# Check the main package.json for lit-hotkeys dependencies and devDependencies
rg "\"(dependencies|devDependencies)\"" packages/lit-hotkeys/package.json -A 20

Repository: TanStack/hotkeys

Length of output: 261


🏁 Script executed:

cat packages/lit-hotkeys/README.md

Repository: TanStack/hotkeys

Length of output: 5962


🏁 Script executed:

# Also check if there are any .tsx or .jsx files in the lit-hotkeys source
fd "\.(tsx?|jsx?)$" packages/lit-hotkeys/src -type f

Repository: TanStack/hotkeys

Length of output: 230


🏁 Script executed:

# Check what's in the src directory
ls -la packages/lit-hotkeys/src/

Repository: TanStack/hotkeys

Length of output: 405


Remove the React Vite plugin from this Lit package's test configuration.

The vitest config imports and uses @vitejs/plugin-react (lines 2, 6), but @vitejs/plugin-react is not declared in packages/lit-hotkeys/package.json. This package is the Lit framework adapter for TanStack Hotkeys and declares lit as a peer and dev dependency—not React. The React plugin should not be applied to the Lit test harness.

♻️ Proposed fix
 import { defineConfig } from 'vitest/config'
-import react from '@vitejs/plugin-react'
 import packageJson from './package.json' with { type: 'json' }
 
 export default defineConfig({
-  plugins: [react()],
   test: {
     name: packageJson.name,
📝 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 react from '@vitejs/plugin-react'
import packageJson from './package.json' with { type: 'json' }
export default defineConfig({
plugins: [react()],
import packageJson from './package.json' with { type: 'json' }
export default defineConfig({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lit-hotkeys/vitest.config.ts` around lines 2 - 6, The vitest config
incorrectly imports and applies the React Vite plugin; remove the import
statement "import react from '@vitejs/plugin-react'" and remove the react()
entry from the plugins array in the default export (the plugins field in the
defineConfig block) so the Lit package's tests do not load React-specific
tooling; if a Lit-specific Vite plugin is required, add that instead, otherwise
leave plugins empty or only include plugins actually declared in this
package.json.

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.

2 participants