@tanstack/lit-hotkeys 0.13.1 → 0.15.0

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.
@@ -1,19 +1,27 @@
1
- import { HOTKEY_DEFAULT_OPTIONS } from "../constants.js";
2
- import { detectPlatform, formatHotkey, getHotkeyManager, rawHotkeyToParsedHotkey } from "@tanstack/hotkeys";
1
+ import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
2
+ import { createHotkeyBindings, prepareHotkeyDefinitions } from "@tanstack/hotkeys/adapter";
3
3
 
4
4
  //#region src/controllers/hotkey.ts
5
5
  /**
6
- * A Lit ReactiveController that registers a keyboard hotkey when the host
7
- * element is connected and unregisters it when the host is disconnected.
6
+ * A Lit ReactiveController that registers a hotkey when the host element is
7
+ * connected and unregisters it when the host is disconnected. The hotkey can
8
+ * be a chord such as `'Mod+S'`, a sequence such as `['G', 'G']`, or an app
9
+ * hotkey from `defineAppHotkeys`, which uses its custom hotkey from
10
+ * `provideAppHotkeys`.
11
+ *
12
+ * Chords accept `requireReset`; sequences accept `timeout`. Pass a getter for
13
+ * the hotkey or options to re-read them after each host update.
8
14
  *
9
15
  * @example
10
16
  * ```ts
11
17
  * class MyElement extends LitElement {
12
- * private hotkey = new HotkeyController(this, 'Mod+S', () => this.save())
18
+ * private save = new HotkeyController(this, 'Mod+S', () => this.doSave())
19
+ * private top = new HotkeyController(this, ['G', 'G'], () => this.scrollToTop())
13
20
  *
14
21
  * constructor() {
15
22
  * super()
16
- * this.addController(this.hotkey)
23
+ * this.addController(this.save)
24
+ * this.addController(this.top)
17
25
  * }
18
26
  * }
19
27
  * ```
@@ -21,43 +29,44 @@ import { detectPlatform, formatHotkey, getHotkeyManager, rawHotkeyToParsedHotkey
21
29
  var HotkeyController = class {
22
30
  _host;
23
31
  _hotkey;
24
- _callback;
25
32
  _options;
26
- /** The hotkey registration handle. */
27
- _registration;
28
- /**
29
- * @param _host - The Lit component that owns this controller (use `this` and pass it to `addController()`).
30
- * @param _hotkey - The key or key combo to listen for (e.g. `'Mod+S'` or a raw hotkey object).
31
- * @param _callback - Function to run when the hotkey is pressed; called with the host as `this`.
32
- * @param _options - Optional registration options (target, platform, enabled, etc.).
33
- */
34
- constructor(_host, _hotkey, _callback, _options = HOTKEY_DEFAULT_OPTIONS) {
33
+ _bindings = createHotkeyBindings();
34
+ _connected = false;
35
+ _boundCallback;
36
+ _unsubscribe;
37
+ constructor(_host, _hotkey, callback, _options = {}) {
35
38
  this._host = _host;
36
39
  this._hotkey = _hotkey;
37
- this._callback = _callback;
38
40
  this._options = _options;
41
+ this._boundCallback = callback.bind(this._host);
39
42
  }
40
- /**
41
- * Registers the hotkey with the global manager when the host is connected to the DOM.
42
- * Skips registration if no target is available (e.g. no document or options.target is null).
43
- */
43
+ /** Registers when connected and a target is available. */
44
44
  hostConnected() {
45
- const manager = getHotkeyManager();
46
- const platform = this._options.platform ?? detectPlatform();
47
- const hotkeyString = typeof this._hotkey === "string" ? this._hotkey : formatHotkey(rawHotkeyToParsedHotkey(this._hotkey, platform));
48
- const resolvedTarget = "target" in this._options ? this._options.target ?? null : typeof document !== "undefined" ? document : null;
49
- if (!resolvedTarget) return;
50
- const { target: _target, ...optionsWithoutTarget } = this._options;
51
- const boundCallback = this._callback.bind(this._host);
52
- this._registration = manager.register(hotkeyString, boundCallback, {
53
- ...optionsWithoutTarget,
54
- target: resolvedTarget
55
- });
45
+ this._connected = true;
46
+ this._unsubscribe = subscribeAppHotkeys(() => this._sync());
47
+ this._sync();
48
+ }
49
+ /** Refreshes options after rendering, when scoped targets are available. */
50
+ hostUpdated() {
51
+ if (this._connected) this._sync();
52
+ }
53
+ _sync() {
54
+ const options = typeof this._options === "function" ? this._options() : this._options;
55
+ this._bindings.update(prepareHotkeyDefinitions([{
56
+ hotkey: typeof this._hotkey === "function" ? this._hotkey() : this._hotkey,
57
+ callback: this._boundCallback,
58
+ options
59
+ }], {
60
+ appHotkeysStore: getAppHotkeysStore(),
61
+ resolveTarget: (target) => target
62
+ }));
56
63
  }
57
- /** Unregisters the hotkey when the host is disconnected from the DOM. */
64
+ /** Releases registrations when the host disconnects. */
58
65
  hostDisconnected() {
59
- if (this._registration?.isActive) this._registration.unregister();
60
- this._registration = void 0;
66
+ this._connected = false;
67
+ this._unsubscribe?.();
68
+ this._unsubscribe = void 0;
69
+ this._bindings.destroy();
61
70
  }
62
71
  };
