@tanstack/lit-hotkeys 0.18.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ //#region src/controllers/_server.ts
2
+ /**
3
+ * Whether the code runs on a server. With `@lit-labs/ssr`'s
4
+ * `connectedCallback: true` option, the server calls `hostConnected` and never
5
+ * calls `hostDisconnected`, so controllers must not subscribe there.
6
+ */
7
+ function isServer() {
8
+ return typeof document === "undefined";
9
+ }
10
+
11
+ //#endregion
12
+ export { isServer };
@@ -1,4 +1,5 @@
1
1
  import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
2
+ import { isServer } from "./_server.js";
2
3
  import { getHotkeyManager, toHotkeyRegistrationView } from "@tanstack/hotkeys";
3
4
 
4
5
  //#region src/controllers/app-hotkeys.ts
@@ -66,6 +67,7 @@ var AppHotkeysController = class {
66
67
  return requireStore().findConflicts(id, hotkey);
67
68
  }
68
69
  hostConnected() {
70
+ if (isServer()) return;
69
71
  const update = () => this._host.requestUpdate();
70
72
  const unsubscribeAppHotkeys = subscribeAppHotkeys(update);
71
73
  const registrations = getHotkeyManager().registrations.subscribe(update);
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { getKeyStateTracker } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/held-key-codes.ts
@@ -45,6 +46,7 @@ var HeldKeyCodesController = class {
45
46
  const tracker = getKeyStateTracker();
46
47
  this._value = tracker.store.state.heldCodes;
47
48
  this._host.requestUpdate();
49
+ if (isServer()) return;
48
50
  const subscription = tracker.store.subscribe(() => {
49
51
  const { heldCodes } = tracker.store.state;
50
52
  this._value = heldCodes;
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { getKeyStateTracker } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/held-keys.ts
@@ -41,6 +42,7 @@ var HeldKeysController = class {
41
42
  }
42
43
  /** Subscribes to the tracker store and updates the internal state when changes occur. */
43
44
  hostConnected() {
45
+ if (isServer()) return;
44
46
  const tracker = getKeyStateTracker();
45
47
  const subscription = tracker.store.subscribe(() => {
46
48
  const { heldKeys } = tracker.store.state;
@@ -1,4 +1,5 @@
1
1
  import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
2
+ import { isServer } from "./_server.js";
2
3
  import { getHotkeyManager, getKeyStateTracker, isAppHotkey, matchesHeldModifiers, resolveAppHotkey } from "@tanstack/hotkeys";
3
4
 
4
5
  //#region src/controllers/hotkey-hint.ts
@@ -31,6 +32,7 @@ var HotkeyHintController = class {
31
32
  hostConnected() {
32
33
  this.update();
33
34
  this.host.requestUpdate();
35
+ if (isServer()) return;
34
36
  const refresh = () => {
35
37
  if (this.update()) this.host.requestUpdate();
36
38
  };
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { HotkeyRecorder } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/hotkey-recorder.ts
@@ -75,6 +76,7 @@ var HotkeyRecorderController = class {
75
76
  }
76
77
  /** Subscribes to the recorder store and updates the internal state when changes occur. */
77
78
  hostConnected() {
79
+ if (isServer()) return;
78
80
  const subscription = this._recorder.store.subscribe(() => {
79
81
  const { isRecording, recordedHotkey, steps } = this._recorder.store.state;
80
82
  if (isRecording !== this._isRecording || recordedHotkey !== this._recordedHotkey || steps !== this._steps) {
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { getHotkeyManager, toHotkeyRegistrationView } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/hotkey-registrations.ts
@@ -36,12 +37,13 @@ var HotkeyRegistrationsController = class {
36
37
  hostConnected() {
37
38
  const manager = getHotkeyManager();
38
39
  const read = () => Array.from(manager.registrations.state.values()).map(toHotkeyRegistrationView);
40
+ this._hotkeys = read();
41
+ if (isServer()) return;
39
42
  const subscription = manager.registrations.subscribe(() => {
40
43
  this._hotkeys = read();
41
44
  this._host.requestUpdate();
42
45
  });
43
46
  this._unsubscribe = () => subscription.unsubscribe();
44
- this._hotkeys = read();
45
47
  }
46
48
  hostDisconnected() {
47
49
  this._unsubscribe?.();
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { getHotkeyManager } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/hotkey-scopes-state.ts
@@ -40,6 +41,7 @@ var HotkeyScopesStateController = class {
40
41
  */
41
42
  hostConnected() {
42
43
  this._host.requestUpdate();
44
+ if (isServer()) return;
43
45
  const subscription = getHotkeyManager().scopes.subscribe(() => this._host.requestUpdate());
44
46
  this._unsubscribe = () => subscription.unsubscribe();
45
47
  }
@@ -1,4 +1,5 @@
1
1
  import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
2
+ import { isServer } from "./_server.js";
2
3
  import { createHotkeyBindings, prepareHotkeyDefinitions } from "@tanstack/hotkeys/adapter";
3
4
 
4
5
  //#region src/controllers/hotkey.ts
@@ -42,6 +43,7 @@ var HotkeyController = class {
42
43
  }
43
44
  /** Registers when connected and a target is available. */
44
45
  hostConnected() {
46
+ if (isServer()) return;
45
47
  this._connected = true;
46
48
  this._unsubscribe = subscribeAppHotkeys(() => this._sync());
47
49
  this._sync();
@@ -5,7 +5,9 @@ import { ReactiveController, ReactiveControllerHost } from "lit";
5
5
  * A Lit ReactiveController that tracks whether a specific key is currently held.
6
6
  *
7
7
  * Subscribes to the global KeyStateTracker and triggers host updates
8
- * when the held state of the specified key changes.
8
+ * when the held state of the specified key changes. Pass a getter to track a
9
+ * key that changes, such as a reactive property; it is read again on each
10
+ * host update.
9
11
  *
10
12
  * @example
11
13
  * ```ts
@@ -50,10 +52,14 @@ export declare class KeyHoldController implements ReactiveController {
50
52
  get value(): boolean;
51
53
  /**
52
54
  * @param _host - The Lit component that owns this controller.
53
- * @param _key - The key to track (e.g. 'Shift', 'Control', 'A').
55
+ * @param _key - The key to track (e.g. 'Shift', 'Control', 'A'), or a getter.
54
56
  */
55
- constructor(_host: ReactiveControllerHost, _key: IndividualKey);
57
+ constructor(_host: ReactiveControllerHost, _key: IndividualKey | (() => IndividualKey));
56
58
  hostConnected(): void;
59
+ /** Re-reads a getter key when host properties trigger an update. */
60
+ hostUpdate(): void;
57
61
  hostDisconnected(): void;
62
+ /** Recomputes the held state and reports whether it changed. */
63
+ private _refresh;
58
64
  }
59
65
  //#endregion
@@ -1,3 +1,4 @@
1
+ import { isServer } from "./_server.js";
1
2
  import { getKeyStateTracker } from "@tanstack/hotkeys";
2
3
 
3
4
  //#region src/controllers/key-hold.ts
@@ -5,7 +6,9 @@ import { getKeyStateTracker } from "@tanstack/hotkeys";
5
6
  * A Lit ReactiveController that tracks whether a specific key is currently held.
6
7
  *
7
8
  * Subscribes to the global KeyStateTracker and triggers host updates
8
- * when the held state of the specified key changes.
9
+ * when the held state of the specified key changes. Pass a getter to track a
10
+ * key that changes, such as a reactive property; it is read again on each
11
+ * host update.
9
12
  *
10
13
  * @example
11
14
  * ```ts
@@ -52,7 +55,7 @@ var KeyHoldController = class {
52
55
  }
53
56
  /**
54
57
  * @param _host - The Lit component that owns this controller.
55
- * @param _key - The key to track (e.g. 'Shift', 'Control', 'A').
58
+ * @param _key - The key to track (e.g. 'Shift', 'Control', 'A'), or a getter.
56
59
  */
57
60
  constructor(_host, _key) {
58
61
  this._host = _host;
@@ -60,22 +63,30 @@ var KeyHoldController = class {
60
63
  this._host.addController(this);
61
64
  }
62
65
  hostConnected() {
63
- const tracker = getKeyStateTracker();
64
- const normalizedKey = this._key.toLowerCase();
65
- const subscription = tracker.store.subscribe(() => {
66
- const isHeld = tracker.store.state.heldKeys.some((heldKey) => heldKey.toLowerCase() === normalizedKey);
67
- if (isHeld !== this._value) {
68
- this._value = isHeld;
69
- this._host.requestUpdate();
70
- }
66
+ if (this._refresh()) this._host.requestUpdate();
67
+ if (isServer()) return;
68
+ const subscription = getKeyStateTracker().store.subscribe(() => {
69
+ if (this._refresh()) this._host.requestUpdate();
71
70
  });
72
71
  this._unsubscribe = () => subscription.unsubscribe();
73
72
  }
73
+ /** Re-reads a getter key when host properties trigger an update. */
74
+ hostUpdate() {
75
+ this._refresh();
76
+ }
74
77
  hostDisconnected() {
75
78
  this._unsubscribe?.();
76
79
  this._unsubscribe = void 0;
77
80
  this._value = false;
78
81
  }
82
+ /** Recomputes the held state and reports whether it changed. */
83
+ _refresh() {
84
+ const key = (typeof this._key === "function" ? this._key() : this._key).toLowerCase();
85
+ const next = getKeyStateTracker().store.state.heldKeys.some((heldKey) => heldKey.toLowerCase() === key);
86
+ const changed = next !== this._value;
87
+ this._value = next;
88
+ return changed;
89
+ }
79
90
  };
80
91
 
81
92
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/lit-hotkeys",
3
- "version": "0.18.0",
3
+ "version": "0.18.1",
4
4
  "description": "Lit adapter for TanStack Hotkeys",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "skills"
36
36
  ],
37
37
  "dependencies": {
38
- "@tanstack/hotkeys": "0.18.0"
38
+ "@tanstack/hotkeys": "0.19.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "lit": "^3.3.3"
@@ -74,7 +74,7 @@ export class MyEditor extends LitElement {
74
74
  | `new HotkeyRegistrationsController(host)` | Read `.hotkeys`, every registered hotkey with its options, `meta`, and `status` (whether it's enabled and in an active scope). |
75
75
  | `new HotkeyScopesStateController(host)` | Read `.value`, the active scopes and the exclusive scope that owns the keyboard. |
76
76
  | `new HotkeyHintController(host, hotkey, options?)` | Read `.value`, whether held modifiers should reveal a shortcut's hint. False unless a registration of the hotkey can fire: enabled, in an active scope, and with focus inside its element target. |
77
- | `new KeyHoldController(host, key)` | Read `.value`, whether one key is held. |
77
+ | `new KeyHoldController(host, key)` | Read `.value`, whether one key is held. Pass a getter, such as `() => this.key`, for a key that changes. |
78
78
  | `new HeldKeysController(host)` | Read `.value`, every key that's held right now. |
79
79
  | `new HeldKeyCodesController(host)` | Read `.value`, which maps each held key to its physical `event.code`. |
80
80