@tanstack/lit-hotkeys 0.12.0 → 0.13.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/constants.js +1 -2
- package/dist/controllers/held-key-codes.d.ts +2 -5
- package/dist/controllers/held-key-codes.js +6 -3
- package/dist/controllers/held-keys.d.ts +2 -5
- package/dist/controllers/held-keys.js +6 -3
- package/dist/controllers/hotkey-hint.d.ts +2 -5
- package/dist/controllers/hotkey-hint.js +6 -3
- package/dist/controllers/hotkey-recorder.d.ts +2 -5
- package/dist/controllers/hotkey-recorder.js +11 -4
- package/dist/controllers/hotkey-registrations.d.ts +2 -5
- package/dist/controllers/hotkey-registrations.js +6 -4
- package/dist/controllers/hotkey-sequence-recorder.d.ts +2 -5
- package/dist/controllers/hotkey-sequence-recorder.js +13 -5
- package/dist/controllers/hotkey-sequence.d.ts +2 -5
- package/dist/controllers/hotkey-sequence.js +7 -2
- package/dist/controllers/hotkey.d.ts +2 -5
- package/dist/controllers/hotkey.js +7 -2
- package/dist/controllers/index.d.ts +2 -1
- package/dist/controllers/key-hold.d.ts +2 -5
- package/dist/controllers/key-hold.js +7 -3
- package/dist/decorators/hotkey-sequence.d.ts +2 -5
- package/dist/decorators/hotkey-sequence.js +1 -2
- package/dist/decorators/hotkey.d.ts +2 -5
- package/dist/decorators/hotkey.js +1 -2
- package/dist/decorators/index.d.ts +2 -1
- package/dist/index.d.ts +2 -0
- package/package.json +9 -14
- package/dist/constants.cjs +0 -27
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/controllers/held-key-codes.cjs +0 -61
- package/dist/controllers/held-key-codes.cjs.map +0 -1
- package/dist/controllers/held-key-codes.d.cts +0 -45
- package/dist/controllers/held-key-codes.js.map +0 -1
- package/dist/controllers/held-keys.cjs +0 -58
- package/dist/controllers/held-keys.cjs.map +0 -1
- package/dist/controllers/held-keys.d.cts +0 -44
- package/dist/controllers/held-keys.js.map +0 -1
- package/dist/controllers/hotkey-hint.cjs +0 -47
- package/dist/controllers/hotkey-hint.cjs.map +0 -1
- package/dist/controllers/hotkey-hint.d.cts +0 -27
- package/dist/controllers/hotkey-hint.js.map +0 -1
- package/dist/controllers/hotkey-recorder.cjs +0 -104
- package/dist/controllers/hotkey-recorder.cjs.map +0 -1
- package/dist/controllers/hotkey-recorder.d.cts +0 -75
- package/dist/controllers/hotkey-recorder.js.map +0 -1
- package/dist/controllers/hotkey-registrations.cjs +0 -70
- package/dist/controllers/hotkey-registrations.cjs.map +0 -1
- package/dist/controllers/hotkey-registrations.d.cts +0 -44
- package/dist/controllers/hotkey-registrations.js.map +0 -1
- package/dist/controllers/hotkey-sequence-recorder.cjs +0 -117
- package/dist/controllers/hotkey-sequence-recorder.cjs.map +0 -1
- package/dist/controllers/hotkey-sequence-recorder.d.cts +0 -83
- package/dist/controllers/hotkey-sequence-recorder.js.map +0 -1
- package/dist/controllers/hotkey-sequence.cjs +0 -58
- package/dist/controllers/hotkey-sequence.cjs.map +0 -1
- package/dist/controllers/hotkey-sequence.d.cts +0 -45
- package/dist/controllers/hotkey-sequence.js.map +0 -1
- package/dist/controllers/hotkey.cjs +0 -60
- package/dist/controllers/hotkey.cjs.map +0 -1
- package/dist/controllers/hotkey.d.cts +0 -45
- package/dist/controllers/hotkey.js.map +0 -1
- package/dist/controllers/index.d.cts +0 -9
- package/dist/controllers/key-hold.cjs +0 -78
- package/dist/controllers/key-hold.cjs.map +0 -1
- package/dist/controllers/key-hold.d.cts +0 -62
- package/dist/controllers/key-hold.js.map +0 -1
- package/dist/decorators/hotkey-sequence.cjs +0 -45
- package/dist/decorators/hotkey-sequence.cjs.map +0 -1
- package/dist/decorators/hotkey-sequence.d.cts +0 -28
- package/dist/decorators/hotkey-sequence.js.map +0 -1
- package/dist/decorators/hotkey.cjs +0 -44
- package/dist/decorators/hotkey.cjs.map +0 -1
- package/dist/decorators/hotkey.d.cts +0 -27
- package/dist/decorators/hotkey.js.map +0 -1
- package/dist/decorators/index.d.cts +0 -2
- package/dist/index.cjs +0 -31
- package/dist/index.d.cts +0 -13
- package/src/constants.ts +0 -23
- package/src/controllers/held-key-codes.ts +0 -67
- package/src/controllers/held-keys.ts +0 -64
- package/src/controllers/hotkey-hint.ts +0 -56
- package/src/controllers/hotkey-recorder.ts +0 -120
- package/src/controllers/hotkey-registrations.ts +0 -89
- package/src/controllers/hotkey-sequence-recorder.ts +0 -141
- package/src/controllers/hotkey-sequence.ts +0 -82
- package/src/controllers/hotkey.ts +0 -96
- package/src/controllers/index.ts +0 -9
- package/src/controllers/key-hold.ts +0 -88
- package/src/decorators/hotkey-sequence.ts +0 -68
- package/src/decorators/hotkey.ts +0 -70
- package/src/decorators/index.ts +0 -2
- package/src/index.ts +0 -6
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { IndividualKey } 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: IndividualKey);
|
|
57
|
-
hostConnected(): void;
|
|
58
|
-
hostDisconnected(): void;
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { KeyHoldController };
|
|
62
|
-
//# sourceMappingURL=key-hold.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
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 { IndividualKey, 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: IndividualKey,\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"}
|
|
@@ -1,45 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,28 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,44 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/index.cjs
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_hotkey_sequence = require('./controllers/hotkey-sequence.cjs');
|
|
3
|
-
const require_hotkey_sequence$1 = require('./decorators/hotkey-sequence.cjs');
|
|
4
|
-
const require_hotkey = require('./controllers/hotkey.cjs');
|
|
5
|
-
const require_hotkey$1 = require('./decorators/hotkey.cjs');
|
|
6
|
-
const require_held_key_codes = require('./controllers/held-key-codes.cjs');
|
|
7
|
-
const require_held_keys = require('./controllers/held-keys.cjs');
|
|
8
|
-
const require_hotkey_recorder = require('./controllers/hotkey-recorder.cjs');
|
|
9
|
-
const require_hotkey_registrations = require('./controllers/hotkey-registrations.cjs');
|
|
10
|
-
const require_hotkey_sequence_recorder = require('./controllers/hotkey-sequence-recorder.cjs');
|
|
11
|
-
const require_key_hold = require('./controllers/key-hold.cjs');
|
|
12
|
-
const require_hotkey_hint = require('./controllers/hotkey-hint.cjs');
|
|
13
|
-
|
|
14
|
-
exports.HeldKeyCodesController = require_held_key_codes.HeldKeyCodesController;
|
|
15
|
-
exports.HeldKeysController = require_held_keys.HeldKeysController;
|
|
16
|
-
exports.HotkeyController = require_hotkey.HotkeyController;
|
|
17
|
-
exports.HotkeyHintController = require_hotkey_hint.HotkeyHintController;
|
|
18
|
-
exports.HotkeyRecorderController = require_hotkey_recorder.HotkeyRecorderController;
|
|
19
|
-
exports.HotkeyRegistrationsController = require_hotkey_registrations.HotkeyRegistrationsController;
|
|
20
|
-
exports.HotkeySequenceController = require_hotkey_sequence.HotkeySequenceController;
|
|
21
|
-
exports.HotkeySequenceRecorderController = require_hotkey_sequence_recorder.HotkeySequenceRecorderController;
|
|
22
|
-
exports.KeyHoldController = require_key_hold.KeyHoldController;
|
|
23
|
-
exports.hotkey = require_hotkey$1.hotkey;
|
|
24
|
-
exports.hotkeySequence = require_hotkey_sequence$1.hotkeySequence;
|
|
25
|
-
var _tanstack_hotkeys = require("@tanstack/hotkeys");
|
|
26
|
-
Object.keys(_tanstack_hotkeys).forEach(function (k) {
|
|
27
|
-
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
get: function () { return _tanstack_hotkeys[k]; }
|
|
30
|
-
});
|
|
31
|
-
});
|
package/dist/index.d.cts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { hotkeySequence } from "./decorators/hotkey-sequence.cjs";
|
|
2
|
-
import { hotkey } from "./decorators/hotkey.cjs";
|
|
3
|
-
import { HeldKeyCodesController } from "./controllers/held-key-codes.cjs";
|
|
4
|
-
import { HeldKeysController } from "./controllers/held-keys.cjs";
|
|
5
|
-
import { HotkeyController } from "./controllers/hotkey.cjs";
|
|
6
|
-
import { HotkeyRecorderController } from "./controllers/hotkey-recorder.cjs";
|
|
7
|
-
import { HotkeyRegistrationsController } from "./controllers/hotkey-registrations.cjs";
|
|
8
|
-
import { HotkeySequenceController } from "./controllers/hotkey-sequence.cjs";
|
|
9
|
-
import { HotkeySequenceRecorderController } from "./controllers/hotkey-sequence-recorder.cjs";
|
|
10
|
-
import { KeyHoldController } from "./controllers/key-hold.cjs";
|
|
11
|
-
import { HotkeyHintController } from "./controllers/hotkey-hint.cjs";
|
|
12
|
-
export * from "@tanstack/hotkeys";
|
|
13
|
-
export { HeldKeyCodesController, HeldKeysController, HotkeyController, HotkeyHintController, HotkeyRecorderController, HotkeyRegistrationsController, HotkeySequenceController, HotkeySequenceRecorderController, KeyHoldController, hotkey, hotkeySequence };
|
package/src/constants.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { HotkeyOptions, SequenceOptions } from '@tanstack/hotkeys'
|
|
2
|
-
|
|
3
|
-
export const HOTKEY_DEFAULT_OPTIONS: HotkeyOptions = {
|
|
4
|
-
enabled: true,
|
|
5
|
-
preventDefault: true,
|
|
6
|
-
stopPropagation: true,
|
|
7
|
-
eventType: 'keydown',
|
|
8
|
-
requireReset: false,
|
|
9
|
-
ignoreInputs: undefined, // smart default: false for Mod+S, true for single keys
|
|
10
|
-
platform: undefined, // auto-detected
|
|
11
|
-
conflictBehavior: 'warn',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const HOTKEY_SEQUENCE_DEFAULT_OPTIONS: SequenceOptions = {
|
|
15
|
-
enabled: true,
|
|
16
|
-
timeout: 1000,
|
|
17
|
-
preventDefault: true,
|
|
18
|
-
stopPropagation: true,
|
|
19
|
-
eventType: 'keydown',
|
|
20
|
-
ignoreInputs: undefined, // smart default: false for Mod+S, true for single keys
|
|
21
|
-
platform: undefined, // auto-detected
|
|
22
|
-
conflictBehavior: 'warn',
|
|
23
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { getKeyStateTracker } from '@tanstack/hotkeys'
|
|
2
|
-
import type { KeyStateTracker } from '@tanstack/hotkeys'
|
|
3
|
-
import type { ReactiveController, ReactiveControllerHost } from 'lit'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Lit ReactiveController that tracks all currently held key names to their physical `event.code` values.
|
|
7
|
-
*
|
|
8
|
-
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
9
|
-
* whenever keys are pressed or released.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* class KeyDisplay extends LitElement {
|
|
14
|
-
* private heldKeyCodes = new HeldKeyCodesController(this)
|
|
15
|
-
*
|
|
16
|
-
* render() {
|
|
17
|
-
* const heldCodes = Object.entries(this.heldKeyCodes.value).map(([key, code]) => `${key}: ${code}`).join(' + ')
|
|
18
|
-
* return html`
|
|
19
|
-
* <div>
|
|
20
|
-
* Currently pressed: ${heldCodes || 'None'}
|
|
21
|
-
* </div>
|
|
22
|
-
* `
|
|
23
|
-
* }
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
export class HeldKeyCodesController implements ReactiveController {
|
|
28
|
-
/** The unsubscribe function to unsubscribe from the tracker store. */
|
|
29
|
-
private _unsubscribe: (() => void) | undefined
|
|
30
|
-
/** The currently held key names to their physical `event.code` values. */
|
|
31
|
-
private _value: Record<string, string> = {}
|
|
32
|
-
|
|
33
|
-
/** Map of currently held key names to their physical `event.code` values. */
|
|
34
|
-
public get value(): Record<string, string> {
|
|
35
|
-
return this._value
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param _host - The Lit component that owns this controller.
|
|
40
|
-
*/
|
|
41
|
-
constructor(private _host: ReactiveControllerHost) {
|
|
42
|
-
this._host.addController(this)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Subscribes to the tracker store and updates the internal state when changes occur. */
|
|
46
|
-
public hostConnected(): void {
|
|
47
|
-
const tracker: KeyStateTracker = getKeyStateTracker()
|
|
48
|
-
this._value = tracker.store.state.heldCodes
|
|
49
|
-
this._host.requestUpdate()
|
|
50
|
-
|
|
51
|
-
const subscription = tracker.store.subscribe(() => {
|
|
52
|
-
const { heldCodes } = tracker.store.state
|
|
53
|
-
|
|
54
|
-
this._value = heldCodes
|
|
55
|
-
this._host.requestUpdate()
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
this._unsubscribe = () => subscription.unsubscribe()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** Unsubscribes from the tracker store and stops tracking the held key codes. */
|
|
62
|
-
public hostDisconnected(): void {
|
|
63
|
-
this._unsubscribe?.()
|
|
64
|
-
this._unsubscribe = undefined
|
|
65
|
-
this._value = {}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { getKeyStateTracker } from '@tanstack/hotkeys'
|
|
2
|
-
import type { KeyStateTracker } from '@tanstack/hotkeys'
|
|
3
|
-
import type { ReactiveController, ReactiveControllerHost } from 'lit'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Lit ReactiveController that tracks all currently held keyboard keys.
|
|
7
|
-
*
|
|
8
|
-
* Subscribes to the global KeyStateTracker and triggers host updates
|
|
9
|
-
* whenever keys are pressed or released.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* class KeyDisplay extends LitElement {
|
|
14
|
-
* private heldKeys = new HeldKeysController(this)
|
|
15
|
-
*
|
|
16
|
-
* render() {
|
|
17
|
-
* return html`
|
|
18
|
-
* <div>
|
|
19
|
-
* Currently pressed: ${this.heldKeys.value.join(' + ') || 'None'}
|
|
20
|
-
* </div>
|
|
21
|
-
* `
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export class HeldKeysController implements ReactiveController {
|
|
27
|
-
/** The unsubscribe function to unsubscribe from the tracker store. */
|
|
28
|
-
private _unsubscribe: (() => void) | undefined
|
|
29
|
-
/** The currently held key names. */
|
|
30
|
-
private _value: Array<string> = []
|
|
31
|
-
|
|
32
|
-
/** Array of currently held key names. */
|
|
33
|
-
public get value(): Array<string> {
|
|
34
|
-
return this._value
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param _host - The Lit component that owns this controller.
|
|
39
|
-
*/
|
|
40
|
-
constructor(private _host: ReactiveControllerHost) {
|
|
41
|
-
this._host.addController(this)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Subscribes to the tracker store and updates the internal state when changes occur. */
|
|
45
|
-
public hostConnected(): void {
|
|
46
|
-
const tracker: KeyStateTracker = getKeyStateTracker()
|
|
47
|
-
|
|
48
|
-
const subscription = tracker.store.subscribe(() => {
|
|
49
|
-
const { heldKeys } = tracker.store.state
|
|
50
|
-
|
|
51
|
-
this._value = heldKeys
|
|
52
|
-
this._host.requestUpdate()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
this._unsubscribe = () => subscription.unsubscribe()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Unsubscribes from the tracker store and stops tracking the held keys. */
|
|
59
|
-
public hostDisconnected(): void {
|
|
60
|
-
this._unsubscribe?.()
|
|
61
|
-
this._unsubscribe = undefined
|
|
62
|
-
this._value = []
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/hotkeys'
|
|
2
|
-
import type { ReactiveController, ReactiveControllerHost } from 'lit'
|
|
3
|
-
import type { HeldModifierOptions, RegisterableHotkey } from '@tanstack/hotkeys'
|
|
4
|
-
|
|
5
|
-
/** Modifier hint controller. Getter arguments can read reactive host properties. */
|
|
6
|
-
export class HotkeyHintController implements ReactiveController {
|
|
7
|
-
private unsubscribe?: () => void
|
|
8
|
-
private visible = false
|
|
9
|
-
|
|
10
|
-
/** Attaches to the host; getter arguments can read changing reactive properties. */
|
|
11
|
-
constructor(
|
|
12
|
-
private host: ReactiveControllerHost,
|
|
13
|
-
private hotkey: RegisterableHotkey | (() => RegisterableHotkey),
|
|
14
|
-
private options: HeldModifierOptions | (() => HeldModifierOptions) = {},
|
|
15
|
-
) {
|
|
16
|
-
host.addController(this)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Current visibility; combine with the action’s enabled state when rendering. */
|
|
20
|
-
get value(): boolean {
|
|
21
|
-
return this.visible
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Subscribes on connection and requests renders only when hint visibility changes. */
|
|
25
|
-
hostConnected(): void {
|
|
26
|
-
this.update()
|
|
27
|
-
const subscription = getKeyStateTracker().store.subscribe(() => {
|
|
28
|
-
if (this.update()) this.host.requestUpdate()
|
|
29
|
-
})
|
|
30
|
-
this.unsubscribe = () => subscription.unsubscribe()
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Re-evaluates getter arguments when host properties trigger an update. */
|
|
34
|
-
hostUpdate(): void {
|
|
35
|
-
this.update()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Releases the subscription and clears cached visibility while disconnected. */
|
|
39
|
-
hostDisconnected(): void {
|
|
40
|
-
this.unsubscribe?.()
|
|
41
|
-
this.unsubscribe = undefined
|
|
42
|
-
this.visible = false
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Recomputes visibility and reports whether the host needs another render. */
|
|
46
|
-
private update(): boolean {
|
|
47
|
-
const next = matchesHeldModifiers(
|
|
48
|
-
typeof this.hotkey === 'function' ? this.hotkey() : this.hotkey,
|
|
49
|
-
getKeyStateTracker().store.state.heldKeys,
|
|
50
|
-
typeof this.options === 'function' ? this.options() : this.options,
|
|
51
|
-
)
|
|
52
|
-
const changed = next !== this.visible
|
|
53
|
-
this.visible = next
|
|
54
|
-
return changed
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { HotkeyRecorder } from '@tanstack/hotkeys'
|
|
2
|
-
import type { ReactiveController, ReactiveControllerHost } from 'lit'
|
|
3
|
-
import type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Lit ReactiveController that records keyboard shortcuts.
|
|
7
|
-
*
|
|
8
|
-
* Wraps the framework-agnostic `HotkeyRecorder` class, managing all the
|
|
9
|
-
* complexity of capturing keyboard events, converting them to hotkey strings,
|
|
10
|
-
* and handling edge cases like Escape to cancel or Backspace/Delete to clear.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* class ShortcutSettings extends LitElement {
|
|
15
|
-
* private recorder = new HotkeyRecorderController(this, {
|
|
16
|
-
* onRecord: (hotkey) => {
|
|
17
|
-
* this.shortcut = hotkey
|
|
18
|
-
* this.requestUpdate()
|
|
19
|
-
* },
|
|
20
|
-
* onCancel: () => {
|
|
21
|
-
* console.log('Recording cancelled')
|
|
22
|
-
* },
|
|
23
|
-
* })
|
|
24
|
-
*
|
|
25
|
-
* private shortcut: Hotkey | null = null
|
|
26
|
-
*
|
|
27
|
-
* render() {
|
|
28
|
-
* return html`
|
|
29
|
-
* <button @click=${() => this.recorder.startRecording()}>
|
|
30
|
-
* ${this.recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}
|
|
31
|
-
* </button>
|
|
32
|
-
* ${this.recorder.recordedHotkey
|
|
33
|
-
* ? html`<div>Recording: ${this.recorder.recordedHotkey}</div>`
|
|
34
|
-
* : nothing}
|
|
35
|
-
* `
|
|
36
|
-
* }
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export class HotkeyRecorderController implements ReactiveController {
|
|
41
|
-
/** The recorder instance. */
|
|
42
|
-
private _recorder: HotkeyRecorder
|
|
43
|
-
/** The unsubscribe function to unsubscribe from the recorder store. */
|
|
44
|
-
private _unsubscribe: (() => void) | undefined
|
|
45
|
-
/** Whether recording is currently active. */
|
|
46
|
-
private _isRecording = false
|
|
47
|
-
/** The currently recorded hotkey (for live preview). */
|
|
48
|
-
private _recordedHotkey: Hotkey | null = null
|
|
49
|
-
|
|
50
|
-
/** Whether recording is currently active. */
|
|
51
|
-
public get isRecording(): boolean {
|
|
52
|
-
return this._isRecording
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** The currently recorded hotkey (for live preview). */
|
|
56
|
-
public get recordedHotkey(): Hotkey | null {
|
|
57
|
-
return this._recordedHotkey
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @param _host - The Lit component that owns this controller.
|
|
62
|
-
* @param _options - Configuration options for the recorder.
|
|
63
|
-
*/
|
|
64
|
-
constructor(
|
|
65
|
-
private _host: ReactiveControllerHost,
|
|
66
|
-
private _options: HotkeyRecorderOptions,
|
|
67
|
-
) {
|
|
68
|
-
this._recorder = new HotkeyRecorder(_options)
|
|
69
|
-
this._host.addController(this)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Subscribes to the recorder store and updates the internal state when changes occur. */
|
|
73
|
-
public hostConnected(): void {
|
|
74
|
-
const subscription = this._recorder.store.subscribe(() => {
|
|
75
|
-
const { isRecording, recordedHotkey } = this._recorder.store.state
|
|
76
|
-
|
|
77
|
-
const hasChanged: boolean =
|
|
78
|
-
isRecording !== this._isRecording ||
|
|
79
|
-
recordedHotkey !== this._recordedHotkey
|
|
80
|
-
|
|
81
|
-
if (hasChanged) {
|
|
82
|
-
this._isRecording = isRecording
|
|
83
|
-
this._recordedHotkey = recordedHotkey
|
|
84
|
-
this._host.requestUpdate()
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
this._unsubscribe = () => subscription.unsubscribe()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Unsubscribes from the recorder store and destroys the recorder instance to prevent memory leaks. */
|
|
92
|
-
public hostDisconnected(): void {
|
|
93
|
-
this._unsubscribe?.()
|
|
94
|
-
this._unsubscribe = undefined
|
|
95
|
-
this._recorder.stop()
|
|
96
|
-
this._isRecording = false
|
|
97
|
-
this._recordedHotkey = null
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** Updates the recorder options (e.g. callbacks). */
|
|
101
|
-
public setOptions(options: Partial<HotkeyRecorderOptions>): void {
|
|
102
|
-
this._options = { ...this._options, ...options }
|
|
103
|
-
this._recorder.setOptions(this._options)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Start recording a new hotkey. */
|
|
107
|
-
public startRecording(): void {
|
|
108
|
-
this._recorder.start()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** Stop recording (same as cancel but without calling onCancel). */
|
|
112
|
-
public stopRecording(): void {
|
|
113
|
-
this._recorder.stop()
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** Cancel recording without saving. */
|
|
117
|
-
public cancelRecording(): void {
|
|
118
|
-
this._recorder.cancel()
|
|
119
|
-
}
|
|
120
|
-
}
|