63
72
 
@@ -1,10 +1,9 @@
1
+ import { AppHotkeyControllerOptions, HotkeyController, HotkeyControllerChordOptions, HotkeyControllerCommonOptions, HotkeyControllerOptions, HotkeyControllerOptionsFor, HotkeyControllerSequenceOptions, HotkeyControllerTarget } from "./hotkey.js";
2
+ import { AppHotkeysController } from "./app-hotkeys.js";
1
3
  import { HeldKeyCodesController } from "./held-key-codes.js";
2
4
  import { HeldKeysController } from "./held-keys.js";
3
- import { HotkeyController } from "./hotkey.js";
4
5
  import { HotkeyRecorderController } from "./hotkey-recorder.js";
5
6
  import { HotkeyRegistrationsController } from "./hotkey-registrations.js";
6
- import { HotkeySequenceController } from "./hotkey-sequence.js";
7
- import { HotkeySequenceRecorderController } from "./hotkey-sequence-recorder.js";
8
7
  import { KeyHoldController } from "./key-hold.js";
9
8
  import { HotkeyHintController } from "./hotkey-hint.js";
10
- export { HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, HotkeySequenceController, HotkeySequenceRecorderController, KeyHoldController };
9
+ export { AppHotkeyControllerOptions, AppHotkeysController, HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyControllerChordOptions, HotkeyControllerCommonOptions, HotkeyControllerOptions, HotkeyControllerOptionsFor, HotkeyControllerSequenceOptions, HotkeyControllerTarget, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, KeyHoldController };
@@ -49,8 +49,8 @@ export declare class KeyHoldController implements ReactiveController {
49
49
  /** Whether the tracked key is currently held down. */
50
50
  get value(): boolean;
51
51
  /**
52
- * @param host - The Lit component that owns this controller.
53
- * @param key - The key to track (e.g. 'Shift', 'Control', 'A').
52
+ * @param _host - The Lit component that owns this controller.
53
+ * @param _key - The key to track (e.g. 'Shift', 'Control', 'A').
54
54
  */
55
55
  constructor(_host: ReactiveControllerHost, _key: IndividualKey);
56
56
  hostConnected(): void;
@@ -51,8 +51,8 @@ var KeyHoldController = class {
51
51
  return this._value;
52
52
  }
53
53
  /**
54
- * @param host - The Lit component that owns this controller.
55
- * @param key - The key to track (e.g. 'Shift', 'Control', 'A').
54
+ * @param _host - The Lit component that owns this controller.
55
+ * @param _key - The key to track (e.g. 'Shift', 'Control', 'A').
56
56
  */
57
57
  constructor(_host, _key) {
58
58
  this._host = _host;
@@ -1,11 +1,14 @@
1
- import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
1
+ import { AppHotkeyControllerOptions, HotkeyControllerOptionsFor } from "../controllers/hotkey.js";
2
+ import { AppHotkey, HotkeyCallback, RegisterableHotkey } from "@tanstack/hotkeys";
2
3
  import { LitElement } from "lit";
3
4
  //#region src/decorators/hotkey.d.ts
5
+ type HotkeyDecorator = <T extends HotkeyCallback>(proto: LitElement, propertyKey: string, descriptor?: TypedPropertyDescriptor<T>) => void;
4
6
  /**
5
- * Decorator that registers a keyboard hotkey on the element when it connects
6
- * and unregisters when it disconnects. Uses {@link HotkeyController} under the hood.
7
+ * Decorator that registers a hotkey on the element when it connects and
8
+ * unregisters when it disconnects: a chord such as `'Mod+S'`, a sequence such
9
+ * as `['G', 'G']`, or an app hotkey. Uses {@link HotkeyController} under the hood.
7
10
  *
8
- * @param hotkey - The key or key combo to listen for (e.g. `'Mod+S'` or a raw hotkey object).
11
+ * @param hotkey - The chord, sequence, or app hotkey to listen for.
9
12
  * @param options - Optional registration options (target, platform, enabled, etc.).
10
13
  * @returns A method decorator for use on LitElement methods.
11
14
  *
@@ -15,10 +18,11 @@ import { LitElement } from "lit";
15
18
  * @hotkey('Mod+S')
16
19
  * save() { this.doSave() }
17
20
  *
18
- * @hotkey('Escape')
19
- * close() { this.dismiss() }
21
+ * @hotkey(['G', 'G'], { timeout: 500 })
22
+ * goToTop() { window.scrollTo(0, 0) }
20
23
  * }
21
24
  * ```
22
25
  */
23
- export declare function hotkey(hotkey: RegisterableHotkey, options?: HotkeyOptions): <T extends HotkeyCallback>(proto: LitElement, propertyKey: string, descriptor?: TypedPropertyDescriptor<T>) => void;
26
+ export declare function hotkey<T extends AppHotkey>(hotkey: T, options?: AppHotkeyControllerOptions<T>): HotkeyDecorator;
27
+ export declare function hotkey<T extends RegisterableHotkey>(hotkey: T, options?: HotkeyControllerOptionsFor<T>): HotkeyDecorator;
24
28
  //#endregion
@@ -1,27 +1,7 @@
1
- import { HOTKEY_DEFAULT_OPTIONS } from "../constants.js";
2
1
  import { HotkeyController } from "../controllers/hotkey.js";
3
2
 
4
3
  //#region src/decorators/hotkey.ts
5
- /**
6
- * Decorator that registers a keyboard hotkey on the element when it connects
7
- * and unregisters when it disconnects. Uses {@link HotkeyController} under the hood.
8
- *
9
- * @param hotkey - The key or key combo to listen for (e.g. `'Mod+S'` or a raw hotkey object).
10
- * @param options - Optional registration options (target, platform, enabled, etc.).
11
- * @returns A method decorator for use on LitElement methods.
12
- *
13
- * @example
14
- * ```ts
15
- * class MyElement extends LitElement {
16
- * @hotkey('Mod+S')
17
- * save() { this.doSave() }
18
- *
19
- * @hotkey('Escape')
20
- * close() { this.dismiss() }
21
- * }
22
- * ```
23
- */
24
- function hotkey(hotkey, options = HOTKEY_DEFAULT_OPTIONS) {
4
+ function hotkey(hotkey, options = {}) {
25
5
  return function(proto, propertyKey, descriptor) {
26
6
  const originalConnected = proto.connectedCallback;
27
7
  const controllerKey = Symbol(`@hotkey:${propertyKey}`);
@@ -1,3 +1,2 @@
1
- import { hotkeySequence } from "./hotkey-sequence.js";
2
1
  import { hotkey } from "./hotkey.js";
3
- export { hotkey, hotkeySequence };
2
+ export { hotkey };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,13 @@
1
- import { hotkeySequence } from "./decorators/hotkey-sequence.js";
1
+ import { AppHotkeyControllerOptions, HotkeyController, HotkeyControllerChordOptions, HotkeyControllerCommonOptions, HotkeyControllerOptions, HotkeyControllerOptionsFor, HotkeyControllerSequenceOptions, HotkeyControllerTarget } from "./controllers/hotkey.js";
2
2
  import { hotkey } from "./decorators/hotkey.js";
3
3
  import "./decorators/index.js";
4
+ import { AppHotkeysController } from "./controllers/app-hotkeys.js";
4
5
  import { HeldKeyCodesController } from "./controllers/held-key-codes.js";
5
6
  import { HeldKeysController } from "./controllers/held-keys.js";
6
- import { HotkeyController } from "./controllers/hotkey.js";
7
7
  import { HotkeyRecorderController } from "./controllers/hotkey-recorder.js";
8
8
  import { HotkeyRegistrationsController } from "./controllers/hotkey-registrations.js";
9
- import { HotkeySequenceController } from "./controllers/hotkey-sequence.js";
10
- import { HotkeySequenceRecorderController } from "./controllers/hotkey-sequence-recorder.js";
11
9
  import { KeyHoldController } from "./controllers/key-hold.js";
12
10
  import { HotkeyHintController } from "./controllers/hotkey-hint.js";
13
11
  import "./controllers/index.js";
14
12
  export * from "@tanstack/hotkeys";
15
- export { HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, HotkeySequenceController, HotkeySequenceRecorderController, KeyHoldController, hotkey, hotkeySequence };
13
+ export { AppHotkeyControllerOptions, AppHotkeysController, HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyControllerChordOptions, HotkeyControllerCommonOptions, HotkeyControllerOptions, HotkeyControllerOptionsFor, HotkeyControllerSequenceOptions, HotkeyControllerTarget, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, KeyHoldController, hotkey };
package/dist/index.js CHANGED
@@ -1,15 +1,13 @@
1
- import { HotkeySequenceController } from "./controllers/hotkey-sequence.js";
2
- import { hotkeySequence } from "./decorators/hotkey-sequence.js";
3
1
  import { HotkeyController } from "./controllers/hotkey.js";
4
2
  import { hotkey } from "./decorators/hotkey.js";
3
+ import { AppHotkeysController } from "./controllers/app-hotkeys.js";
5
4
  import { HeldKeyCodesController } from "./controllers/held-key-codes.js";
6
5
  import { HeldKeysController } from "./controllers/held-keys.js";
7
6
  import { HotkeyRecorderController } from "./controllers/hotkey-recorder.js";
8
7
  import { HotkeyRegistrationsController } from "./controllers/hotkey-registrations.js";
9
- import { HotkeySequenceRecorderController } from "./controllers/hotkey-sequence-recorder.js";
10
8
  import { KeyHoldController } from "./controllers/key-hold.js";
11
9
  import { HotkeyHintController } from "./controllers/hotkey-hint.js";
12
10
 
13
11
  export * from "@tanstack/hotkeys"
14
12
 
15
- export { HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, HotkeySequenceController, HotkeySequenceRecorderController, KeyHoldController, hotkey, hotkeySequence };
13
+ export { AppHotkeysController, HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, KeyHoldController, hotkey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/lit-hotkeys",
3
- "version": "0.13.1",
3
+ "version": "0.15.0",
4
4
  "description": "Lit adapter for TanStack Hotkeys",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@tanstack/hotkeys": "0.10.1"
36
+ "@tanstack/hotkeys": "0.12.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "lit": "^3.3.3"
package/dist/constants.js DELETED
@@ -1,24 +0,0 @@
1
- //#region src/constants.ts
2
- const HOTKEY_DEFAULT_OPTIONS = {
3
- enabled: true,
4
- preventDefault: true,
5
- stopPropagation: true,
6
- eventType: "keydown",
7
- requireReset: false,
8
- ignoreInputs: void 0,
9
- platform: void 0,
10
- conflictBehavior: "warn"
11
- };
12
- const HOTKEY_SEQUENCE_DEFAULT_OPTIONS = {
13
- enabled: true,
14
- timeout: 1e3,
15
- preventDefault: true,
16
- stopPropagation: true,
17
- eventType: "keydown",
18
- ignoreInputs: void 0,
19
- platform: void 0,
20
- conflictBehavior: "warn"
21
- };
22
-
23
- //#endregion
24
- export { HOTKEY_DEFAULT_OPTIONS, HOTKEY_SEQUENCE_DEFAULT_OPTIONS };
@@ -1,80 +0,0 @@
1
- import { HotkeySequence, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
2
- import { ReactiveController, ReactiveControllerHost } from "lit";
3
- //#region src/controllers/hotkey-sequence-recorder.d.ts
4
- /**
5
- * A Lit ReactiveController that records multi-chord sequences (Vim-style shortcuts).
6
- *
7
- * Wraps the framework-agnostic `HotkeySequenceRecorder` class, managing store
8
- * subscriptions and host update lifecycle automatically.
9
- *
10
- * @example
11
- * ```ts
12
- * class ShortcutSettings extends LitElement {
13
- * private recorder = new HotkeySequenceRecorderController(this, {
14
- * onRecord: (sequence) => {
15
- * this.sequence = sequence
16
- * this.requestUpdate()
17
- * },
18
- * onCancel: () => {
19
- * console.log('Recording cancelled')
20
- * },
21
- * })
22
- *
23
- * private sequence: HotkeySequence | null = null
24
- *
25
- * render() {
26
- * return html`
27
- * <button @click=${() => this.recorder.startRecording()}>
28
- * ${this.recorder.isRecording ? 'Recording...' : 'Edit Sequence'}
29
- * </button>
30
- * ${this.recorder.steps.length
31
- * ? html`<div>Steps: ${this.recorder.steps.join(' → ')}</div>`
32
- * : nothing}
33
- * ${this.recorder.recordedSequence
34
- * ? html`<div>Recorded: ${this.recorder.recordedSequence.join(' → ')}</div>`
35
- * : nothing}
36
- * `
37
- * }
38
- * }
39
- * ```
40
- */
41
- export declare class HotkeySequenceRecorderController implements ReactiveController {
42
- private _host;
43
- private _options;
44
- /** The recorder instance. */
45
- private _recorder;
46
- /** The unsubscribe function. */
47
- private _unsubscribe;
48
- /** Whether recording is currently active. */
49
- private _isRecording;
50
- /** Chords captured in the current session. */
51
- private _steps;
52
- /** Last committed sequence, or null if none. */
53
- private _recordedSequence;
54
- /** Whether recording is currently active. */
55
- get isRecording(): boolean;
56
- /** Chords captured in the current session. */
57
- get steps(): HotkeySequence;
58
- /** Last committed sequence, or null if none. */
59
- get recordedSequence(): HotkeySequence | null;
60
- /**
61
- * @param _host - The Lit component that owns this controller.
62
- * @param _options - Configuration options for the sequence recorder.
63
- */
64
- constructor(_host: ReactiveControllerHost, _options: HotkeySequenceRecorderOptions);
65
- /** Subscribes to the recorder store and updates internal state when changes occur. */
66
- hostConnected(): void;
67
- /** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
68
- hostDisconnected(): void;
69
- /** Updates the recorder options. */
70
- setOptions(options: Partial<HotkeySequenceRecorderOptions>): void;
71
- /** Start recording a new sequence. */
72
- startRecording(): void;
73
- /** Stop recording (same as cancel but without calling onCancel). */
74
- stopRecording(): void;
75
- /** Cancel recording without saving. */
76
- cancelRecording(): void;
77
- /** Commit current steps as a sequence (no-op if empty). */
78
- commitRecording(): void;
79
- }
80
- //#endregion
@@ -1,125 +0,0 @@
1
- import { HotkeySequenceRecorder } from "@tanstack/hotkeys";
2
-
3
- //#region src/controllers/hotkey-sequence-recorder.ts
4
- /**
5
- * A Lit ReactiveController that records multi-chord sequences (Vim-style shortcuts).
6
- *
7
- * Wraps the framework-agnostic `HotkeySequenceRecorder` class, managing store
8
- * subscriptions and host update lifecycle automatically.
9
- *
10
- * @example
11
- * ```ts
12
- * class ShortcutSettings extends LitElement {
13
- * private recorder = new HotkeySequenceRecorderController(this, {
14
- * onRecord: (sequence) => {
15
- * this.sequence = sequence
16
- * this.requestUpdate()
17
- * },
18
- * onCancel: () => {
19
- * console.log('Recording cancelled')
20
- * },
21
- * })
22
- *
23
- * private sequence: HotkeySequence | null = null
24
- *
25
- * render() {
26
- * return html`
27
- * <button @click=${() => this.recorder.startRecording()}>
28
- * ${this.recorder.isRecording ? 'Recording...' : 'Edit Sequence'}
29
- * </button>
30
- * ${this.recorder.steps.length
31
- * ? html`<div>Steps: ${this.recorder.steps.join(' → ')}</div>`
32
- * : nothing}
33
- * ${this.recorder.recordedSequence
34
- * ? html`<div>Recorded: ${this.recorder.recordedSequence.join(' → ')}</div>`
35
- * : nothing}
36
- * `
37
- * }
38
- * }
39
- * ```
40
- */
41
- var HotkeySequenceRecorderController = class {
42
- _host;
43
- _options;
44
- /** The recorder instance. */
45
- _recorder;
46
- /** The unsubscribe function. */
47
- _unsubscribe;
48
- /** Whether recording is currently active. */
49
- _isRecording = false;
50
- /** Chords captured in the current session. */
51
- _steps = [];
52
- /** Last committed sequence, or null if none. */
53
- _recordedSequence = null;
54
- /** Whether recording is currently active. */
55
- get isRecording() {
56
- return this._isRecording;
57
- }
58
- /** Chords captured in the current session. */
59
- get steps() {
60
- return this._steps;
61
- }
62
- /** Last committed sequence, or null if none. */
63
- get recordedSequence() {
64
- return this._recordedSequence;
65
- }
66
- /**
67
- * @param _host - The Lit component that owns this controller.
68
- * @param _options - Configuration options for the sequence recorder.
69
- */
70
- constructor(_host, _options) {
71
- this._host = _host;
72
- this._options = _options;
73
- this._recorder = new HotkeySequenceRecorder(_options);
74
- this._host.addController(this);
75
- }
76
- /** Subscribes to the recorder store and updates internal state when changes occur. */
77
- hostConnected() {
78
- const subscription = this._recorder.store.subscribe(() => {
79
- const { isRecording, steps, recordedSequence } = this._recorder.store.state;
80
- if (isRecording !== this._isRecording || steps !== this._steps || recordedSequence !== this._recordedSequence) {
81
- this._isRecording = isRecording;
82
- this._steps = steps;
83
- this._recordedSequence = recordedSequence;
84
- this._host.requestUpdate();
85
- }
86
- });
87
- this._unsubscribe = () => subscription.unsubscribe();
88
- }
89
- /** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
90
- hostDisconnected() {
91
- this._unsubscribe?.();
92
- this._unsubscribe = void 0;
93
- this._recorder.stop();
94
- this._isRecording = false;
95
- this._steps = [];
96
- this._recordedSequence = null;
97
- }
98
- /** Updates the recorder options. */
99
- setOptions(options) {
100
- this._options = {
101
- ...this._options,
102
- ...options
103
- };
104
- this._recorder.setOptions(this._options);
105
- }
106
- /** Start recording a new sequence. */
107
- startRecording() {
108
- this._recorder.start();
109
- }
110
- /** Stop recording (same as cancel but without calling onCancel). */
111
- stopRecording() {
112
- this._recorder.stop();
113
- }
114
- /** Cancel recording without saving. */
115
- cancelRecording() {
116
- this._recorder.cancel();
117
- }
118
- /** Commit current steps as a sequence (no-op if empty). */
119
- commitRecording() {
120
- this._recorder.commit();
121
- }
122
- };
123
-
124
- //#endregion
125
- export { HotkeySequenceRecorderController };
@@ -1,42 +0,0 @@
1
- import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
- import { ReactiveController, ReactiveControllerHost } from "lit";
3
- //#region src/controllers/hotkey-sequence.d.ts
4
- /**
5
- * A Lit ReactiveController that registers a keyboard sequence (e.g. Vim-style)
6
- * when the host element is connected and unregisters it when the host is disconnected.
7
- *
8
- * @example
9
- * ```ts
10
- * class MyElement extends LitElement {
11
- * private seq = new HotkeySequenceController(this, ['G', 'G'], () => this.goToTop())
12
- *
13
- * constructor() {
14
- * super()
15
- * this.addController(this.seq)
16
- * }
17
- * }
18
- * ```
19
- */
20
- export declare class HotkeySequenceController implements ReactiveController {
21
- private _host;
22
- private _sequence;
23
- private _callback;
24
- private _options;
25
- /** The sequence registration handle. */
26
- private _registration;
27
- /**
28
- * @param _host - The Lit component that owns this controller (use `this` and pass it to `addController()`).
29
- * @param _sequence - The key sequence to listen for (e.g. `['G', 'G']`).
30
- * @param _callback - Function to run when the sequence is completed; called with the host as `this`.
31
- * @param _options - Optional sequence options (target, timeout, enabled, etc.).
32
- */
33
- constructor(_host: ReactiveControllerHost, _sequence: HotkeySequence, _callback: HotkeyCallback, _options?: SequenceOptions);
34
- /**
35
- * Registers the sequence with the global sequence manager when the host is connected to the DOM.
36
- * Skips registration if disabled, sequence is empty, or no target is available.
37
- */
38
- hostConnected(): void;
39
- /** Unregisters the sequence when the host is disconnected from the DOM. */
40
- hostDisconnected(): void;
41
- }
42
- //#endregion
@@ -1,63 +0,0 @@
1
- import { HOTKEY_SEQUENCE_DEFAULT_OPTIONS } from "../constants.js";
2
- import { getSequenceManager } from "@tanstack/hotkeys";
3
-
4
- //#region src/controllers/hotkey-sequence.ts
5
- /**
6
- * A Lit ReactiveController that registers a keyboard sequence (e.g. Vim-style)
7
- * when the host element is connected and unregisters it when the host is disconnected.
8
- *
9
- * @example
10
- * ```ts
11
- * class MyElement extends LitElement {
12
- * private seq = new HotkeySequenceController(this, ['G', 'G'], () => this.goToTop())
13
- *
14
- * constructor() {
15
- * super()
16
- * this.addController(this.seq)
17
- * }
18
- * }
19
- * ```
20
- */
21
- var HotkeySequenceController = class {
22
- _host;
23
- _sequence;
24
- _callback;
25
- _options;
26
- /** The sequence registration handle. */
27
- _registration;
28
- /**
29
- * @param _host - The Lit component that owns this controller (use `this` and pass it to `addController()`).
30
- * @param _sequence - The key sequence to listen for (e.g. `['G', 'G']`).
31
- * @param _callback - Function to run when the sequence is completed; called with the host as `this`.
32
- * @param _options - Optional sequence options (target, timeout, enabled, etc.).
33
- */
34
- constructor(_host, _sequence, _callback, _options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS) {
35
- this._host = _host;
36
- this._sequence = _sequence;
37
- this._callback = _callback;
38
- this._options = _options;
39
- }
40
- /**
41
- * Registers the sequence with the global sequence manager when the host is connected to the DOM.
42
- * Skips registration if disabled, sequence is empty, or no target is available.
43
- */
44
- hostConnected() {
45
- const { target: _target, ...optionsWithoutTarget } = this._options;
46
- const manager = getSequenceManager();
47
- const resolvedTarget = "target" in this._options ? this._options.target ?? null : typeof document !== "undefined" ? document : null;
48
- if (!resolvedTarget) return;
49
- const boundCallback = this._callback.bind(this._host);
50
- this._registration = manager.register(this._sequence, boundCallback, {
51
- ...optionsWithoutTarget,
52
- target: resolvedTarget
53
- });
54
- }
55
- /** Unregisters the sequence when the host is disconnected from the DOM. */
56
- hostDisconnected() {
57
- if (this._registration?.isActive) this._registration.unregister();
58
- this._registration = void 0;
59
- }
60
- };
61
-
62
- //#endregion
63
- export { HotkeySequenceController };
@@ -1,25 +0,0 @@
1
- import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
- import { LitElement } from "lit";
3
- //#region src/decorators/hotkey-sequence.d.ts
4
- /**
5
- * Decorator that registers a keyboard sequence (e.g. Vim-style) on the element
6
- * when it connects and unregisters when it disconnects. Uses
7
- * {@link HotkeySequenceController} under the hood.
8
- *
9
- * @param sequence - The key sequence to listen for (e.g. `['G', 'G']` for "g g").
10
- * @param options - Optional sequence options (target, timeout, enabled, etc.).
11
- * @returns A method decorator for use on LitElement methods.
12
- *
13
- * @example
14
- * ```ts
15
- * class MyElement extends LitElement {
16
- * @hotkeySequence(['G', 'G'])
17
- * goToTop() { window.scrollTo(0, 0) }
18
- *
19
- * @hotkeySequence(['D', 'D'], { timeout: 500 })
20
- * deleteLine() { this.deleteCurrentLine() }
21
- * }
22
- * ```
23
- */
24
- export declare function hotkeySequence(sequence: HotkeySequence, options?: SequenceOptions): <T extends HotkeyCallback>(proto: LitElement, methodName: string, descriptor: TypedPropertyDescriptor<T>) => void;
25
- //#endregion