@tanstack/lit-hotkeys 0.0.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.
- package/README.md +123 -0
- package/dist/constants.cjs +27 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.js +25 -0
- package/dist/constants.js.map +1 -0
- package/dist/controllers/held-key-codes.cjs +61 -0
- package/dist/controllers/held-key-codes.cjs.map +1 -0
- package/dist/controllers/held-key-codes.d.cts +45 -0
- package/dist/controllers/held-key-codes.d.ts +45 -0
- package/dist/controllers/held-key-codes.js +61 -0
- package/dist/controllers/held-key-codes.js.map +1 -0
- package/dist/controllers/held-keys.cjs +58 -0
- package/dist/controllers/held-keys.cjs.map +1 -0
- package/dist/controllers/held-keys.d.cts +44 -0
- package/dist/controllers/held-keys.d.ts +44 -0
- package/dist/controllers/held-keys.js +58 -0
- package/dist/controllers/held-keys.js.map +1 -0
- package/dist/controllers/hotkey-recorder.cjs +104 -0
- package/dist/controllers/hotkey-recorder.cjs.map +1 -0
- package/dist/controllers/hotkey-recorder.d.cts +75 -0
- package/dist/controllers/hotkey-recorder.d.ts +75 -0
- package/dist/controllers/hotkey-recorder.js +104 -0
- package/dist/controllers/hotkey-recorder.js.map +1 -0
- package/dist/controllers/hotkey-sequence-recorder.cjs +117 -0
- package/dist/controllers/hotkey-sequence-recorder.cjs.map +1 -0
- package/dist/controllers/hotkey-sequence-recorder.d.cts +83 -0
- package/dist/controllers/hotkey-sequence-recorder.d.ts +83 -0
- package/dist/controllers/hotkey-sequence-recorder.js +117 -0
- package/dist/controllers/hotkey-sequence-recorder.js.map +1 -0
- package/dist/controllers/hotkey-sequence.cjs +58 -0
- package/dist/controllers/hotkey-sequence.cjs.map +1 -0
- package/dist/controllers/hotkey-sequence.d.cts +45 -0
- package/dist/controllers/hotkey-sequence.d.ts +45 -0
- package/dist/controllers/hotkey-sequence.js +58 -0
- package/dist/controllers/hotkey-sequence.js.map +1 -0
- package/dist/controllers/hotkey.cjs +60 -0
- package/dist/controllers/hotkey.cjs.map +1 -0
- package/dist/controllers/hotkey.d.cts +45 -0
- package/dist/controllers/hotkey.d.ts +45 -0
- package/dist/controllers/hotkey.js +60 -0
- package/dist/controllers/hotkey.js.map +1 -0
- package/dist/controllers/index.d.cts +7 -0
- package/dist/controllers/index.d.ts +7 -0
- package/dist/controllers/key-hold.cjs +78 -0
- package/dist/controllers/key-hold.cjs.map +1 -0
- package/dist/controllers/key-hold.d.cts +62 -0
- package/dist/controllers/key-hold.d.ts +62 -0
- package/dist/controllers/key-hold.js +78 -0
- package/dist/controllers/key-hold.js.map +1 -0
- package/dist/decorators/hotkey-sequence.cjs +45 -0
- package/dist/decorators/hotkey-sequence.cjs.map +1 -0
- package/dist/decorators/hotkey-sequence.d.cts +28 -0
- package/dist/decorators/hotkey-sequence.d.ts +28 -0
- package/dist/decorators/hotkey-sequence.js +45 -0
- package/dist/decorators/hotkey-sequence.js.map +1 -0
- package/dist/decorators/hotkey.cjs +44 -0
- package/dist/decorators/hotkey.cjs.map +1 -0
- package/dist/decorators/hotkey.d.cts +27 -0
- package/dist/decorators/hotkey.d.ts +27 -0
- package/dist/decorators/hotkey.js +44 -0
- package/dist/decorators/hotkey.js.map +1 -0
- package/dist/decorators/index.d.cts +2 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/index.cjs +27 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +13 -0
- package/package.json +60 -0
- package/src/constants.ts +23 -0
- package/src/controllers/held-key-codes.ts +67 -0
- package/src/controllers/held-keys.ts +64 -0
- package/src/controllers/hotkey-recorder.ts +120 -0
- package/src/controllers/hotkey-sequence-recorder.ts +141 -0
- package/src/controllers/hotkey-sequence.ts +82 -0
- package/src/controllers/hotkey.ts +96 -0
- package/src/controllers/index.ts +7 -0
- package/src/controllers/key-hold.ts +88 -0
- package/src/decorators/hotkey-sequence.ts +68 -0
- package/src/decorators/hotkey.ts +70 -0
- package/src/decorators/index.ts +2 -0
- package/src/index.ts +6 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
let _tanstack_hotkeys = require("@tanstack/hotkeys");
|
|
2
|
+
|
|
3
|
+
//#region src/controllers/key-hold.ts
|
|
4
|
+
/**
|
|
5
|
+
* A Lit ReactiveController that tracks whether a specific key is currently held.
|
|
6
|
+
*
|
|
7
|
+
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
8
|
+
* when the held state of the specified key changes.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* class MyElement extends LitElement {
|
|
13
|
+
* private shiftHold = new KeyHoldController(this, 'Shift')
|
|
14
|
+
*
|
|
15
|
+
* render() {
|
|
16
|
+
* return html`
|
|
17
|
+
* <div style="opacity: ${this.shiftHold.value ? 1 : 0.5}">
|
|
18
|
+
* ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}
|
|
19
|
+
* </div>
|
|
20
|
+
* `
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* class ModifierIndicators extends LitElement {
|
|
28
|
+
* private ctrl = new KeyHoldController(this, 'Control')
|
|
29
|
+
* private shift = new KeyHoldController(this, 'Shift')
|
|
30
|
+
* private alt = new KeyHoldController(this, 'Alt')
|
|
31
|
+
*
|
|
32
|
+
* render() {
|
|
33
|
+
* return html`
|
|
34
|
+
* <span style="opacity: ${this.ctrl.value ? 1 : 0.3}">Ctrl</span>
|
|
35
|
+
* <span style="opacity: ${this.shift.value ? 1 : 0.3}">Shift</span>
|
|
36
|
+
* <span style="opacity: ${this.alt.value ? 1 : 0.3}">Alt</span>
|
|
37
|
+
* `
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
var KeyHoldController = class {
|
|
43
|
+
/** Whether the tracked key is currently held down. */
|
|
44
|
+
get value() {
|
|
45
|
+
return this._value;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @param host - The Lit component that owns this controller.
|
|
49
|
+
* @param key - The key to track (e.g. 'Shift', 'Control', 'A').
|
|
50
|
+
*/
|
|
51
|
+
constructor(_host, _key) {
|
|
52
|
+
this._host = _host;
|
|
53
|
+
this._key = _key;
|
|
54
|
+
this._value = false;
|
|
55
|
+
this._host.addController(this);
|
|
56
|
+
}
|
|
57
|
+
hostConnected() {
|
|
58
|
+
const tracker = (0, _tanstack_hotkeys.getKeyStateTracker)();
|
|
59
|
+
const normalizedKey = this._key.toLowerCase();
|
|
60
|
+
const subscription = tracker.store.subscribe(() => {
|
|
61
|
+
const isHeld = tracker.store.state.heldKeys.some((heldKey) => heldKey.toLowerCase() === normalizedKey);
|
|
62
|
+
if (isHeld !== this._value) {
|
|
63
|
+
this._value = isHeld;
|
|
64
|
+
this._host.requestUpdate();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this._unsubscribe = () => subscription.unsubscribe();
|
|
68
|
+
}
|
|
69
|
+
hostDisconnected() {
|
|
70
|
+
this._unsubscribe?.();
|
|
71
|
+
this._unsubscribe = void 0;
|
|
72
|
+
this._value = false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.KeyHoldController = KeyHoldController;
|
|
78
|
+
//# sourceMappingURL=key-hold.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-hold.cjs","names":[],"sources":["../../src/controllers/key-hold.ts"],"sourcesContent":["import { getKeyStateTracker } from '@tanstack/hotkeys'\nimport type { ReactiveController, ReactiveControllerHost } from 'lit'\nimport type { HeldKey, KeyStateTracker } from '@tanstack/hotkeys'\n\n/**\n * A Lit ReactiveController that tracks whether a specific key is currently held.\n *\n * Subscribes to the global KeyStateTracker and triggers host updates\n * when the held state of the specified key changes.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * private shiftHold = new KeyHoldController(this, 'Shift')\n *\n * render() {\n * return html`\n * <div style=\"opacity: ${this.shiftHold.value ? 1 : 0.5}\">\n * ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}\n * </div>\n * `\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * class ModifierIndicators extends LitElement {\n * private ctrl = new KeyHoldController(this, 'Control')\n * private shift = new KeyHoldController(this, 'Shift')\n * private alt = new KeyHoldController(this, 'Alt')\n *\n * render() {\n * return html`\n * <span style=\"opacity: ${this.ctrl.value ? 1 : 0.3}\">Ctrl</span>\n * <span style=\"opacity: ${this.shift.value ? 1 : 0.3}\">Shift</span>\n * <span style=\"opacity: ${this.alt.value ? 1 : 0.3}\">Alt</span>\n * `\n * }\n * }\n * ```\n */\nexport class KeyHoldController implements ReactiveController {\n /** The unsubscribe function to unsubscribe from the tracker store. */\n private _unsubscribe: (() => void) | undefined\n /** Whether the tracked key is currently held down. */\n private _value = false\n\n /** Whether the tracked key is currently held down. */\n public get value(): boolean {\n return this._value\n }\n\n /**\n * @param host - The Lit component that owns this controller.\n * @param key - The key to track (e.g. 'Shift', 'Control', 'A').\n */\n constructor(\n private _host: ReactiveControllerHost,\n private _key: HeldKey,\n ) {\n this._host.addController(this)\n }\n\n public hostConnected(): void {\n const tracker: KeyStateTracker = getKeyStateTracker()\n const normalizedKey: string = this._key.toLowerCase()\n\n const subscription = tracker.store.subscribe(() => {\n const isHeld: boolean = tracker.store.state.heldKeys.some(\n (heldKey: string) => heldKey.toLowerCase() === normalizedKey,\n )\n\n if (isHeld !== this._value) {\n this._value = isHeld\n this._host.requestUpdate()\n }\n })\n\n this._unsubscribe = () => subscription.unsubscribe()\n }\n\n public hostDisconnected(): void {\n this._unsubscribe?.()\n this._unsubscribe = undefined\n this._value = false\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,oBAAb,MAA6D;;CAO3D,IAAW,QAAiB;AAC1B,SAAO,KAAK;;;;;;CAOd,YACE,AAAQ,OACR,AAAQ,MACR;EAFQ;EACA;gBAbO;AAef,OAAK,MAAM,cAAc,KAAK;;CAGhC,AAAO,gBAAsB;EAC3B,MAAM,qDAA+C;EACrD,MAAM,gBAAwB,KAAK,KAAK,aAAa;EAErD,MAAM,eAAe,QAAQ,MAAM,gBAAgB;GACjD,MAAM,SAAkB,QAAQ,MAAM,MAAM,SAAS,MAClD,YAAoB,QAAQ,aAAa,KAAK,cAChD;AAED,OAAI,WAAW,KAAK,QAAQ;AAC1B,SAAK,SAAS;AACd,SAAK,MAAM,eAAe;;IAE5B;AAEF,OAAK,qBAAqB,aAAa,aAAa;;CAGtD,AAAO,mBAAyB;AAC9B,OAAK,gBAAgB;AACrB,OAAK,eAAe;AACpB,OAAK,SAAS"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { HeldKey } from "@tanstack/hotkeys";
|
|
2
|
+
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/controllers/key-hold.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A Lit ReactiveController that tracks whether a specific key is currently held.
|
|
7
|
+
*
|
|
8
|
+
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
9
|
+
* when the held state of the specified key changes.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* class MyElement extends LitElement {
|
|
14
|
+
* private shiftHold = new KeyHoldController(this, 'Shift')
|
|
15
|
+
*
|
|
16
|
+
* render() {
|
|
17
|
+
* return html`
|
|
18
|
+
* <div style="opacity: ${this.shiftHold.value ? 1 : 0.5}">
|
|
19
|
+
* ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}
|
|
20
|
+
* </div>
|
|
21
|
+
* `
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* class ModifierIndicators extends LitElement {
|
|
29
|
+
* private ctrl = new KeyHoldController(this, 'Control')
|
|
30
|
+
* private shift = new KeyHoldController(this, 'Shift')
|
|
31
|
+
* private alt = new KeyHoldController(this, 'Alt')
|
|
32
|
+
*
|
|
33
|
+
* render() {
|
|
34
|
+
* return html`
|
|
35
|
+
* <span style="opacity: ${this.ctrl.value ? 1 : 0.3}">Ctrl</span>
|
|
36
|
+
* <span style="opacity: ${this.shift.value ? 1 : 0.3}">Shift</span>
|
|
37
|
+
* <span style="opacity: ${this.alt.value ? 1 : 0.3}">Alt</span>
|
|
38
|
+
* `
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare class KeyHoldController implements ReactiveController {
|
|
44
|
+
private _host;
|
|
45
|
+
private _key;
|
|
46
|
+
/** The unsubscribe function to unsubscribe from the tracker store. */
|
|
47
|
+
private _unsubscribe;
|
|
48
|
+
/** Whether the tracked key is currently held down. */
|
|
49
|
+
private _value;
|
|
50
|
+
/** Whether the tracked key is currently held down. */
|
|
51
|
+
get value(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* @param host - The Lit component that owns this controller.
|
|
54
|
+
* @param key - The key to track (e.g. 'Shift', 'Control', 'A').
|
|
55
|
+
*/
|
|
56
|
+
constructor(_host: ReactiveControllerHost, _key: HeldKey);
|
|
57
|
+
hostConnected(): void;
|
|
58
|
+
hostDisconnected(): void;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { KeyHoldController };
|
|
62
|
+
//# sourceMappingURL=key-hold.d.cts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { HeldKey } from "@tanstack/hotkeys";
|
|
2
|
+
import { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/controllers/key-hold.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A Lit ReactiveController that tracks whether a specific key is currently held.
|
|
7
|
+
*
|
|
8
|
+
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
9
|
+
* when the held state of the specified key changes.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* class MyElement extends LitElement {
|
|
14
|
+
* private shiftHold = new KeyHoldController(this, 'Shift')
|
|
15
|
+
*
|
|
16
|
+
* render() {
|
|
17
|
+
* return html`
|
|
18
|
+
* <div style="opacity: ${this.shiftHold.value ? 1 : 0.5}">
|
|
19
|
+
* ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}
|
|
20
|
+
* </div>
|
|
21
|
+
* `
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* class ModifierIndicators extends LitElement {
|
|
29
|
+
* private ctrl = new KeyHoldController(this, 'Control')
|
|
30
|
+
* private shift = new KeyHoldController(this, 'Shift')
|
|
31
|
+
* private alt = new KeyHoldController(this, 'Alt')
|
|
32
|
+
*
|
|
33
|
+
* render() {
|
|
34
|
+
* return html`
|
|
35
|
+
* <span style="opacity: ${this.ctrl.value ? 1 : 0.3}">Ctrl</span>
|
|
36
|
+
* <span style="opacity: ${this.shift.value ? 1 : 0.3}">Shift</span>
|
|
37
|
+
* <span style="opacity: ${this.alt.value ? 1 : 0.3}">Alt</span>
|
|
38
|
+
* `
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare class KeyHoldController implements ReactiveController {
|
|
44
|
+
private _host;
|
|
45
|
+
private _key;
|
|
46
|
+
/** The unsubscribe function to unsubscribe from the tracker store. */
|
|
47
|
+
private _unsubscribe;
|
|
48
|
+
/** Whether the tracked key is currently held down. */
|
|
49
|
+
private _value;
|
|
50
|
+
/** Whether the tracked key is currently held down. */
|
|
51
|
+
get value(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* @param host - The Lit component that owns this controller.
|
|
54
|
+
* @param key - The key to track (e.g. 'Shift', 'Control', 'A').
|
|
55
|
+
*/
|
|
56
|
+
constructor(_host: ReactiveControllerHost, _key: HeldKey);
|
|
57
|
+
hostConnected(): void;
|
|
58
|
+
hostDisconnected(): void;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { KeyHoldController };
|
|
62
|
+
//# sourceMappingURL=key-hold.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getKeyStateTracker } from "@tanstack/hotkeys";
|
|
2
|
+
|
|
3
|
+
//#region src/controllers/key-hold.ts
|
|
4
|
+
/**
|
|
5
|
+
* A Lit ReactiveController that tracks whether a specific key is currently held.
|
|
6
|
+
*
|
|
7
|
+
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
8
|
+
* when the held state of the specified key changes.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* class MyElement extends LitElement {
|
|
13
|
+
* private shiftHold = new KeyHoldController(this, 'Shift')
|
|
14
|
+
*
|
|
15
|
+
* render() {
|
|
16
|
+
* return html`
|
|
17
|
+
* <div style="opacity: ${this.shiftHold.value ? 1 : 0.5}">
|
|
18
|
+
* ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}
|
|
19
|
+
* </div>
|
|
20
|
+
* `
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* class ModifierIndicators extends LitElement {
|
|
28
|
+
* private ctrl = new KeyHoldController(this, 'Control')
|
|
29
|
+
* private shift = new KeyHoldController(this, 'Shift')
|
|
30
|
+
* private alt = new KeyHoldController(this, 'Alt')
|
|
31
|
+
*
|
|
32
|
+
* render() {
|
|
33
|
+
* return html`
|
|
34
|
+
* <span style="opacity: ${this.ctrl.value ? 1 : 0.3}">Ctrl</span>
|
|
35
|
+
* <span style="opacity: ${this.shift.value ? 1 : 0.3}">Shift</span>
|
|
36
|
+
* <span style="opacity: ${this.alt.value ? 1 : 0.3}">Alt</span>
|
|
37
|
+
* `
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
var KeyHoldController = class {
|
|
43
|
+
/** Whether the tracked key is currently held down. */
|
|
44
|
+
get value() {
|
|
45
|
+
return this._value;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @param host - The Lit component that owns this controller.
|
|
49
|
+
* @param key - The key to track (e.g. 'Shift', 'Control', 'A').
|
|
50
|
+
*/
|
|
51
|
+
constructor(_host, _key) {
|
|
52
|
+
this._host = _host;
|
|
53
|
+
this._key = _key;
|
|
54
|
+
this._value = false;
|
|
55
|
+
this._host.addController(this);
|
|
56
|
+
}
|
|
57
|
+
hostConnected() {
|
|
58
|
+
const tracker = getKeyStateTracker();
|
|
59
|
+
const normalizedKey = this._key.toLowerCase();
|
|
60
|
+
const subscription = tracker.store.subscribe(() => {
|
|
61
|
+
const isHeld = tracker.store.state.heldKeys.some((heldKey) => heldKey.toLowerCase() === normalizedKey);
|
|
62
|
+
if (isHeld !== this._value) {
|
|
63
|
+
this._value = isHeld;
|
|
64
|
+
this._host.requestUpdate();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this._unsubscribe = () => subscription.unsubscribe();
|
|
68
|
+
}
|
|
69
|
+
hostDisconnected() {
|
|
70
|
+
this._unsubscribe?.();
|
|
71
|
+
this._unsubscribe = void 0;
|
|
72
|
+
this._value = false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { KeyHoldController };
|
|
78
|
+
//# sourceMappingURL=key-hold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-hold.js","names":[],"sources":["../../src/controllers/key-hold.ts"],"sourcesContent":["import { getKeyStateTracker } from '@tanstack/hotkeys'\nimport type { ReactiveController, ReactiveControllerHost } from 'lit'\nimport type { HeldKey, KeyStateTracker } from '@tanstack/hotkeys'\n\n/**\n * A Lit ReactiveController that tracks whether a specific key is currently held.\n *\n * Subscribes to the global KeyStateTracker and triggers host updates\n * when the held state of the specified key changes.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * private shiftHold = new KeyHoldController(this, 'Shift')\n *\n * render() {\n * return html`\n * <div style=\"opacity: ${this.shiftHold.value ? 1 : 0.5}\">\n * ${this.shiftHold.value ? 'Shift is pressed!' : 'Press Shift'}\n * </div>\n * `\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * class ModifierIndicators extends LitElement {\n * private ctrl = new KeyHoldController(this, 'Control')\n * private shift = new KeyHoldController(this, 'Shift')\n * private alt = new KeyHoldController(this, 'Alt')\n *\n * render() {\n * return html`\n * <span style=\"opacity: ${this.ctrl.value ? 1 : 0.3}\">Ctrl</span>\n * <span style=\"opacity: ${this.shift.value ? 1 : 0.3}\">Shift</span>\n * <span style=\"opacity: ${this.alt.value ? 1 : 0.3}\">Alt</span>\n * `\n * }\n * }\n * ```\n */\nexport class KeyHoldController implements ReactiveController {\n /** The unsubscribe function to unsubscribe from the tracker store. */\n private _unsubscribe: (() => void) | undefined\n /** Whether the tracked key is currently held down. */\n private _value = false\n\n /** Whether the tracked key is currently held down. */\n public get value(): boolean {\n return this._value\n }\n\n /**\n * @param host - The Lit component that owns this controller.\n * @param key - The key to track (e.g. 'Shift', 'Control', 'A').\n */\n constructor(\n private _host: ReactiveControllerHost,\n private _key: HeldKey,\n ) {\n this._host.addController(this)\n }\n\n public hostConnected(): void {\n const tracker: KeyStateTracker = getKeyStateTracker()\n const normalizedKey: string = this._key.toLowerCase()\n\n const subscription = tracker.store.subscribe(() => {\n const isHeld: boolean = tracker.store.state.heldKeys.some(\n (heldKey: string) => heldKey.toLowerCase() === normalizedKey,\n )\n\n if (isHeld !== this._value) {\n this._value = isHeld\n this._host.requestUpdate()\n }\n })\n\n this._unsubscribe = () => subscription.unsubscribe()\n }\n\n public hostDisconnected(): void {\n this._unsubscribe?.()\n this._unsubscribe = undefined\n this._value = false\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,oBAAb,MAA6D;;CAO3D,IAAW,QAAiB;AAC1B,SAAO,KAAK;;;;;;CAOd,YACE,AAAQ,OACR,AAAQ,MACR;EAFQ;EACA;gBAbO;AAef,OAAK,MAAM,cAAc,KAAK;;CAGhC,AAAO,gBAAsB;EAC3B,MAAM,UAA2B,oBAAoB;EACrD,MAAM,gBAAwB,KAAK,KAAK,aAAa;EAErD,MAAM,eAAe,QAAQ,MAAM,gBAAgB;GACjD,MAAM,SAAkB,QAAQ,MAAM,MAAM,SAAS,MAClD,YAAoB,QAAQ,aAAa,KAAK,cAChD;AAED,OAAI,WAAW,KAAK,QAAQ;AAC1B,SAAK,SAAS;AACd,SAAK,MAAM,eAAe;;IAE5B;AAEF,OAAK,qBAAqB,aAAa,aAAa;;CAGtD,AAAO,mBAAyB;AAC9B,OAAK,gBAAgB;AACrB,OAAK,eAAe;AACpB,OAAK,SAAS"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const require_constants = require('../constants.cjs');
|
|
2
|
+
const require_hotkey_sequence = require('../controllers/hotkey-sequence.cjs');
|
|
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 = require_constants.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 require_hotkey_sequence.HotkeySequenceController(this, sequence, callback, options);
|
|
36
|
+
host[controllerKey] = controller;
|
|
37
|
+
this.addController(controller);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
exports.hotkeySequence = hotkeySequence;
|
|
45
|
+
//# sourceMappingURL=hotkey-sequence.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hotkey-sequence.cjs","names":["HOTKEY_SEQUENCE_DEFAULT_OPTIONS","HotkeySequenceController"],"sources":["../../src/decorators/hotkey-sequence.ts"],"sourcesContent":["import { HotkeySequenceController } from '../controllers/hotkey-sequence'\nimport { HOTKEY_SEQUENCE_DEFAULT_OPTIONS } from '../constants'\nimport type { LitElement } from 'lit'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n} from '@tanstack/hotkeys'\n\n/**\n * Decorator that registers a keyboard sequence (e.g. Vim-style) on the element\n * when it connects and unregisters when it disconnects. Uses\n * {@link HotkeySequenceController} under the hood.\n *\n * @param sequence - The key sequence to listen for (e.g. `['G', 'G']` for \"g g\").\n * @param options - Optional sequence options (target, timeout, enabled, etc.).\n * @returns A method decorator for use on LitElement methods.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * @hotkeySequence(['G', 'G'])\n * goToTop() { window.scrollTo(0, 0) }\n *\n * @hotkeySequence(['D', 'D'], { timeout: 500 })\n * deleteLine() { this.deleteCurrentLine() }\n * }\n * ```\n */\nexport function hotkeySequence(\n sequence: HotkeySequence,\n options: SequenceOptions = HOTKEY_SEQUENCE_DEFAULT_OPTIONS,\n) {\n return function <T extends HotkeyCallback>(\n proto: LitElement,\n methodName: string,\n descriptor: TypedPropertyDescriptor<T>,\n ) {\n const originalConnected = proto.connectedCallback\n const controllerKey = Symbol(`@hotkeySequence:${methodName}`)\n\n proto.connectedCallback = function () {\n originalConnected.call(this)\n\n const host = this as unknown as {\n [key: symbol]: HotkeySequenceController | undefined\n addController: (c: unknown) => void\n [key: string]: unknown\n }\n if (!host[controllerKey]) {\n const callback: HotkeyCallback = descriptor.value\n ? descriptor.value.bind(this)\n : (host[methodName] as HotkeyCallback).bind(this)\n\n if (typeof callback !== 'function') {\n throw new Error(\n `@hotkeySequence decorator can only be applied to functions`,\n )\n }\n\n const controller: HotkeySequenceController =\n new HotkeySequenceController(this, sequence, callback, options)\n host[controllerKey] = controller\n this.addController(controller)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,eACd,UACA,UAA2BA,mDAC3B;AACA,QAAO,SACL,OACA,YACA,YACA;EACA,MAAM,oBAAoB,MAAM;EAChC,MAAM,gBAAgB,OAAO,mBAAmB,aAAa;AAE7D,QAAM,oBAAoB,WAAY;AACpC,qBAAkB,KAAK,KAAK;GAE5B,MAAM,OAAO;AAKb,OAAI,CAAC,KAAK,gBAAgB;IACxB,MAAM,WAA2B,WAAW,QACxC,WAAW,MAAM,KAAK,KAAK,GAC1B,KAAK,YAA+B,KAAK,KAAK;AAEnD,QAAI,OAAO,aAAa,WACtB,OAAM,IAAI,MACR,6DACD;IAGH,MAAM,aACJ,IAAIC,iDAAyB,MAAM,UAAU,UAAU,QAAQ;AACjE,SAAK,iBAAiB;AACtB,SAAK,cAAc,WAAW"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
|
|
2
|
+
import { LitElement } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/decorators/hotkey-sequence.d.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
|
+
declare function hotkeySequence(sequence: HotkeySequence, options?: SequenceOptions): <T extends HotkeyCallback>(proto: LitElement, methodName: string, descriptor: TypedPropertyDescriptor<T>) => void;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { hotkeySequence };
|
|
28
|
+
//# sourceMappingURL=hotkey-sequence.d.cts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
|
|
2
|
+
import { LitElement } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/decorators/hotkey-sequence.d.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
|
+
declare function hotkeySequence(sequence: HotkeySequence, options?: SequenceOptions): <T extends HotkeyCallback>(proto: LitElement, methodName: string, descriptor: TypedPropertyDescriptor<T>) => void;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { hotkeySequence };
|
|
28
|
+
//# sourceMappingURL=hotkey-sequence.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
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 };
|
|
45
|
+
//# sourceMappingURL=hotkey-sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hotkey-sequence.js","names":[],"sources":["../../src/decorators/hotkey-sequence.ts"],"sourcesContent":["import { HotkeySequenceController } from '../controllers/hotkey-sequence'\nimport { HOTKEY_SEQUENCE_DEFAULT_OPTIONS } from '../constants'\nimport type { LitElement } from 'lit'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n} from '@tanstack/hotkeys'\n\n/**\n * Decorator that registers a keyboard sequence (e.g. Vim-style) on the element\n * when it connects and unregisters when it disconnects. Uses\n * {@link HotkeySequenceController} under the hood.\n *\n * @param sequence - The key sequence to listen for (e.g. `['G', 'G']` for \"g g\").\n * @param options - Optional sequence options (target, timeout, enabled, etc.).\n * @returns A method decorator for use on LitElement methods.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * @hotkeySequence(['G', 'G'])\n * goToTop() { window.scrollTo(0, 0) }\n *\n * @hotkeySequence(['D', 'D'], { timeout: 500 })\n * deleteLine() { this.deleteCurrentLine() }\n * }\n * ```\n */\nexport function hotkeySequence(\n sequence: HotkeySequence,\n options: SequenceOptions = HOTKEY_SEQUENCE_DEFAULT_OPTIONS,\n) {\n return function <T extends HotkeyCallback>(\n proto: LitElement,\n methodName: string,\n descriptor: TypedPropertyDescriptor<T>,\n ) {\n const originalConnected = proto.connectedCallback\n const controllerKey = Symbol(`@hotkeySequence:${methodName}`)\n\n proto.connectedCallback = function () {\n originalConnected.call(this)\n\n const host = this as unknown as {\n [key: symbol]: HotkeySequenceController | undefined\n addController: (c: unknown) => void\n [key: string]: unknown\n }\n if (!host[controllerKey]) {\n const callback: HotkeyCallback = descriptor.value\n ? descriptor.value.bind(this)\n : (host[methodName] as HotkeyCallback).bind(this)\n\n if (typeof callback !== 'function') {\n throw new Error(\n `@hotkeySequence decorator can only be applied to functions`,\n )\n }\n\n const controller: HotkeySequenceController =\n new HotkeySequenceController(this, sequence, callback, options)\n host[controllerKey] = controller\n this.addController(controller)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,eACd,UACA,UAA2B,iCAC3B;AACA,QAAO,SACL,OACA,YACA,YACA;EACA,MAAM,oBAAoB,MAAM;EAChC,MAAM,gBAAgB,OAAO,mBAAmB,aAAa;AAE7D,QAAM,oBAAoB,WAAY;AACpC,qBAAkB,KAAK,KAAK;GAE5B,MAAM,OAAO;AAKb,OAAI,CAAC,KAAK,gBAAgB;IACxB,MAAM,WAA2B,WAAW,QACxC,WAAW,MAAM,KAAK,KAAK,GAC1B,KAAK,YAA+B,KAAK,KAAK;AAEnD,QAAI,OAAO,aAAa,WACtB,OAAM,IAAI,MACR,6DACD;IAGH,MAAM,aACJ,IAAI,yBAAyB,MAAM,UAAU,UAAU,QAAQ;AACjE,SAAK,iBAAiB;AACtB,SAAK,cAAc,WAAW"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const require_constants = require('../constants.cjs');
|
|
2
|
+
const require_hotkey = require('../controllers/hotkey.cjs');
|
|
3
|
+
|
|
4
|
+
//#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 = require_constants.HOTKEY_DEFAULT_OPTIONS) {
|
|
25
|
+
return function(proto, propertyKey, descriptor) {
|
|
26
|
+
const originalConnected = proto.connectedCallback;
|
|
27
|
+
const controllerKey = Symbol(`@hotkey:${propertyKey}`);
|
|
28
|
+
proto.connectedCallback = function() {
|
|
29
|
+
originalConnected.call(this);
|
|
30
|
+
const host = this;
|
|
31
|
+
if (!host[controllerKey]) {
|
|
32
|
+
const callback = descriptor?.value ? descriptor.value.bind(this) : host[propertyKey];
|
|
33
|
+
if (typeof callback !== "function") throw new Error(`@hotkey decorator can only be applied to functions`);
|
|
34
|
+
const controller = new require_hotkey.HotkeyController(this, hotkey, callback, options);
|
|
35
|
+
host[controllerKey] = controller;
|
|
36
|
+
this.addController(controller);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
exports.hotkey = hotkey;
|
|
44
|
+
//# sourceMappingURL=hotkey.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hotkey.cjs","names":["HOTKEY_DEFAULT_OPTIONS","HotkeyController"],"sources":["../../src/decorators/hotkey.ts"],"sourcesContent":["import { HotkeyController } from '../controllers/hotkey'\nimport { HOTKEY_DEFAULT_OPTIONS } from '../constants'\nimport type { LitElement } from 'lit'\nimport type {\n HotkeyCallback,\n HotkeyOptions,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\n/**\n * Decorator that registers a keyboard hotkey on the element when it connects\n * and unregisters when it disconnects. Uses {@link HotkeyController} under the hood.\n *\n * @param hotkey - The key or key combo to listen for (e.g. `'Mod+S'` or a raw hotkey object).\n * @param options - Optional registration options (target, platform, enabled, etc.).\n * @returns A method decorator for use on LitElement methods.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * @hotkey('Mod+S')\n * save() { this.doSave() }\n *\n * @hotkey('Escape')\n * close() { this.dismiss() }\n * }\n * ```\n */\nexport function hotkey(\n hotkey: RegisterableHotkey,\n options: HotkeyOptions = HOTKEY_DEFAULT_OPTIONS,\n) {\n return function <T extends HotkeyCallback>(\n proto: LitElement,\n propertyKey: string,\n descriptor?: TypedPropertyDescriptor<T>,\n ) {\n const originalConnected = proto.connectedCallback\n const controllerKey = Symbol(`@hotkey:${propertyKey}`)\n\n proto.connectedCallback = function () {\n originalConnected.call(this)\n\n const host = this as unknown as {\n [key: symbol]: HotkeyController | undefined\n addController: (c: unknown) => void\n [key: string]: unknown\n }\n\n if (!host[controllerKey]) {\n const callback: HotkeyCallback = descriptor?.value\n ? (descriptor.value.bind(this) as HotkeyCallback)\n : (host[propertyKey] as HotkeyCallback)\n\n if (typeof callback !== 'function') {\n throw new Error(`@hotkey decorator can only be applied to functions`)\n }\n\n const controller: HotkeyController = new HotkeyController(\n this,\n hotkey,\n callback,\n options,\n )\n host[controllerKey] = controller\n this.addController(controller)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,OACd,QACA,UAAyBA,0CACzB;AACA,QAAO,SACL,OACA,aACA,YACA;EACA,MAAM,oBAAoB,MAAM;EAChC,MAAM,gBAAgB,OAAO,WAAW,cAAc;AAEtD,QAAM,oBAAoB,WAAY;AACpC,qBAAkB,KAAK,KAAK;GAE5B,MAAM,OAAO;AAMb,OAAI,CAAC,KAAK,gBAAgB;IACxB,MAAM,WAA2B,YAAY,QACxC,WAAW,MAAM,KAAK,KAAK,GAC3B,KAAK;AAEV,QAAI,OAAO,aAAa,WACtB,OAAM,IAAI,MAAM,qDAAqD;IAGvE,MAAM,aAA+B,IAAIC,gCACvC,MACA,QACA,UACA,QACD;AACD,SAAK,iBAAiB;AACtB,SAAK,cAAc,WAAW"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
|
|
2
|
+
import { LitElement } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/decorators/hotkey.d.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
|
+
declare function hotkey(hotkey: RegisterableHotkey, options?: HotkeyOptions): <T extends HotkeyCallback>(proto: LitElement, propertyKey: string, descriptor?: TypedPropertyDescriptor<T>) => void;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { hotkey };
|
|
27
|
+
//# sourceMappingURL=hotkey.d.cts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
|
|
2
|
+
import { LitElement } from "lit";
|
|
3
|
+
|
|
4
|
+
//#region src/decorators/hotkey.d.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
|
+
declare function hotkey(hotkey: RegisterableHotkey, options?: HotkeyOptions): <T extends HotkeyCallback>(proto: LitElement, propertyKey: string, descriptor?: TypedPropertyDescriptor<T>) => void;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { hotkey };
|
|
27
|
+
//# sourceMappingURL=hotkey.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { HOTKEY_DEFAULT_OPTIONS } from "../constants.js";
|
|
2
|
+
import { HotkeyController } from "../controllers/hotkey.js";
|
|
3
|
+
|
|
4
|
+
//#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) {
|
|
25
|
+
return function(proto, propertyKey, descriptor) {
|
|
26
|
+
const originalConnected = proto.connectedCallback;
|
|
27
|
+
const controllerKey = Symbol(`@hotkey:${propertyKey}`);
|
|
28
|
+
proto.connectedCallback = function() {
|
|
29
|
+
originalConnected.call(this);
|
|
30
|
+
const host = this;
|
|
31
|
+
if (!host[controllerKey]) {
|
|
32
|
+
const callback = descriptor?.value ? descriptor.value.bind(this) : host[propertyKey];
|
|
33
|
+
if (typeof callback !== "function") throw new Error(`@hotkey decorator can only be applied to functions`);
|
|
34
|
+
const controller = new HotkeyController(this, hotkey, callback, options);
|
|
35
|
+
host[controllerKey] = controller;
|
|
36
|
+
this.addController(controller);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { hotkey };
|
|
44
|
+
//# sourceMappingURL=hotkey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hotkey.js","names":[],"sources":["../../src/decorators/hotkey.ts"],"sourcesContent":["import { HotkeyController } from '../controllers/hotkey'\nimport { HOTKEY_DEFAULT_OPTIONS } from '../constants'\nimport type { LitElement } from 'lit'\nimport type {\n HotkeyCallback,\n HotkeyOptions,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\n/**\n * Decorator that registers a keyboard hotkey on the element when it connects\n * and unregisters when it disconnects. Uses {@link HotkeyController} under the hood.\n *\n * @param hotkey - The key or key combo to listen for (e.g. `'Mod+S'` or a raw hotkey object).\n * @param options - Optional registration options (target, platform, enabled, etc.).\n * @returns A method decorator for use on LitElement methods.\n *\n * @example\n * ```ts\n * class MyElement extends LitElement {\n * @hotkey('Mod+S')\n * save() { this.doSave() }\n *\n * @hotkey('Escape')\n * close() { this.dismiss() }\n * }\n * ```\n */\nexport function hotkey(\n hotkey: RegisterableHotkey,\n options: HotkeyOptions = HOTKEY_DEFAULT_OPTIONS,\n) {\n return function <T extends HotkeyCallback>(\n proto: LitElement,\n propertyKey: string,\n descriptor?: TypedPropertyDescriptor<T>,\n ) {\n const originalConnected = proto.connectedCallback\n const controllerKey = Symbol(`@hotkey:${propertyKey}`)\n\n proto.connectedCallback = function () {\n originalConnected.call(this)\n\n const host = this as unknown as {\n [key: symbol]: HotkeyController | undefined\n addController: (c: unknown) => void\n [key: string]: unknown\n }\n\n if (!host[controllerKey]) {\n const callback: HotkeyCallback = descriptor?.value\n ? (descriptor.value.bind(this) as HotkeyCallback)\n : (host[propertyKey] as HotkeyCallback)\n\n if (typeof callback !== 'function') {\n throw new Error(`@hotkey decorator can only be applied to functions`)\n }\n\n const controller: HotkeyController = new HotkeyController(\n this,\n hotkey,\n callback,\n options,\n )\n host[controllerKey] = controller\n this.addController(controller)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,OACd,QACA,UAAyB,wBACzB;AACA,QAAO,SACL,OACA,aACA,YACA;EACA,MAAM,oBAAoB,MAAM;EAChC,MAAM,gBAAgB,OAAO,WAAW,cAAc;AAEtD,QAAM,oBAAoB,WAAY;AACpC,qBAAkB,KAAK,KAAK;GAE5B,MAAM,OAAO;AAMb,OAAI,CAAC,KAAK,gBAAgB;IACxB,MAAM,WAA2B,YAAY,QACxC,WAAW,MAAM,KAAK,KAAK,GAC3B,KAAK;AAEV,QAAI,OAAO,aAAa,WACtB,OAAM,IAAI,MAAM,qDAAqD;IAGvE,MAAM,aAA+B,IAAI,iBACvC,MACA,QACA,UACA,QACD;AACD,SAAK,iBAAiB;AACtB,SAAK,cAAc,WAAW"}
|