@tanstack/lit-hotkeys 0.14.0 → 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.
- package/dist/controllers/_app-hotkeys.js +11 -0
- package/dist/controllers/app-hotkeys.d.ts +48 -0
- package/dist/controllers/app-hotkeys.js +84 -0
- package/dist/controllers/hotkey-hint.d.ts +2 -2
- package/dist/controllers/hotkey-hint.js +13 -5
- package/dist/controllers/hotkey-recorder.d.ts +21 -9
- package/dist/controllers/hotkey-recorder.js +21 -11
- package/dist/controllers/hotkey-registrations.d.ts +11 -18
- package/dist/controllers/hotkey-registrations.js +19 -37
- package/dist/controllers/hotkey.d.ts +35 -9
- package/dist/controllers/hotkey.js +25 -16
- package/dist/controllers/index.d.ts +3 -4
- package/dist/controllers/key-hold.d.ts +2 -2
- package/dist/controllers/key-hold.js +2 -2
- package/dist/decorators/hotkey.d.ts +11 -7
- package/dist/decorators/hotkey.js +1 -21
- package/dist/decorators/index.d.ts +1 -2
- package/dist/index.d.ts +3 -5
- package/dist/index.js +2 -4
- package/package.json +2 -2
- package/dist/constants.js +0 -24
- package/dist/controllers/hotkey-sequence-recorder.d.ts +0 -81
- package/dist/controllers/hotkey-sequence-recorder.js +0 -128
- package/dist/controllers/hotkey-sequence.d.ts +0 -42
- package/dist/controllers/hotkey-sequence.js +0 -65
- package/dist/decorators/hotkey-sequence.d.ts +0 -25
- package/dist/decorators/hotkey-sequence.js +0 -44
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getHotkeyManager } from "@tanstack/hotkeys";
|
|
2
|
+
import { subscribePublishedAppHotkeys as subscribeAppHotkeys } from "@tanstack/hotkeys/adapter";
|
|
3
|
+
|
|
4
|
+
//#region src/controllers/_app-hotkeys.ts
|
|
5
|
+
/** The app hotkeys store published by `provideAppHotkeys`, if any. */
|
|
6
|
+
function getAppHotkeysStore() {
|
|
7
|
+
return getHotkeyManager().appHotkeys.state;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { getAppHotkeysStore, subscribeAppHotkeys };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AppHotkey, AppHotkeyListItem, CustomHotkeys, Hotkey, RegisteredAppHotkeys } from "@tanstack/hotkeys";
|
|
2
|
+
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
|
+
//#region src/controllers/app-hotkeys.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A Lit ReactiveController for app hotkeys provided with `provideAppHotkeys`:
|
|
6
|
+
* the effective app hotkeys, a cheat sheet list with live status, and the
|
|
7
|
+
* user's custom hotkeys. Requests an update when any of them change.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* class CheatSheet extends LitElement {
|
|
12
|
+
* private app = new AppHotkeysController(this)
|
|
13
|
+
*
|
|
14
|
+
* render() {
|
|
15
|
+
* return html`<ul>
|
|
16
|
+
* ${this.app.list.map(
|
|
17
|
+
* ({ appHotkey, status }) => html`<li>${appHotkey.meta?.name}: ${status}</li>`,
|
|
18
|
+
* )}
|
|
19
|
+
* </ul>`
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class AppHotkeysController implements ReactiveController {
|
|
25
|
+
private _host;
|
|
26
|
+
private _unsubscribe;
|
|
27
|
+
constructor(_host: ReactiveControllerHost);
|
|
28
|
+
/** Effective app hotkeys, typed by `Register`. */
|
|
29
|
+
get appHotkeys(): RegisteredAppHotkeys;
|
|
30
|
+
/** Every app hotkey with its live status, in declaration order. */
|
|
31
|
+
get list(): Array<AppHotkeyListItem<RegisteredAppHotkeys[keyof RegisteredAppHotkeys]>>;
|
|
32
|
+
/** The user's hotkeys that differ from the defaults. */
|
|
33
|
+
get customHotkeys(): CustomHotkeys;
|
|
34
|
+
/**
|
|
35
|
+
* Sets the user's hotkey for an app hotkey. `null` unbinds it.
|
|
36
|
+
* Returns conflicting app hotkeys; when any exist, nothing changes.
|
|
37
|
+
*/
|
|
38
|
+
setCustomHotkey(id: keyof RegisteredAppHotkeys & string, hotkey: Hotkey | null): Array<AppHotkey>;
|
|
39
|
+
/** Restores the default hotkey for an app hotkey. */
|
|
40
|
+
resetCustomHotkey(id: keyof RegisteredAppHotkeys & string): void;
|
|
41
|
+
/** Restores every default hotkey. */
|
|
42
|
+
resetCustomHotkeys(): void;
|
|
43
|
+
/** Other app hotkeys that would collide if `id` used `hotkey`. */
|
|
44
|
+
findConflicts(id: keyof RegisteredAppHotkeys & string, hotkey: Hotkey): Array<AppHotkey>;
|
|
45
|
+
hostConnected(): void;
|
|
46
|
+
hostDisconnected(): void;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
|
|
2
|
+
import { getHotkeyManager, toHotkeyRegistrationView } from "@tanstack/hotkeys";
|
|
3
|
+
|
|
4
|
+
//#region src/controllers/app-hotkeys.ts
|
|
5
|
+
function requireStore() {
|
|
6
|
+
const store = getAppHotkeysStore();
|
|
7
|
+
if (!store) throw new Error("AppHotkeysController requires provideAppHotkeys()");
|
|
8
|
+
return store;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A Lit ReactiveController for app hotkeys provided with `provideAppHotkeys`:
|
|
12
|
+
* the effective app hotkeys, a cheat sheet list with live status, and the
|
|
13
|
+
* user's custom hotkeys. Requests an update when any of them change.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* class CheatSheet extends LitElement {
|
|
18
|
+
* private app = new AppHotkeysController(this)
|
|
19
|
+
*
|
|
20
|
+
* render() {
|
|
21
|
+
* return html`<ul>
|
|
22
|
+
* ${this.app.list.map(
|
|
23
|
+
* ({ appHotkey, status }) => html`<li>${appHotkey.meta?.name}: ${status}</li>`,
|
|
24
|
+
* )}
|
|
25
|
+
* </ul>`
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
var AppHotkeysController = class {
|
|
31
|
+
_host;
|
|
32
|
+
_unsubscribe;
|
|
33
|
+
constructor(_host) {
|
|
34
|
+
this._host = _host;
|
|
35
|
+
this._host.addController(this);
|
|
36
|
+
}
|
|
37
|
+
/** Effective app hotkeys, typed by `Register`. */
|
|
38
|
+
get appHotkeys() {
|
|
39
|
+
return requireStore().appHotkeys;
|
|
40
|
+
}
|
|
41
|
+
/** Every app hotkey with its live status, in declaration order. */
|
|
42
|
+
get list() {
|
|
43
|
+
return requireStore().getList(Array.from(getHotkeyManager().registrations.state.values()).map(toHotkeyRegistrationView));
|
|
44
|
+
}
|
|
45
|
+
/** The user's hotkeys that differ from the defaults. */
|
|
46
|
+
get customHotkeys() {
|
|
47
|
+
return requireStore().customHotkeys;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sets the user's hotkey for an app hotkey. `null` unbinds it.
|
|
51
|
+
* Returns conflicting app hotkeys; when any exist, nothing changes.
|
|
52
|
+
*/
|
|
53
|
+
setCustomHotkey(id, hotkey) {
|
|
54
|
+
return requireStore().setCustomHotkey(id, hotkey);
|
|
55
|
+
}
|
|
56
|
+
/** Restores the default hotkey for an app hotkey. */
|
|
57
|
+
resetCustomHotkey(id) {
|
|
58
|
+
requireStore().resetCustomHotkey(id);
|
|
59
|
+
}
|
|
60
|
+
/** Restores every default hotkey. */
|
|
61
|
+
resetCustomHotkeys() {
|
|
62
|
+
requireStore().resetCustomHotkeys();
|
|
63
|
+
}
|
|
64
|
+
/** Other app hotkeys that would collide if `id` used `hotkey`. */
|
|
65
|
+
findConflicts(id, hotkey) {
|
|
66
|
+
return requireStore().findConflicts(id, hotkey);
|
|
67
|
+
}
|
|
68
|
+
hostConnected() {
|
|
69
|
+
const update = () => this._host.requestUpdate();
|
|
70
|
+
const unsubscribeAppHotkeys = subscribeAppHotkeys(update);
|
|
71
|
+
const registrations = getHotkeyManager().registrations.subscribe(update);
|
|
72
|
+
this._unsubscribe = () => {
|
|
73
|
+
unsubscribeAppHotkeys();
|
|
74
|
+
registrations.unsubscribe();
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
hostDisconnected() {
|
|
78
|
+
this._unsubscribe?.();
|
|
79
|
+
this._unsubscribe = void 0;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
export { AppHotkeysController };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HeldModifierOptions, RegisterableHotkey } from "@tanstack/hotkeys";
|
|
1
|
+
import { AppHotkey, HeldModifierOptions, RegisterableHotkey } from "@tanstack/hotkeys";
|
|
2
2
|
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
3
|
//#region src/controllers/hotkey-hint.d.ts
|
|
4
4
|
/** Modifier hint controller. Getter arguments can read reactive host properties. */
|
|
@@ -9,7 +9,7 @@ export declare class HotkeyHintController implements ReactiveController {
|
|
|
9
9
|
private unsubscribe?;
|
|
10
10
|
private visible;
|
|
11
11
|
/** Attaches to the host; getter arguments can read changing reactive properties. */
|
|
12
|
-
constructor(host: ReactiveControllerHost, hotkey: RegisterableHotkey | (() => RegisterableHotkey), options?: HeldModifierOptions | (() => HeldModifierOptions));
|
|
12
|
+
constructor(host: ReactiveControllerHost, hotkey: RegisterableHotkey | AppHotkey | (() => RegisterableHotkey | AppHotkey), options?: HeldModifierOptions | (() => HeldModifierOptions));
|
|
13
13
|
/** Current visibility; combine with the action’s enabled state when rendering. */
|
|
14
14
|
get value(): boolean;
|
|
15
15
|
/** Subscribes on connection and requests renders only when hint visibility changes. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAppHotkeysStore, subscribeAppHotkeys } from "./_app-hotkeys.js";
|
|
2
|
+
import { getKeyStateTracker, isAppHotkey, matchesHeldModifiers, resolveAppHotkey } from "@tanstack/hotkeys";
|
|
2
3
|
|
|
3
4
|
//#region src/controllers/hotkey-hint.ts
|
|
4
5
|
/** Modifier hint controller. Getter arguments can read reactive host properties. */
|
|
@@ -22,10 +23,15 @@ var HotkeyHintController = class {
|
|
|
22
23
|
/** Subscribes on connection and requests renders only when hint visibility changes. */
|
|
23
24
|
hostConnected() {
|
|
24
25
|
this.update();
|
|
25
|
-
const
|
|
26
|
+
const refresh = () => {
|
|
26
27
|
if (this.update()) this.host.requestUpdate();
|
|
27
|
-
}
|
|
28
|
-
|
|
28
|
+
};
|
|
29
|
+
const subscription = getKeyStateTracker().store.subscribe(refresh);
|
|
30
|
+
const unsubscribeAppHotkeys = subscribeAppHotkeys(refresh);
|
|
31
|
+
this.unsubscribe = () => {
|
|
32
|
+
subscription.unsubscribe();
|
|
33
|
+
unsubscribeAppHotkeys();
|
|
34
|
+
};
|
|
29
35
|
}
|
|
30
36
|
/** Re-evaluates getter arguments when host properties trigger an update. */
|
|
31
37
|
hostUpdate() {
|
|
@@ -39,7 +45,9 @@ var HotkeyHintController = class {
|
|
|
39
45
|
}
|
|
40
46
|
/** Recomputes visibility and reports whether the host needs another render. */
|
|
41
47
|
update() {
|
|
42
|
-
const
|
|
48
|
+
const value = typeof this.hotkey === "function" ? this.hotkey() : this.hotkey;
|
|
49
|
+
const hotkey = isAppHotkey(value) ? resolveAppHotkey(value, getAppHotkeysStore()).hotkey : value;
|
|
50
|
+
const next = hotkey !== null && matchesHeldModifiers(hotkey, getKeyStateTracker().store.state.heldKeys, typeof this.options === "function" ? this.options() : this.options);
|
|
43
51
|
const changed = next !== this.visible;
|
|
44
52
|
this.visible = next;
|
|
45
53
|
return changed;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
|
|
1
|
+
import { Hotkey, HotkeyChordRecorderOptions, HotkeyRecorderOptions, HotkeySequence, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
|
|
2
2
|
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
3
|
//#region src/controllers/hotkey-recorder.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* A Lit ReactiveController that records keyboard shortcuts.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* With the default `maxSteps: 1`, the first valid chord is recorded. With a
|
|
8
|
+
* larger `maxSteps`, each chord adds a step; the recording commits on Enter
|
|
9
|
+
* (unless `commitKeys: 'none'`), after `idleTimeoutMs`, or at `maxSteps`, and
|
|
10
|
+
* `onRecord` receives a chord (one step) or a sequence. Escape cancels;
|
|
11
|
+
* Backspace/Delete removes the last step or clears.
|
|
10
12
|
*
|
|
11
13
|
* @example
|
|
12
14
|
* ```ts
|
|
@@ -46,17 +48,25 @@ export declare class HotkeyRecorderController implements ReactiveController {
|
|
|
46
48
|
private _unsubscribe;
|
|
47
49
|
/** Whether recording is currently active. */
|
|
48
50
|
private _isRecording;
|
|
49
|
-
/** The
|
|
51
|
+
/** The last committed hotkey. */
|
|
50
52
|
private _recordedHotkey;
|
|
53
|
+
/** Chords recorded so far in a multi-step recording. */
|
|
54
|
+
private _steps;
|
|
51
55
|
/** Whether recording is currently active. */
|
|
52
56
|
get isRecording(): boolean;
|
|
53
|
-
/** The
|
|
57
|
+
/** The last committed hotkey: a chord, or a sequence of two or more steps. */
|
|
54
58
|
get recordedHotkey(): Hotkey | null;
|
|
59
|
+
/** Chords recorded so far in a multi-step recording (for live preview). */
|
|
60
|
+
get steps(): HotkeySequence;
|
|
55
61
|
/**
|
|
56
|
-
* @param
|
|
57
|
-
* @param
|
|
62
|
+
* @param host - The Lit component that owns this controller.
|
|
63
|
+
* @param options - Options or a getter, read during recording.
|
|
58
64
|
*/
|
|
59
|
-
constructor(
|
|
65
|
+
constructor(host: ReactiveControllerHost, options: HotkeyChordRecorderOptions);
|
|
66
|
+
constructor(host: ReactiveControllerHost, options: HotkeySequenceRecorderOptions);
|
|
67
|
+
constructor(host: ReactiveControllerHost, options: () => HotkeySequenceRecorderOptions);
|
|
68
|
+
constructor(host: ReactiveControllerHost, options: () => HotkeyChordRecorderOptions);
|
|
69
|
+
constructor(host: ReactiveControllerHost, options: () => HotkeyRecorderOptions);
|
|
60
70
|
/** Subscribes to the recorder store and updates the internal state when changes occur. */
|
|
61
71
|
hostConnected(): void;
|
|
62
72
|
/** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
|
|
@@ -69,5 +79,7 @@ export declare class HotkeyRecorderController implements ReactiveController {
|
|
|
69
79
|
stopRecording(): void;
|
|
70
80
|
/** Cancel recording without saving. */
|
|
71
81
|
cancelRecording(): void;
|
|
82
|
+
/** Commit the recorded steps now (multi-step recordings). */
|
|
83
|
+
commitRecording(): void;
|
|
72
84
|
}
|
|
73
85
|
//#endregion
|
|
@@ -4,9 +4,11 @@ import { HotkeyRecorder } from "@tanstack/hotkeys";
|
|
|
4
4
|
/**
|
|
5
5
|
* A Lit ReactiveController that records keyboard shortcuts.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* With the default `maxSteps: 1`, the first valid chord is recorded. With a
|
|
8
|
+
* larger `maxSteps`, each chord adds a step; the recording commits on Enter
|
|
9
|
+
* (unless `commitKeys: 'none'`), after `idleTimeoutMs`, or at `maxSteps`, and
|
|
10
|
+
* `onRecord` receives a chord (one step) or a sequence. Escape cancels;
|
|
11
|
+
* Backspace/Delete removes the last step or clears.
|
|
10
12
|
*
|
|
11
13
|
* @example
|
|
12
14
|
* ```ts
|
|
@@ -46,20 +48,22 @@ var HotkeyRecorderController = class {
|
|
|
46
48
|
_unsubscribe;
|
|
47
49
|
/** Whether recording is currently active. */
|
|
48
50
|
_isRecording = false;
|
|
49
|
-
/** The
|
|
51
|
+
/** The last committed hotkey. */
|
|
50
52
|
_recordedHotkey = null;
|
|
53
|
+
/** Chords recorded so far in a multi-step recording. */
|
|
54
|
+
_steps = [];
|
|
51
55
|
/** Whether recording is currently active. */
|
|
52
56
|
get isRecording() {
|
|
53
57
|
return this._isRecording;
|
|
54
58
|
}
|
|
55
|
-
/** The
|
|
59
|
+
/** The last committed hotkey: a chord, or a sequence of two or more steps. */
|
|
56
60
|
get recordedHotkey() {
|
|
57
61
|
return this._recordedHotkey;
|
|
58
62
|
}
|
|
59
|
-
/**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
/** Chords recorded so far in a multi-step recording (for live preview). */
|
|
64
|
+
get steps() {
|
|
65
|
+
return this._steps;
|
|
66
|
+
}
|
|
63
67
|
constructor(_host, _options) {
|
|
64
68
|
this._host = _host;
|
|
65
69
|
this._options = _options;
|
|
@@ -72,10 +76,11 @@ var HotkeyRecorderController = class {
|
|
|
72
76
|
/** Subscribes to the recorder store and updates the internal state when changes occur. */
|
|
73
77
|
hostConnected() {
|
|
74
78
|
const subscription = this._recorder.store.subscribe(() => {
|
|
75
|
-
const { isRecording, recordedHotkey } = this._recorder.store.state;
|
|
76
|
-
if (isRecording !== this._isRecording || recordedHotkey !== this._recordedHotkey) {
|
|
79
|
+
const { isRecording, recordedHotkey, steps } = this._recorder.store.state;
|
|
80
|
+
if (isRecording !== this._isRecording || recordedHotkey !== this._recordedHotkey || steps !== this._steps) {
|
|
77
81
|
this._isRecording = isRecording;
|
|
78
82
|
this._recordedHotkey = recordedHotkey;
|
|
83
|
+
this._steps = steps;
|
|
79
84
|
this._host.requestUpdate();
|
|
80
85
|
}
|
|
81
86
|
});
|
|
@@ -88,6 +93,7 @@ var HotkeyRecorderController = class {
|
|
|
88
93
|
this._recorder.stop();
|
|
89
94
|
this._isRecording = false;
|
|
90
95
|
this._recordedHotkey = null;
|
|
96
|
+
this._steps = [];
|
|
91
97
|
}
|
|
92
98
|
/** Updates the recorder options (e.g. callbacks). */
|
|
93
99
|
setOptions(options) {
|
|
@@ -108,6 +114,10 @@ var HotkeyRecorderController = class {
|
|
|
108
114
|
cancelRecording() {
|
|
109
115
|
this._recorder.cancel();
|
|
110
116
|
}
|
|
117
|
+
/** Commit the recorded steps now (multi-step recordings). */
|
|
118
|
+
commitRecording() {
|
|
119
|
+
this._recorder.commit();
|
|
120
|
+
}
|
|
111
121
|
};
|
|
112
122
|
|
|
113
123
|
//#endregion
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { HotkeyRegistrationView
|
|
1
|
+
import { HotkeyRegistrationView } from "@tanstack/hotkeys";
|
|
2
2
|
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
3
|
//#region src/controllers/hotkey-registrations.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* A Lit ReactiveController that
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* triggers host updates whenever registrations change.
|
|
5
|
+
* A Lit ReactiveController that reads every hotkey registration, chords and
|
|
6
|
+
* sequences, from the singleton HotkeyManager and requests an update when
|
|
7
|
+
* they change. Narrow each view with `kind`.
|
|
9
8
|
*
|
|
10
9
|
* @example
|
|
11
10
|
* ```ts
|
|
@@ -13,27 +12,21 @@ import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
|
13
12
|
* private registrations = new HotkeyRegistrationsController(this)
|
|
14
13
|
*
|
|
15
14
|
* render() {
|
|
16
|
-
* return html
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* </ul>
|
|
22
|
-
* `
|
|
15
|
+
* return html`<ul>
|
|
16
|
+
* ${this.registrations.hotkeys.map(
|
|
17
|
+
* (reg) => html`<li>${reg.options.meta?.name}: ${formatForDisplay(reg.hotkey)}</li>`,
|
|
18
|
+
* )}
|
|
19
|
+
* </ul>`
|
|
23
20
|
* }
|
|
24
21
|
* }
|
|
25
22
|
* ```
|
|
26
23
|
*/
|
|
27
24
|
export declare class HotkeyRegistrationsController implements ReactiveController {
|
|
28
25
|
private _host;
|
|
29
|
-
private
|
|
30
|
-
private _unsubscribeSequences;
|
|
26
|
+
private _unsubscribe;
|
|
31
27
|
private _hotkeys;
|
|
32
|
-
|
|
33
|
-
/** All registered hotkeys (public view, no callbacks). */
|
|
28
|
+
/** Every registration, chords and sequences (public view, no callbacks). */
|
|
34
29
|
get hotkeys(): Array<HotkeyRegistrationView>;
|
|
35
|
-
/** All registered sequences. */
|
|
36
|
-
get sequences(): Array<SequenceRegistrationView>;
|
|
37
30
|
constructor(_host: ReactiveControllerHost);
|
|
38
31
|
hostConnected(): void;
|
|
39
32
|
hostDisconnected(): void;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { getHotkeyManager,
|
|
1
|
+
import { getHotkeyManager, toHotkeyRegistrationView } from "@tanstack/hotkeys";
|
|
2
2
|
|
|
3
3
|
//#region src/controllers/hotkey-registrations.ts
|
|
4
4
|
/**
|
|
5
|
-
* A Lit ReactiveController that
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* triggers host updates whenever registrations change.
|
|
5
|
+
* A Lit ReactiveController that reads every hotkey registration, chords and
|
|
6
|
+
* sequences, from the singleton HotkeyManager and requests an update when
|
|
7
|
+
* they change. Narrow each view with `kind`.
|
|
9
8
|
*
|
|
10
9
|
* @example
|
|
11
10
|
* ```ts
|
|
@@ -13,58 +12,41 @@ import { getHotkeyManager, getSequenceManager, toHotkeyRegistrationView } from "
|
|
|
13
12
|
* private registrations = new HotkeyRegistrationsController(this)
|
|
14
13
|
*
|
|
15
14
|
* render() {
|
|
16
|
-
* return html
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* </ul>
|
|
22
|
-
* `
|
|
15
|
+
* return html`<ul>
|
|
16
|
+
* ${this.registrations.hotkeys.map(
|
|
17
|
+
* (reg) => html`<li>${reg.options.meta?.name}: ${formatForDisplay(reg.hotkey)}</li>`,
|
|
18
|
+
* )}
|
|
19
|
+
* </ul>`
|
|
23
20
|
* }
|
|
24
21
|
* }
|
|
25
22
|
* ```
|
|
26
23
|
*/
|
|
27
24
|
var HotkeyRegistrationsController = class {
|
|
28
25
|
_host;
|
|
29
|
-
|
|
30
|
-
_unsubscribeSequences;
|
|
26
|
+
_unsubscribe;
|
|
31
27
|
_hotkeys = [];
|
|
32
|
-
|
|
33
|
-
/** All registered hotkeys (public view, no callbacks). */
|
|
28
|
+
/** Every registration, chords and sequences (public view, no callbacks). */
|
|
34
29
|
get hotkeys() {
|
|
35
30
|
return this._hotkeys;
|
|
36
31
|
}
|
|
37
|
-
/** All registered sequences. */
|
|
38
|
-
get sequences() {
|
|
39
|
-
return this._sequences;
|
|
40
|
-
}
|
|
41
32
|
constructor(_host) {
|
|
42
33
|
this._host = _host;
|
|
43
34
|
this._host.addController(this);
|
|
44
35
|
}
|
|
45
36
|
hostConnected() {
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
this._hotkeys =
|
|
50
|
-
this._host.requestUpdate();
|
|
51
|
-
});
|
|
52
|
-
const sequencesSub = sequenceManager.registrations.subscribe(() => {
|
|
53
|
-
this._sequences = Array.from(sequenceManager.registrations.state.values());
|
|
37
|
+
const manager = getHotkeyManager();
|
|
38
|
+
const read = () => Array.from(manager.registrations.state.values()).map(toHotkeyRegistrationView);
|
|
39
|
+
const subscription = manager.registrations.subscribe(() => {
|
|
40
|
+
this._hotkeys = read();
|
|
54
41
|
this._host.requestUpdate();
|
|
55
42
|
});
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
58
|
-
this._hotkeys = Array.from(hotkeyManager.registrations.state.values()).map(toHotkeyRegistrationView);
|
|
59
|
-
this._sequences = Array.from(sequenceManager.registrations.state.values());
|
|
43
|
+
this._unsubscribe = () => subscription.unsubscribe();
|
|
44
|
+
this._hotkeys = read();
|
|
60
45
|
}
|
|
61
46
|
hostDisconnected() {
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
64
|
-
this._unsubscribeHotkeys = void 0;
|
|
65
|
-
this._unsubscribeSequences = void 0;
|
|
47
|
+
this._unsubscribe?.();
|
|
48
|
+
this._unsubscribe = void 0;
|
|
66
49
|
this._hotkeys = [];
|
|
67
|
-
this._sequences = [];
|
|
68
50
|
}
|
|
69
51
|
};
|
|
70
52
|
|
|
@@ -1,18 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppHotkey, HotkeyCallback, RegisterableHotkey, Target } from "@tanstack/hotkeys";
|
|
2
|
+
import { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from "@tanstack/hotkeys/adapter";
|
|
2
3
|
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
4
|
//#region src/controllers/hotkey.d.ts
|
|
5
|
+
/** The element to listen on. A `null` target skips registration until it is set. */
|
|
6
|
+
export type HotkeyControllerTarget = Target | null;
|
|
7
|
+
/** Options shared by chords and sequences. */
|
|
8
|
+
export type HotkeyControllerOptions = AdapterHotkeyOptions<HotkeyControllerTarget>;
|
|
9
|
+
/** Options for a chord such as `'Mod+S'`. */
|
|
10
|
+
export type HotkeyControllerChordOptions = AdapterChordOptions<HotkeyControllerTarget>;
|
|
11
|
+
/** Options for a sequence such as `['G', 'G']`. */
|
|
12
|
+
export type HotkeyControllerSequenceOptions = AdapterSequenceOptions<HotkeyControllerTarget>;
|
|
13
|
+
/** Options for every kind; each applies to the kinds that support it. */
|
|
14
|
+
export type HotkeyControllerCommonOptions = AdapterCommonOptions<HotkeyControllerTarget>;
|
|
15
|
+
/** The options type for a hotkey: chord options for chords, sequence options for sequences. */
|
|
16
|
+
export type HotkeyControllerOptionsFor<T extends RegisterableHotkey> = AdapterOptionsFor<T, HotkeyControllerTarget>;
|
|
17
|
+
/** Call-site options for an app hotkey, typed by its declared default kind. */
|
|
18
|
+
export type AppHotkeyControllerOptions<T extends AppHotkey = AppHotkey> = AdapterAppHotkeyOptions<T, HotkeyControllerTarget>;
|
|
19
|
+
type MaybeGetter<T> = T | (() => T);
|
|
4
20
|
/**
|
|
5
|
-
* A Lit ReactiveController that registers a
|
|
6
|
-
*
|
|
21
|
+
* A Lit ReactiveController that registers a hotkey when the host element is
|
|
22
|
+
* connected and unregisters it when the host is disconnected. The hotkey can
|
|
23
|
+
* be a chord such as `'Mod+S'`, a sequence such as `['G', 'G']`, or an app
|
|
24
|
+
* hotkey from `defineAppHotkeys`, which uses its custom hotkey from
|
|
25
|
+
* `provideAppHotkeys`.
|
|
26
|
+
*
|
|
27
|
+
* Chords accept `requireReset`; sequences accept `timeout`. Pass a getter for
|
|
28
|
+
* the hotkey or options to re-read them after each host update.
|
|
7
29
|
*
|
|
8
30
|
* @example
|
|
9
31
|
* ```ts
|
|
10
32
|
* class MyElement extends LitElement {
|
|
11
|
-
* private
|
|
33
|
+
* private save = new HotkeyController(this, 'Mod+S', () => this.doSave())
|
|
34
|
+
* private top = new HotkeyController(this, ['G', 'G'], () => this.scrollToTop())
|
|
12
35
|
*
|
|
13
36
|
* constructor() {
|
|
14
37
|
* super()
|
|
15
|
-
* this.addController(this.
|
|
38
|
+
* this.addController(this.save)
|
|
39
|
+
* this.addController(this.top)
|
|
16
40
|
* }
|
|
17
41
|
* }
|
|
18
42
|
* ```
|
|
@@ -24,13 +48,15 @@ export declare class HotkeyController implements ReactiveController {
|
|
|
24
48
|
private _bindings;
|
|
25
49
|
private _connected;
|
|
26
50
|
private _boundCallback;
|
|
51
|
+
private _unsubscribe;
|
|
27
52
|
/**
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
53
|
+
* @param host - The Lit component that owns this controller. Add the controller with `addController()`.
|
|
54
|
+
* @param hotkey - The chord, sequence, or app hotkey to register, or a getter. A getter is read on connection and after host updates.
|
|
30
55
|
* @param callback - Called with the host as `this`.
|
|
31
|
-
* @param
|
|
56
|
+
* @param options - Options or a getter. Property getters are read on connection and after host updates.
|
|
32
57
|
*/
|
|
33
|
-
constructor(
|
|
58
|
+
constructor(host: ReactiveControllerHost, hotkey: MaybeGetter<AppHotkey>, callback: HotkeyCallback, options?: MaybeGetter<AppHotkeyControllerOptions>);
|
|
59
|
+
constructor(host: ReactiveControllerHost, hotkey: MaybeGetter<RegisterableHotkey>, callback: HotkeyCallback, options?: MaybeGetter<HotkeyControllerCommonOptions>);
|
|
34
60
|
/** Registers when connected and a target is available. */
|
|
35
61
|
hostConnected(): void;
|
|
36
62
|
/** Refreshes options after rendering, when scoped targets are available. */
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createHotkeyBindings } from "@tanstack/hotkeys/adapter";
|
|
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
|
|
7
|
-
*
|
|
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
|
|
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.
|
|
23
|
+
* this.addController(this.save)
|
|
24
|
+
* this.addController(this.top)
|
|
17
25
|
* }
|
|
18
26
|
* }
|
|
19
27
|
* ```
|
|
@@ -25,13 +33,8 @@ var HotkeyController = class {
|
|
|
25
33
|
_bindings = createHotkeyBindings();
|
|
26
34
|
_connected = false;
|
|
27
35
|
_boundCallback;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* @param _hotkey - The shortcut to register.
|
|
31
|
-
* @param callback - Called with the host as `this`.
|
|
32
|
-
* @param _options - Options or a getter. Property getters are read on connection and after host updates.
|
|
33
|
-
*/
|
|
34
|
-
constructor(_host, _hotkey, callback, _options = HOTKEY_DEFAULT_OPTIONS) {
|
|
36
|
+
_unsubscribe;
|
|
37
|
+
constructor(_host, _hotkey, callback, _options = {}) {
|
|
35
38
|
this._host = _host;
|
|
36
39
|
this._hotkey = _hotkey;
|
|
37
40
|
this._options = _options;
|
|
@@ -40,6 +43,7 @@ var HotkeyController = class {
|
|
|
40
43
|
/** Registers when connected and a target is available. */
|
|
41
44
|
hostConnected() {
|
|
42
45
|
this._connected = true;
|
|
46
|
+
this._unsubscribe = subscribeAppHotkeys(() => this._sync());
|
|
43
47
|
this._sync();
|
|
44
48
|
}
|
|
45
49
|
/** Refreshes options after rendering, when scoped targets are available. */
|
|
@@ -48,15 +52,20 @@ var HotkeyController = class {
|
|
|
48
52
|
}
|
|
49
53
|
_sync() {
|
|
50
54
|
const options = typeof this._options === "function" ? this._options() : this._options;
|
|
51
|
-
this._bindings.update([{
|
|
52
|
-
hotkey: this._hotkey,
|
|
55
|
+
this._bindings.update(prepareHotkeyDefinitions([{
|
|
56
|
+
hotkey: typeof this._hotkey === "function" ? this._hotkey() : this._hotkey,
|
|
53
57
|
callback: this._boundCallback,
|
|
54
58
|
options
|
|
55
|
-
}]
|
|
59
|
+
}], {
|
|
60
|
+
appHotkeysStore: getAppHotkeysStore(),
|
|
61
|
+
resolveTarget: (target) => target
|
|
62
|
+
}));
|
|
56
63
|
}
|
|
57
64
|
/** Releases registrations when the host disconnects. */
|
|
58
65
|
hostDisconnected() {
|
|
59
66
|
this._connected = false;
|
|
67
|
+
this._unsubscribe?.();
|
|
68
|
+
this._unsubscribe = void 0;
|
|
60
69
|
this._bindings.destroy();
|
|
61
70
|
}
|
|
62
71
|
};
|
|
@@ -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,
|
|
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
|
|
53
|
-
* @param
|
|
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
|
|
55
|
-
* @param
|
|
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 {
|
|
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
|
|
6
|
-
*
|
|
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
|
|
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('
|
|
19
|
-
*
|
|
21
|
+
* @hotkey(['G', 'G'], { timeout: 500 })
|
|
22
|
+
* goToTop() { window.scrollTo(0, 0) }
|
|
20
23
|
* }
|
|
21
24
|
* ```
|
|
22
25
|
*/
|
|
23
|
-
export declare function hotkey
|
|
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}`);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
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,
|
|
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,
|
|
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.
|
|
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.
|
|
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,81 +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
|
-
private _optionOverrides;
|
|
47
|
-
/** The unsubscribe function. */
|
|
48
|
-
private _unsubscribe;
|
|
49
|
-
/** Whether recording is currently active. */
|
|
50
|
-
private _isRecording;
|
|
51
|
-
/** Chords captured in the current session. */
|
|
52
|
-
private _steps;
|
|
53
|
-
/** Last committed sequence, or null if none. */
|
|
54
|
-
private _recordedSequence;
|
|
55
|
-
/** Whether recording is currently active. */
|
|
56
|
-
get isRecording(): boolean;
|
|
57
|
-
/** Chords captured in the current session. */
|
|
58
|
-
get steps(): HotkeySequence;
|
|
59
|
-
/** Last committed sequence, or null if none. */
|
|
60
|
-
get recordedSequence(): HotkeySequence | null;
|
|
61
|
-
/**
|
|
62
|
-
* @param _host - The Lit component that owns this controller.
|
|
63
|
-
* @param _options - Options or a getter, read during recording.
|
|
64
|
-
*/
|
|
65
|
-
constructor(_host: ReactiveControllerHost, _options: HotkeySequenceRecorderOptions | (() => HotkeySequenceRecorderOptions));
|
|
66
|
-
/** Subscribes to the recorder store and updates internal state when changes occur. */
|
|
67
|
-
hostConnected(): void;
|
|
68
|
-
/** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
|
|
69
|
-
hostDisconnected(): void;
|
|
70
|
-
/** Updates the recorder options. */
|
|
71
|
-
setOptions(options: Partial<HotkeySequenceRecorderOptions>): void;
|
|
72
|
-
/** Start recording a new sequence. */
|
|
73
|
-
startRecording(): void;
|
|
74
|
-
/** Stop recording (same as cancel but without calling onCancel). */
|
|
75
|
-
stopRecording(): void;
|
|
76
|
-
/** Cancel recording without saving. */
|
|
77
|
-
cancelRecording(): void;
|
|
78
|
-
/** Commit current steps as a sequence (no-op if empty). */
|
|
79
|
-
commitRecording(): void;
|
|
80
|
-
}
|
|
81
|
-
//#endregion
|
|
@@ -1,128 +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
|
-
_optionOverrides = {};
|
|
47
|
-
/** The unsubscribe function. */
|
|
48
|
-
_unsubscribe;
|
|
49
|
-
/** Whether recording is currently active. */
|
|
50
|
-
_isRecording = false;
|
|
51
|
-
/** Chords captured in the current session. */
|
|
52
|
-
_steps = [];
|
|
53
|
-
/** Last committed sequence, or null if none. */
|
|
54
|
-
_recordedSequence = null;
|
|
55
|
-
/** Whether recording is currently active. */
|
|
56
|
-
get isRecording() {
|
|
57
|
-
return this._isRecording;
|
|
58
|
-
}
|
|
59
|
-
/** Chords captured in the current session. */
|
|
60
|
-
get steps() {
|
|
61
|
-
return this._steps;
|
|
62
|
-
}
|
|
63
|
-
/** Last committed sequence, or null if none. */
|
|
64
|
-
get recordedSequence() {
|
|
65
|
-
return this._recordedSequence;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* @param _host - The Lit component that owns this controller.
|
|
69
|
-
* @param _options - Options or a getter, read during recording.
|
|
70
|
-
*/
|
|
71
|
-
constructor(_host, _options) {
|
|
72
|
-
this._host = _host;
|
|
73
|
-
this._options = _options;
|
|
74
|
-
this._recorder = new HotkeySequenceRecorder(() => ({
|
|
75
|
-
...typeof this._options === "function" ? this._options() : this._options,
|
|
76
|
-
...this._optionOverrides
|
|
77
|
-
}));
|
|
78
|
-
this._host.addController(this);
|
|
79
|
-
}
|
|
80
|
-
/** Subscribes to the recorder store and updates internal state when changes occur. */
|
|
81
|
-
hostConnected() {
|
|
82
|
-
const subscription = this._recorder.store.subscribe(() => {
|
|
83
|
-
const { isRecording, steps, recordedSequence } = this._recorder.store.state;
|
|
84
|
-
if (isRecording !== this._isRecording || steps !== this._steps || recordedSequence !== this._recordedSequence) {
|
|
85
|
-
this._isRecording = isRecording;
|
|
86
|
-
this._steps = steps;
|
|
87
|
-
this._recordedSequence = recordedSequence;
|
|
88
|
-
this._host.requestUpdate();
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
this._unsubscribe = () => subscription.unsubscribe();
|
|
92
|
-
}
|
|
93
|
-
/** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
|
|
94
|
-
hostDisconnected() {
|
|
95
|
-
this._unsubscribe?.();
|
|
96
|
-
this._unsubscribe = void 0;
|
|
97
|
-
this._recorder.stop();
|
|
98
|
-
this._isRecording = false;
|
|
99
|
-
this._steps = [];
|
|
100
|
-
this._recordedSequence = null;
|
|
101
|
-
}
|
|
102
|
-
/** Updates the recorder options. */
|
|
103
|
-
setOptions(options) {
|
|
104
|
-
this._optionOverrides = {
|
|
105
|
-
...this._optionOverrides,
|
|
106
|
-
...options
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
/** Start recording a new sequence. */
|
|
110
|
-
startRecording() {
|
|
111
|
-
this._recorder.start();
|
|
112
|
-
}
|
|
113
|
-
/** Stop recording (same as cancel but without calling onCancel). */
|
|
114
|
-
stopRecording() {
|
|
115
|
-
this._recorder.stop();
|
|
116
|
-
}
|
|
117
|
-
/** Cancel recording without saving. */
|
|
118
|
-
cancelRecording() {
|
|
119
|
-
this._recorder.cancel();
|
|
120
|
-
}
|
|
121
|
-
/** Commit current steps as a sequence (no-op if empty). */
|
|
122
|
-
commitRecording() {
|
|
123
|
-
this._recorder.commit();
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
//#endregion
|
|
128
|
-
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 _options;
|
|
24
|
-
private _bindings;
|
|
25
|
-
private _connected;
|
|
26
|
-
private _boundCallback;
|
|
27
|
-
/**
|
|
28
|
-
* @param _host - The Lit component that owns this controller. Add the controller with `addController()`.
|
|
29
|
-
* @param _sequence - The sequence to register.
|
|
30
|
-
* @param callback - Called with the host as `this`.
|
|
31
|
-
* @param _options - Options or a getter. Property getters are read on connection and after host updates.
|
|
32
|
-
*/
|
|
33
|
-
constructor(_host: ReactiveControllerHost, _sequence: HotkeySequence, callback: HotkeyCallback, _options?: SequenceOptions | (() => SequenceOptions));
|
|
34
|
-
/** Registers when connected and a target is available. */
|
|
35
|
-
hostConnected(): void;
|
|
36
|
-
/** Refreshes options after rendering, when scoped targets are available. */
|
|
37
|
-
hostUpdated(): void;
|
|
38
|
-
private _sync;
|
|
39
|
-
/** Releases registrations when the host disconnects. */
|
|
40
|
-
hostDisconnected(): void;
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { HOTKEY_SEQUENCE_DEFAULT_OPTIONS } from "../constants.js";
|
|
2
|
-
import { createHotkeySequenceBindings } from "@tanstack/hotkeys/adapter";
|
|
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
|
-
_options;
|
|
25
|
-
_bindings = createHotkeySequenceBindings();
|
|
26
|
-
_connected = false;
|
|
27
|
-
_boundCallback;
|
|
28
|
-
/**
|
|
29
|
-
* @param _host - The Lit component that owns this controller. Add the controller with `addController()`.
|
|
30
|
-
* @param _sequence - The sequence to register.
|
|
31
|
-
* @param callback - Called with the host as `this`.
|
|
32
|
-
* @param _options - Options or a getter. Property getters are read on connection and after host updates.
|
|
33
|
-
*/
|
|
34
|
-
constructor(_host, _sequence, callback, _options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS) {
|
|
35
|
-
this._host = _host;
|
|
36
|
-
this._sequence = _sequence;
|
|
37
|
-
this._options = _options;
|
|
38
|
-
this._boundCallback = callback.bind(this._host);
|
|
39
|
-
}
|
|
40
|
-
/** Registers when connected and a target is available. */
|
|
41
|
-
hostConnected() {
|
|
42
|
-
this._connected = true;
|
|
43
|
-
this._sync();
|
|
44
|
-
}
|
|
45
|
-
/** Refreshes options after rendering, when scoped targets are available. */
|
|
46
|
-
hostUpdated() {
|
|
47
|
-
if (this._connected) this._sync();
|
|
48
|
-
}
|
|
49
|
-
_sync() {
|
|
50
|
-
const options = typeof this._options === "function" ? this._options() : this._options;
|
|
51
|
-
this._bindings.update([{
|
|
52
|
-
sequence: this._sequence,
|
|
53
|
-
callback: this._boundCallback,
|
|
54
|
-
options
|
|
55
|
-
}]);
|
|
56
|
-
}
|
|
57
|
-
/** Releases registrations when the host disconnects. */
|
|
58
|
-
hostDisconnected() {
|
|
59
|
-
this._connected = false;
|
|
60
|
-
this._bindings.destroy();
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
//#endregion
|
|
65
|
-
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
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { HOTKEY_SEQUENCE_DEFAULT_OPTIONS } from "../constants.js";
|
|
2
|
-
import { HotkeySequenceController } from "../controllers/hotkey-sequence.js";
|
|
3
|
-
|
|
4
|
-
//#region src/decorators/hotkey-sequence.ts
|
|
5
|
-
/**
|
|
6
|
-
* Decorator that registers a keyboard sequence (e.g. Vim-style) on the element
|
|
7
|
-
* when it connects and unregisters when it disconnects. Uses
|
|
8
|
-
* {@link HotkeySequenceController} under the hood.
|
|
9
|
-
*
|
|
10
|
-
* @param sequence - The key sequence to listen for (e.g. `['G', 'G']` for "g g").
|
|
11
|
-
* @param options - Optional sequence options (target, timeout, enabled, etc.).
|
|
12
|
-
* @returns A method decorator for use on LitElement methods.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* class MyElement extends LitElement {
|
|
17
|
-
* @hotkeySequence(['G', 'G'])
|
|
18
|
-
* goToTop() { window.scrollTo(0, 0) }
|
|
19
|
-
*
|
|
20
|
-
* @hotkeySequence(['D', 'D'], { timeout: 500 })
|
|
21
|
-
* deleteLine() { this.deleteCurrentLine() }
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
function hotkeySequence(sequence, options = HOTKEY_SEQUENCE_DEFAULT_OPTIONS) {
|
|
26
|
-
return function(proto, methodName, descriptor) {
|
|
27
|
-
const originalConnected = proto.connectedCallback;
|
|
28
|
-
const controllerKey = Symbol(`@hotkeySequence:${methodName}`);
|
|
29
|
-
proto.connectedCallback = function() {
|
|
30
|
-
originalConnected.call(this);
|
|
31
|
-
const host = this;
|
|
32
|
-
if (!host[controllerKey]) {
|
|
33
|
-
const callback = descriptor.value ? descriptor.value.bind(this) : host[methodName].bind(this);
|
|
34
|
-
if (typeof callback !== "function") throw new Error(`@hotkeySequence decorator can only be applied to functions`);
|
|
35
|
-
const controller = new HotkeySequenceController(this, sequence, callback, options);
|
|
36
|
-
host[controllerKey] = controller;
|
|
37
|
-
this.addController(controller);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
//#endregion
|
|
44
|
-
export { hotkeySequence };
|