@tanstack/angular-hotkeys 0.3.3

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.
Files changed (56) hide show
  1. package/README.md +122 -0
  2. package/dist/hotkeys-provider.cjs +26 -0
  3. package/dist/hotkeys-provider.cjs.map +1 -0
  4. package/dist/hotkeys-provider.d.cts +21 -0
  5. package/dist/hotkeys-provider.d.ts +21 -0
  6. package/dist/hotkeys-provider.js +23 -0
  7. package/dist/hotkeys-provider.js.map +1 -0
  8. package/dist/index.cjs +26 -0
  9. package/dist/index.d.cts +9 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.js +11 -0
  12. package/dist/injectHeldKeyCodes.cjs +34 -0
  13. package/dist/injectHeldKeyCodes.cjs.map +1 -0
  14. package/dist/injectHeldKeyCodes.d.cts +30 -0
  15. package/dist/injectHeldKeyCodes.d.ts +30 -0
  16. package/dist/injectHeldKeyCodes.js +34 -0
  17. package/dist/injectHeldKeyCodes.js.map +1 -0
  18. package/dist/injectHeldKeys.cjs +29 -0
  19. package/dist/injectHeldKeys.cjs.map +1 -0
  20. package/dist/injectHeldKeys.d.cts +25 -0
  21. package/dist/injectHeldKeys.d.ts +25 -0
  22. package/dist/injectHeldKeys.js +29 -0
  23. package/dist/injectHeldKeys.js.map +1 -0
  24. package/dist/injectHotkey.cjs +93 -0
  25. package/dist/injectHotkey.cjs.map +1 -0
  26. package/dist/injectHotkey.d.cts +73 -0
  27. package/dist/injectHotkey.d.ts +73 -0
  28. package/dist/injectHotkey.js +93 -0
  29. package/dist/injectHotkey.js.map +1 -0
  30. package/dist/injectHotkeyRecorder.cjs +82 -0
  31. package/dist/injectHotkeyRecorder.cjs.map +1 -0
  32. package/dist/injectHotkeyRecorder.d.cts +49 -0
  33. package/dist/injectHotkeyRecorder.d.ts +49 -0
  34. package/dist/injectHotkeyRecorder.js +82 -0
  35. package/dist/injectHotkeyRecorder.js.map +1 -0
  36. package/dist/injectHotkeySequence.cjs +55 -0
  37. package/dist/injectHotkeySequence.cjs.map +1 -0
  38. package/dist/injectHotkeySequence.d.cts +35 -0
  39. package/dist/injectHotkeySequence.d.ts +35 -0
  40. package/dist/injectHotkeySequence.js +55 -0
  41. package/dist/injectHotkeySequence.js.map +1 -0
  42. package/dist/injectKeyHold.cjs +49 -0
  43. package/dist/injectKeyHold.cjs.map +1 -0
  44. package/dist/injectKeyHold.d.cts +41 -0
  45. package/dist/injectKeyHold.d.ts +41 -0
  46. package/dist/injectKeyHold.js +49 -0
  47. package/dist/injectKeyHold.js.map +1 -0
  48. package/package.json +67 -0
  49. package/src/hotkeys-provider.ts +40 -0
  50. package/src/index.ts +13 -0
  51. package/src/injectHeldKeyCodes.ts +31 -0
  52. package/src/injectHeldKeys.ts +26 -0
  53. package/src/injectHotkey.ts +145 -0
  54. package/src/injectHotkeyRecorder.ts +128 -0
  55. package/src/injectHotkeySequence.ts +87 -0
  56. package/src/injectKeyHold.ts +52 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectHotkey.cjs","names":["injectDefaultHotkeysOptions"],"sources":["../src/injectHotkey.ts"],"sourcesContent":["import { effect } from '@angular/core'\nimport {\n detectPlatform,\n formatHotkey,\n getHotkeyManager,\n rawHotkeyToParsedHotkey,\n} from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type {\n Hotkey,\n HotkeyCallback,\n HotkeyOptions,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\nexport interface InjectHotkeyOptions extends Omit<HotkeyOptions, 'target'> {\n /**\n * The DOM element to attach the event listener to.\n * Can be a direct DOM element, an accessor (for reactive targets that become\n * available after mount), or null. Defaults to document.\n * When using scoped targets, pass an accessor: () => ({ target: elementSignal() })\n * so the hotkey waits for the element to be attached before registering.\n */\n target?: HTMLElement | Document | Window | null\n}\n\n/**\n * Angular inject-based API for registering a keyboard hotkey.\n *\n * Uses the singleton HotkeyManager for efficient event handling.\n * The callback receives both the keyboard event and a context object\n * containing the hotkey string and parsed hotkey.\n *\n * Call in an injection context (e.g. constructor or field initializer).\n * Uses effect() to track reactive dependencies and update registration\n * when options or the callback change.\n *\n * @param hotkey - The hotkey string (e.g. 'Mod+S', 'Escape') or getter function\n * @param callback - The function to call when the hotkey is pressed\n * @param options - Options for the hotkey behavior, or getter for reactive options\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class SaveButtonComponent {\n * private readonly saveCount = signal(0)\n *\n * constructor() {\n * injectHotkey('Mod+S', (event, { hotkey }) => {\n * event.preventDefault()\n * this.saveCount.update(c => c + 1)\n * })\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class ModalComponent {\n * isOpen = signal(true)\n *\n * constructor() {\n * injectHotkey('Escape', () => this.close(), () => ({ enabled: this.isOpen() }))\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class EditorComponent {\n * private readonly editorRef = viewChild<ElementRef<HTMLDivElement>>('editorRef')\n *\n * constructor() {\n * injectHotkey('Mod+B', () => this.toggleBold(), () => ({\n * target: this.editorRef()?.nativeElement ?? null,\n * }))\n * }\n * }\n * ```\n */\nexport function injectHotkey(\n hotkey: RegisterableHotkey | (() => RegisterableHotkey),\n callback: HotkeyCallback,\n options: InjectHotkeyOptions | (() => InjectHotkeyOptions) = {},\n): void {\n const defaultOptions = injectDefaultHotkeysOptions()\n const manager = getHotkeyManager()\n\n effect((onCleanup) => {\n // Resolve reactive values\n const resolvedHotkey = typeof hotkey === 'function' ? hotkey() : hotkey\n const resolvedOptions = typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkey,\n ...resolvedOptions,\n } as InjectHotkeyOptions\n\n // Normalize to hotkey string\n const platform = mergedOptions.platform ?? detectPlatform()\n const hotkeyString: Hotkey =\n typeof resolvedHotkey === 'string'\n ? resolvedHotkey\n : (formatHotkey(\n rawHotkeyToParsedHotkey(resolvedHotkey, platform),\n ) as Hotkey)\n\n // Resolve target: when explicitly provided (even as null), use it and skip if null.\n // When not provided, default to document. Matches React's ref handling.\n const resolvedTarget =\n 'target' in mergedOptions\n ? (mergedOptions.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (!resolvedTarget) {\n return\n }\n\n // Extract options without target (target is handled separately)\n const { target: _target, ...optionsWithoutTarget } = mergedOptions\n\n // Register the hotkey\n const registration = manager.register(hotkeyString, callback, {\n ...optionsWithoutTarget,\n target: resolvedTarget,\n })\n\n // Update callback and options on every effect run\n if (registration.isActive) {\n registration.callback = callback\n registration.setOptions(optionsWithoutTarget)\n }\n\n // Cleanup on disposal\n onCleanup(() => {\n if (registration.isActive) {\n registration.unregister()\n }\n })\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFA,SAAgB,aACd,QACA,UACA,UAA6D,EAAE,EACzD;CACN,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,mDAA4B;AAElC,4BAAQ,cAAc;EAEpB,MAAM,iBAAiB,OAAO,WAAW,aAAa,QAAQ,GAAG;EACjE,MAAM,kBAAkB,OAAO,YAAY,aAAa,SAAS,GAAG;EAEpE,MAAM,gBAAgB;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ;EAGD,MAAM,WAAW,cAAc,mDAA4B;EAC3D,MAAM,eACJ,OAAO,mBAAmB,WACtB,oGAE0B,gBAAgB,SAAS,CAClD;EAIP,MAAM,iBACJ,YAAY,gBACP,cAAc,UAAU,OACzB,OAAO,aAAa,cAClB,WACA;AAER,MAAI,CAAC,eACH;EAIF,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB;EAGrD,MAAM,eAAe,QAAQ,SAAS,cAAc,UAAU;GAC5D,GAAG;GACH,QAAQ;GACT,CAAC;AAGF,MAAI,aAAa,UAAU;AACzB,gBAAa,WAAW;AACxB,gBAAa,WAAW,qBAAqB;;AAI/C,kBAAgB;AACd,OAAI,aAAa,SACf,cAAa,YAAY;IAE3B;GACF"}
@@ -0,0 +1,73 @@
1
+ import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
2
+
3
+ //#region src/injectHotkey.d.ts
4
+ interface InjectHotkeyOptions extends Omit<HotkeyOptions, 'target'> {
5
+ /**
6
+ * The DOM element to attach the event listener to.
7
+ * Can be a direct DOM element, an accessor (for reactive targets that become
8
+ * available after mount), or null. Defaults to document.
9
+ * When using scoped targets, pass an accessor: () => ({ target: elementSignal() })
10
+ * so the hotkey waits for the element to be attached before registering.
11
+ */
12
+ target?: HTMLElement | Document | Window | null;
13
+ }
14
+ /**
15
+ * Angular inject-based API for registering a keyboard hotkey.
16
+ *
17
+ * Uses the singleton HotkeyManager for efficient event handling.
18
+ * The callback receives both the keyboard event and a context object
19
+ * containing the hotkey string and parsed hotkey.
20
+ *
21
+ * Call in an injection context (e.g. constructor or field initializer).
22
+ * Uses effect() to track reactive dependencies and update registration
23
+ * when options or the callback change.
24
+ *
25
+ * @param hotkey - The hotkey string (e.g. 'Mod+S', 'Escape') or getter function
26
+ * @param callback - The function to call when the hotkey is pressed
27
+ * @param options - Options for the hotkey behavior, or getter for reactive options
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * @Component({ ... })
32
+ * export class SaveButtonComponent {
33
+ * private readonly saveCount = signal(0)
34
+ *
35
+ * constructor() {
36
+ * injectHotkey('Mod+S', (event, { hotkey }) => {
37
+ * event.preventDefault()
38
+ * this.saveCount.update(c => c + 1)
39
+ * })
40
+ * }
41
+ * }
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * @Component({ ... })
47
+ * export class ModalComponent {
48
+ * isOpen = signal(true)
49
+ *
50
+ * constructor() {
51
+ * injectHotkey('Escape', () => this.close(), () => ({ enabled: this.isOpen() }))
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * @Component({ ... })
59
+ * export class EditorComponent {
60
+ * private readonly editorRef = viewChild<ElementRef<HTMLDivElement>>('editorRef')
61
+ *
62
+ * constructor() {
63
+ * injectHotkey('Mod+B', () => this.toggleBold(), () => ({
64
+ * target: this.editorRef()?.nativeElement ?? null,
65
+ * }))
66
+ * }
67
+ * }
68
+ * ```
69
+ */
70
+ declare function injectHotkey(hotkey: RegisterableHotkey | (() => RegisterableHotkey), callback: HotkeyCallback, options?: InjectHotkeyOptions | (() => InjectHotkeyOptions)): void;
71
+ //#endregion
72
+ export { InjectHotkeyOptions, injectHotkey };
73
+ //# sourceMappingURL=injectHotkey.d.cts.map
@@ -0,0 +1,73 @@
1
+ import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
2
+
3
+ //#region src/injectHotkey.d.ts
4
+ interface InjectHotkeyOptions extends Omit<HotkeyOptions, 'target'> {
5
+ /**
6
+ * The DOM element to attach the event listener to.
7
+ * Can be a direct DOM element, an accessor (for reactive targets that become
8
+ * available after mount), or null. Defaults to document.
9
+ * When using scoped targets, pass an accessor: () => ({ target: elementSignal() })
10
+ * so the hotkey waits for the element to be attached before registering.
11
+ */
12
+ target?: HTMLElement | Document | Window | null;
13
+ }
14
+ /**
15
+ * Angular inject-based API for registering a keyboard hotkey.
16
+ *
17
+ * Uses the singleton HotkeyManager for efficient event handling.
18
+ * The callback receives both the keyboard event and a context object
19
+ * containing the hotkey string and parsed hotkey.
20
+ *
21
+ * Call in an injection context (e.g. constructor or field initializer).
22
+ * Uses effect() to track reactive dependencies and update registration
23
+ * when options or the callback change.
24
+ *
25
+ * @param hotkey - The hotkey string (e.g. 'Mod+S', 'Escape') or getter function
26
+ * @param callback - The function to call when the hotkey is pressed
27
+ * @param options - Options for the hotkey behavior, or getter for reactive options
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * @Component({ ... })
32
+ * export class SaveButtonComponent {
33
+ * private readonly saveCount = signal(0)
34
+ *
35
+ * constructor() {
36
+ * injectHotkey('Mod+S', (event, { hotkey }) => {
37
+ * event.preventDefault()
38
+ * this.saveCount.update(c => c + 1)
39
+ * })
40
+ * }
41
+ * }
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * @Component({ ... })
47
+ * export class ModalComponent {
48
+ * isOpen = signal(true)
49
+ *
50
+ * constructor() {
51
+ * injectHotkey('Escape', () => this.close(), () => ({ enabled: this.isOpen() }))
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * @Component({ ... })
59
+ * export class EditorComponent {
60
+ * private readonly editorRef = viewChild<ElementRef<HTMLDivElement>>('editorRef')
61
+ *
62
+ * constructor() {
63
+ * injectHotkey('Mod+B', () => this.toggleBold(), () => ({
64
+ * target: this.editorRef()?.nativeElement ?? null,
65
+ * }))
66
+ * }
67
+ * }
68
+ * ```
69
+ */
70
+ declare function injectHotkey(hotkey: RegisterableHotkey | (() => RegisterableHotkey), callback: HotkeyCallback, options?: InjectHotkeyOptions | (() => InjectHotkeyOptions)): void;
71
+ //#endregion
72
+ export { InjectHotkeyOptions, injectHotkey };
73
+ //# sourceMappingURL=injectHotkey.d.ts.map
@@ -0,0 +1,93 @@
1
+ import { injectDefaultHotkeysOptions } from "./hotkeys-provider.js";
2
+ import { detectPlatform, formatHotkey, getHotkeyManager, rawHotkeyToParsedHotkey } from "@tanstack/hotkeys";
3
+ import { effect } from "@angular/core";
4
+
5
+ //#region src/injectHotkey.ts
6
+ /**
7
+ * Angular inject-based API for registering a keyboard hotkey.
8
+ *
9
+ * Uses the singleton HotkeyManager for efficient event handling.
10
+ * The callback receives both the keyboard event and a context object
11
+ * containing the hotkey string and parsed hotkey.
12
+ *
13
+ * Call in an injection context (e.g. constructor or field initializer).
14
+ * Uses effect() to track reactive dependencies and update registration
15
+ * when options or the callback change.
16
+ *
17
+ * @param hotkey - The hotkey string (e.g. 'Mod+S', 'Escape') or getter function
18
+ * @param callback - The function to call when the hotkey is pressed
19
+ * @param options - Options for the hotkey behavior, or getter for reactive options
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * @Component({ ... })
24
+ * export class SaveButtonComponent {
25
+ * private readonly saveCount = signal(0)
26
+ *
27
+ * constructor() {
28
+ * injectHotkey('Mod+S', (event, { hotkey }) => {
29
+ * event.preventDefault()
30
+ * this.saveCount.update(c => c + 1)
31
+ * })
32
+ * }
33
+ * }
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * @Component({ ... })
39
+ * export class ModalComponent {
40
+ * isOpen = signal(true)
41
+ *
42
+ * constructor() {
43
+ * injectHotkey('Escape', () => this.close(), () => ({ enabled: this.isOpen() }))
44
+ * }
45
+ * }
46
+ * ```
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * @Component({ ... })
51
+ * export class EditorComponent {
52
+ * private readonly editorRef = viewChild<ElementRef<HTMLDivElement>>('editorRef')
53
+ *
54
+ * constructor() {
55
+ * injectHotkey('Mod+B', () => this.toggleBold(), () => ({
56
+ * target: this.editorRef()?.nativeElement ?? null,
57
+ * }))
58
+ * }
59
+ * }
60
+ * ```
61
+ */
62
+ function injectHotkey(hotkey, callback, options = {}) {
63
+ const defaultOptions = injectDefaultHotkeysOptions();
64
+ const manager = getHotkeyManager();
65
+ effect((onCleanup) => {
66
+ const resolvedHotkey = typeof hotkey === "function" ? hotkey() : hotkey;
67
+ const resolvedOptions = typeof options === "function" ? options() : options;
68
+ const mergedOptions = {
69
+ ...defaultOptions.hotkey,
70
+ ...resolvedOptions
71
+ };
72
+ const platform = mergedOptions.platform ?? detectPlatform();
73
+ const hotkeyString = typeof resolvedHotkey === "string" ? resolvedHotkey : formatHotkey(rawHotkeyToParsedHotkey(resolvedHotkey, platform));
74
+ const resolvedTarget = "target" in mergedOptions ? mergedOptions.target ?? null : typeof document !== "undefined" ? document : null;
75
+ if (!resolvedTarget) return;
76
+ const { target: _target, ...optionsWithoutTarget } = mergedOptions;
77
+ const registration = manager.register(hotkeyString, callback, {
78
+ ...optionsWithoutTarget,
79
+ target: resolvedTarget
80
+ });
81
+ if (registration.isActive) {
82
+ registration.callback = callback;
83
+ registration.setOptions(optionsWithoutTarget);
84
+ }
85
+ onCleanup(() => {
86
+ if (registration.isActive) registration.unregister();
87
+ });
88
+ });
89
+ }
90
+
91
+ //#endregion
92
+ export { injectHotkey };
93
+ //# sourceMappingURL=injectHotkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectHotkey.js","names":[],"sources":["../src/injectHotkey.ts"],"sourcesContent":["import { effect } from '@angular/core'\nimport {\n detectPlatform,\n formatHotkey,\n getHotkeyManager,\n rawHotkeyToParsedHotkey,\n} from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type {\n Hotkey,\n HotkeyCallback,\n HotkeyOptions,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\nexport interface InjectHotkeyOptions extends Omit<HotkeyOptions, 'target'> {\n /**\n * The DOM element to attach the event listener to.\n * Can be a direct DOM element, an accessor (for reactive targets that become\n * available after mount), or null. Defaults to document.\n * When using scoped targets, pass an accessor: () => ({ target: elementSignal() })\n * so the hotkey waits for the element to be attached before registering.\n */\n target?: HTMLElement | Document | Window | null\n}\n\n/**\n * Angular inject-based API for registering a keyboard hotkey.\n *\n * Uses the singleton HotkeyManager for efficient event handling.\n * The callback receives both the keyboard event and a context object\n * containing the hotkey string and parsed hotkey.\n *\n * Call in an injection context (e.g. constructor or field initializer).\n * Uses effect() to track reactive dependencies and update registration\n * when options or the callback change.\n *\n * @param hotkey - The hotkey string (e.g. 'Mod+S', 'Escape') or getter function\n * @param callback - The function to call when the hotkey is pressed\n * @param options - Options for the hotkey behavior, or getter for reactive options\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class SaveButtonComponent {\n * private readonly saveCount = signal(0)\n *\n * constructor() {\n * injectHotkey('Mod+S', (event, { hotkey }) => {\n * event.preventDefault()\n * this.saveCount.update(c => c + 1)\n * })\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class ModalComponent {\n * isOpen = signal(true)\n *\n * constructor() {\n * injectHotkey('Escape', () => this.close(), () => ({ enabled: this.isOpen() }))\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class EditorComponent {\n * private readonly editorRef = viewChild<ElementRef<HTMLDivElement>>('editorRef')\n *\n * constructor() {\n * injectHotkey('Mod+B', () => this.toggleBold(), () => ({\n * target: this.editorRef()?.nativeElement ?? null,\n * }))\n * }\n * }\n * ```\n */\nexport function injectHotkey(\n hotkey: RegisterableHotkey | (() => RegisterableHotkey),\n callback: HotkeyCallback,\n options: InjectHotkeyOptions | (() => InjectHotkeyOptions) = {},\n): void {\n const defaultOptions = injectDefaultHotkeysOptions()\n const manager = getHotkeyManager()\n\n effect((onCleanup) => {\n // Resolve reactive values\n const resolvedHotkey = typeof hotkey === 'function' ? hotkey() : hotkey\n const resolvedOptions = typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkey,\n ...resolvedOptions,\n } as InjectHotkeyOptions\n\n // Normalize to hotkey string\n const platform = mergedOptions.platform ?? detectPlatform()\n const hotkeyString: Hotkey =\n typeof resolvedHotkey === 'string'\n ? resolvedHotkey\n : (formatHotkey(\n rawHotkeyToParsedHotkey(resolvedHotkey, platform),\n ) as Hotkey)\n\n // Resolve target: when explicitly provided (even as null), use it and skip if null.\n // When not provided, default to document. Matches React's ref handling.\n const resolvedTarget =\n 'target' in mergedOptions\n ? (mergedOptions.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (!resolvedTarget) {\n return\n }\n\n // Extract options without target (target is handled separately)\n const { target: _target, ...optionsWithoutTarget } = mergedOptions\n\n // Register the hotkey\n const registration = manager.register(hotkeyString, callback, {\n ...optionsWithoutTarget,\n target: resolvedTarget,\n })\n\n // Update callback and options on every effect run\n if (registration.isActive) {\n registration.callback = callback\n registration.setOptions(optionsWithoutTarget)\n }\n\n // Cleanup on disposal\n onCleanup(() => {\n if (registration.isActive) {\n registration.unregister()\n }\n })\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFA,SAAgB,aACd,QACA,UACA,UAA6D,EAAE,EACzD;CACN,MAAM,iBAAiB,6BAA6B;CACpD,MAAM,UAAU,kBAAkB;AAElC,SAAQ,cAAc;EAEpB,MAAM,iBAAiB,OAAO,WAAW,aAAa,QAAQ,GAAG;EACjE,MAAM,kBAAkB,OAAO,YAAY,aAAa,SAAS,GAAG;EAEpE,MAAM,gBAAgB;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ;EAGD,MAAM,WAAW,cAAc,YAAY,gBAAgB;EAC3D,MAAM,eACJ,OAAO,mBAAmB,WACtB,iBACC,aACC,wBAAwB,gBAAgB,SAAS,CAClD;EAIP,MAAM,iBACJ,YAAY,gBACP,cAAc,UAAU,OACzB,OAAO,aAAa,cAClB,WACA;AAER,MAAI,CAAC,eACH;EAIF,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB;EAGrD,MAAM,eAAe,QAAQ,SAAS,cAAc,UAAU;GAC5D,GAAG;GACH,QAAQ;GACT,CAAC;AAGF,MAAI,aAAa,UAAU;AACzB,gBAAa,WAAW;AACxB,gBAAa,WAAW,qBAAqB;;AAI/C,kBAAgB;AACd,OAAI,aAAa,SACf,cAAa,YAAY;IAE3B;GACF"}
@@ -0,0 +1,82 @@
1
+ const require_hotkeys_provider = require('./hotkeys-provider.cjs');
2
+ let _tanstack_hotkeys = require("@tanstack/hotkeys");
3
+ let _angular_core = require("@angular/core");
4
+
5
+ //#region src/injectHotkeyRecorder.ts
6
+ /**
7
+ * Angular inject-based API for recording keyboard shortcuts.
8
+ *
9
+ * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures
10
+ * keyboard events, converts them to hotkey strings, and handles Escape to
11
+ * cancel or Backspace/Delete to clear.
12
+ *
13
+ * @param options - Configuration options for the recorder (or getter)
14
+ * @returns Object with recording state signals and control functions
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * @Component({ ... })
19
+ * export class ShortcutSettingsComponent {
20
+ * shortcut = signal<Hotkey>('Mod+S')
21
+ * recorder = injectHotkeyRecorder({
22
+ * onRecord: (hotkey) => this.shortcut.set(hotkey),
23
+ * onCancel: () => console.log('Recording cancelled'),
24
+ * })
25
+ *
26
+ * constructor() {
27
+ * injectHotkey(
28
+ * () => this.shortcut(),
29
+ * () => this.handleSave(),
30
+ * () => ({ enabled: !this.recorder.isRecording() }),
31
+ * )
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ function injectHotkeyRecorder(options) {
37
+ const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
38
+ const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
39
+ const recorderSignal = (0, _angular_core.computed)(() => (0, _angular_core.untracked)(() => {
40
+ const resolvedOptions = typeof options === "function" ? options() : options;
41
+ return new _tanstack_hotkeys.HotkeyRecorder({
42
+ ...defaultOptions.hotkeyRecorder,
43
+ ...resolvedOptions
44
+ });
45
+ }));
46
+ const recorderStore = (0, _angular_core.computed)(() => (0, _angular_core.untracked)(() => recorderSignal().store));
47
+ const isRecording = injectLazyStore(recorderStore, (state) => state.isRecording);
48
+ const recordedHotkey = injectLazyStore(recorderStore, (state) => state.recordedHotkey);
49
+ (0, _angular_core.effect)(() => {
50
+ const resolved = typeof options === "function" ? options() : options;
51
+ recorderSignal().setOptions({
52
+ ...defaultOptions.hotkeyRecorder,
53
+ ...resolved
54
+ });
55
+ });
56
+ destroyRef.onDestroy(() => {
57
+ recorderSignal().destroy();
58
+ });
59
+ return {
60
+ isRecording,
61
+ recordedHotkey,
62
+ startRecording: () => recorderSignal().start(),
63
+ stopRecording: () => recorderSignal().stop(),
64
+ cancelRecording: () => recorderSignal().cancel()
65
+ };
66
+ }
67
+ function injectLazyStore(storeSignal, selector) {
68
+ const slice = (0, _angular_core.linkedSignal)(() => selector(storeSignal().get()));
69
+ (0, _angular_core.effect)((onCleanup) => {
70
+ const currentStore = storeSignal();
71
+ slice.set(selector(currentStore.get()));
72
+ const { unsubscribe } = currentStore.subscribe((s) => {
73
+ slice.set(selector(s));
74
+ });
75
+ onCleanup(() => unsubscribe());
76
+ });
77
+ return slice.asReadonly();
78
+ }
79
+
80
+ //#endregion
81
+ exports.injectHotkeyRecorder = injectHotkeyRecorder;
82
+ //# sourceMappingURL=injectHotkeyRecorder.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectHotkeyRecorder.cjs","names":["injectDefaultHotkeysOptions","DestroyRef","HotkeyRecorder"],"sources":["../src/injectHotkeyRecorder.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n linkedSignal,\n untracked,\n} from '@angular/core'\nimport { HotkeyRecorder } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { Atom, ReadonlyAtom } from '@tanstack/angular-store'\nimport type { Signal } from '@angular/core'\nimport type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'\n\nexport interface AngularHotkeyRecorder {\n /** Whether recording is currently active */\n readonly isRecording: () => boolean\n /** The currently recorded hotkey (for live preview) */\n readonly recordedHotkey: () => Hotkey | null\n /** Start recording a new hotkey */\n readonly startRecording: () => void\n /** Stop recording (same as cancel) */\n readonly stopRecording: () => void\n /** Cancel recording without saving */\n readonly cancelRecording: () => void\n}\n\n/**\n * Angular inject-based API for recording keyboard shortcuts.\n *\n * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures\n * keyboard events, converts them to hotkey strings, and handles Escape to\n * cancel or Backspace/Delete to clear.\n *\n * @param options - Configuration options for the recorder (or getter)\n * @returns Object with recording state signals and control functions\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class ShortcutSettingsComponent {\n * shortcut = signal<Hotkey>('Mod+S')\n * recorder = injectHotkeyRecorder({\n * onRecord: (hotkey) => this.shortcut.set(hotkey),\n * onCancel: () => console.log('Recording cancelled'),\n * })\n *\n * constructor() {\n * injectHotkey(\n * () => this.shortcut(),\n * () => this.handleSave(),\n * () => ({ enabled: !this.recorder.isRecording() }),\n * )\n * }\n * }\n * ```\n */\nexport function injectHotkeyRecorder(\n options: HotkeyRecorderOptions | (() => HotkeyRecorderOptions),\n): AngularHotkeyRecorder {\n const defaultOptions = injectDefaultHotkeysOptions()\n const destroyRef = inject(DestroyRef)\n\n // Stable signal to lazy initialize the recorder\n const recorderSignal = computed(() =>\n untracked(() => {\n const resolvedOptions =\n typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkeyRecorder,\n ...resolvedOptions,\n } as HotkeyRecorderOptions\n\n return new HotkeyRecorder(mergedOptions)\n }),\n )\n\n // Subscribe to recorder state\n const recorderStore = computed(() => untracked(() => recorderSignal().store))\n const isRecording = injectLazyStore(\n recorderStore,\n (state) => state.isRecording,\n )\n const recordedHotkey = injectLazyStore(\n recorderStore,\n (state) => state.recordedHotkey,\n )\n\n // Sync options on every effect run (matches React's sync on render)\n effect(() => {\n const resolved = typeof options === 'function' ? options() : options\n recorderSignal().setOptions({\n ...defaultOptions.hotkeyRecorder,\n ...resolved,\n } as HotkeyRecorderOptions)\n })\n\n destroyRef.onDestroy(() => {\n recorderSignal().destroy()\n })\n\n return {\n isRecording,\n recordedHotkey,\n startRecording: () => recorderSignal().start(),\n stopRecording: () => recorderSignal().stop(),\n cancelRecording: () => recorderSignal().cancel(),\n }\n}\n\nfunction injectLazyStore<TState, TSelected = NoInfer<TState>>(\n storeSignal: Signal<Atom<TState> | ReadonlyAtom<TState>>,\n selector: (state: NoInfer<TState>) => TSelected,\n): Signal<TSelected> {\n const slice = linkedSignal(() => selector(storeSignal().get()))\n\n effect((onCleanup) => {\n const currentStore = storeSignal()\n slice.set(selector(currentStore.get()))\n const { unsubscribe } = currentStore.subscribe((s) => {\n slice.set(selector(s))\n })\n onCleanup(() => unsubscribe())\n })\n\n return slice.asReadonly()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,qBACd,SACuB;CACvB,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,uCAAoBC,yBAAW;CAGrC,MAAM,sFACY;EACd,MAAM,kBACJ,OAAO,YAAY,aAAa,SAAS,GAAG;AAO9C,SAAO,IAAIC,iCALW;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ,CAEuC;GACxC,CACH;CAGD,MAAM,qFAA+C,gBAAgB,CAAC,MAAM,CAAC;CAC7E,MAAM,cAAc,gBAClB,gBACC,UAAU,MAAM,YAClB;CACD,MAAM,iBAAiB,gBACrB,gBACC,UAAU,MAAM,eAClB;AAGD,iCAAa;EACX,MAAM,WAAW,OAAO,YAAY,aAAa,SAAS,GAAG;AAC7D,kBAAgB,CAAC,WAAW;GAC1B,GAAG,eAAe;GAClB,GAAG;GACJ,CAA0B;GAC3B;AAEF,YAAW,gBAAgB;AACzB,kBAAgB,CAAC,SAAS;GAC1B;AAEF,QAAO;EACL;EACA;EACA,sBAAsB,gBAAgB,CAAC,OAAO;EAC9C,qBAAqB,gBAAgB,CAAC,MAAM;EAC5C,uBAAuB,gBAAgB,CAAC,QAAQ;EACjD;;AAGH,SAAS,gBACP,aACA,UACmB;CACnB,MAAM,8CAA2B,SAAS,aAAa,CAAC,KAAK,CAAC,CAAC;AAE/D,4BAAQ,cAAc;EACpB,MAAM,eAAe,aAAa;AAClC,QAAM,IAAI,SAAS,aAAa,KAAK,CAAC,CAAC;EACvC,MAAM,EAAE,gBAAgB,aAAa,WAAW,MAAM;AACpD,SAAM,IAAI,SAAS,EAAE,CAAC;IACtB;AACF,kBAAgB,aAAa,CAAC;GAC9B;AAEF,QAAO,MAAM,YAAY"}
@@ -0,0 +1,49 @@
1
+ import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
2
+
3
+ //#region src/injectHotkeyRecorder.d.ts
4
+ interface AngularHotkeyRecorder {
5
+ /** Whether recording is currently active */
6
+ readonly isRecording: () => boolean;
7
+ /** The currently recorded hotkey (for live preview) */
8
+ readonly recordedHotkey: () => Hotkey | null;
9
+ /** Start recording a new hotkey */
10
+ readonly startRecording: () => void;
11
+ /** Stop recording (same as cancel) */
12
+ readonly stopRecording: () => void;
13
+ /** Cancel recording without saving */
14
+ readonly cancelRecording: () => void;
15
+ }
16
+ /**
17
+ * Angular inject-based API for recording keyboard shortcuts.
18
+ *
19
+ * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures
20
+ * keyboard events, converts them to hotkey strings, and handles Escape to
21
+ * cancel or Backspace/Delete to clear.
22
+ *
23
+ * @param options - Configuration options for the recorder (or getter)
24
+ * @returns Object with recording state signals and control functions
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * @Component({ ... })
29
+ * export class ShortcutSettingsComponent {
30
+ * shortcut = signal<Hotkey>('Mod+S')
31
+ * recorder = injectHotkeyRecorder({
32
+ * onRecord: (hotkey) => this.shortcut.set(hotkey),
33
+ * onCancel: () => console.log('Recording cancelled'),
34
+ * })
35
+ *
36
+ * constructor() {
37
+ * injectHotkey(
38
+ * () => this.shortcut(),
39
+ * () => this.handleSave(),
40
+ * () => ({ enabled: !this.recorder.isRecording() }),
41
+ * )
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ declare function injectHotkeyRecorder(options: HotkeyRecorderOptions | (() => HotkeyRecorderOptions)): AngularHotkeyRecorder;
47
+ //#endregion
48
+ export { AngularHotkeyRecorder, injectHotkeyRecorder };
49
+ //# sourceMappingURL=injectHotkeyRecorder.d.cts.map
@@ -0,0 +1,49 @@
1
+ import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
2
+
3
+ //#region src/injectHotkeyRecorder.d.ts
4
+ interface AngularHotkeyRecorder {
5
+ /** Whether recording is currently active */
6
+ readonly isRecording: () => boolean;
7
+ /** The currently recorded hotkey (for live preview) */
8
+ readonly recordedHotkey: () => Hotkey | null;
9
+ /** Start recording a new hotkey */
10
+ readonly startRecording: () => void;
11
+ /** Stop recording (same as cancel) */
12
+ readonly stopRecording: () => void;
13
+ /** Cancel recording without saving */
14
+ readonly cancelRecording: () => void;
15
+ }
16
+ /**
17
+ * Angular inject-based API for recording keyboard shortcuts.
18
+ *
19
+ * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures
20
+ * keyboard events, converts them to hotkey strings, and handles Escape to
21
+ * cancel or Backspace/Delete to clear.
22
+ *
23
+ * @param options - Configuration options for the recorder (or getter)
24
+ * @returns Object with recording state signals and control functions
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * @Component({ ... })
29
+ * export class ShortcutSettingsComponent {
30
+ * shortcut = signal<Hotkey>('Mod+S')
31
+ * recorder = injectHotkeyRecorder({
32
+ * onRecord: (hotkey) => this.shortcut.set(hotkey),
33
+ * onCancel: () => console.log('Recording cancelled'),
34
+ * })
35
+ *
36
+ * constructor() {
37
+ * injectHotkey(
38
+ * () => this.shortcut(),
39
+ * () => this.handleSave(),
40
+ * () => ({ enabled: !this.recorder.isRecording() }),
41
+ * )
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ declare function injectHotkeyRecorder(options: HotkeyRecorderOptions | (() => HotkeyRecorderOptions)): AngularHotkeyRecorder;
47
+ //#endregion
48
+ export { AngularHotkeyRecorder, injectHotkeyRecorder };
49
+ //# sourceMappingURL=injectHotkeyRecorder.d.ts.map
@@ -0,0 +1,82 @@
1
+ import { injectDefaultHotkeysOptions } from "./hotkeys-provider.js";
2
+ import { HotkeyRecorder } from "@tanstack/hotkeys";
3
+ import { DestroyRef, computed, effect, inject, linkedSignal, untracked } from "@angular/core";
4
+
5
+ //#region src/injectHotkeyRecorder.ts
6
+ /**
7
+ * Angular inject-based API for recording keyboard shortcuts.
8
+ *
9
+ * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures
10
+ * keyboard events, converts them to hotkey strings, and handles Escape to
11
+ * cancel or Backspace/Delete to clear.
12
+ *
13
+ * @param options - Configuration options for the recorder (or getter)
14
+ * @returns Object with recording state signals and control functions
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * @Component({ ... })
19
+ * export class ShortcutSettingsComponent {
20
+ * shortcut = signal<Hotkey>('Mod+S')
21
+ * recorder = injectHotkeyRecorder({
22
+ * onRecord: (hotkey) => this.shortcut.set(hotkey),
23
+ * onCancel: () => console.log('Recording cancelled'),
24
+ * })
25
+ *
26
+ * constructor() {
27
+ * injectHotkey(
28
+ * () => this.shortcut(),
29
+ * () => this.handleSave(),
30
+ * () => ({ enabled: !this.recorder.isRecording() }),
31
+ * )
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ function injectHotkeyRecorder(options) {
37
+ const defaultOptions = injectDefaultHotkeysOptions();
38
+ const destroyRef = inject(DestroyRef);
39
+ const recorderSignal = computed(() => untracked(() => {
40
+ const resolvedOptions = typeof options === "function" ? options() : options;
41
+ return new HotkeyRecorder({
42
+ ...defaultOptions.hotkeyRecorder,
43
+ ...resolvedOptions
44
+ });
45
+ }));
46
+ const recorderStore = computed(() => untracked(() => recorderSignal().store));
47
+ const isRecording = injectLazyStore(recorderStore, (state) => state.isRecording);
48
+ const recordedHotkey = injectLazyStore(recorderStore, (state) => state.recordedHotkey);
49
+ effect(() => {
50
+ const resolved = typeof options === "function" ? options() : options;
51
+ recorderSignal().setOptions({
52
+ ...defaultOptions.hotkeyRecorder,
53
+ ...resolved
54
+ });
55
+ });
56
+ destroyRef.onDestroy(() => {
57
+ recorderSignal().destroy();
58
+ });
59
+ return {
60
+ isRecording,
61
+ recordedHotkey,
62
+ startRecording: () => recorderSignal().start(),
63
+ stopRecording: () => recorderSignal().stop(),
64
+ cancelRecording: () => recorderSignal().cancel()
65
+ };
66
+ }
67
+ function injectLazyStore(storeSignal, selector) {
68
+ const slice = linkedSignal(() => selector(storeSignal().get()));
69
+ effect((onCleanup) => {
70
+ const currentStore = storeSignal();
71
+ slice.set(selector(currentStore.get()));
72
+ const { unsubscribe } = currentStore.subscribe((s) => {
73
+ slice.set(selector(s));
74
+ });
75
+ onCleanup(() => unsubscribe());
76
+ });
77
+ return slice.asReadonly();
78
+ }
79
+
80
+ //#endregion
81
+ export { injectHotkeyRecorder };
82
+ //# sourceMappingURL=injectHotkeyRecorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectHotkeyRecorder.js","names":[],"sources":["../src/injectHotkeyRecorder.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n linkedSignal,\n untracked,\n} from '@angular/core'\nimport { HotkeyRecorder } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { Atom, ReadonlyAtom } from '@tanstack/angular-store'\nimport type { Signal } from '@angular/core'\nimport type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'\n\nexport interface AngularHotkeyRecorder {\n /** Whether recording is currently active */\n readonly isRecording: () => boolean\n /** The currently recorded hotkey (for live preview) */\n readonly recordedHotkey: () => Hotkey | null\n /** Start recording a new hotkey */\n readonly startRecording: () => void\n /** Stop recording (same as cancel) */\n readonly stopRecording: () => void\n /** Cancel recording without saving */\n readonly cancelRecording: () => void\n}\n\n/**\n * Angular inject-based API for recording keyboard shortcuts.\n *\n * Thin wrapper around the framework-agnostic HotkeyRecorder class: captures\n * keyboard events, converts them to hotkey strings, and handles Escape to\n * cancel or Backspace/Delete to clear.\n *\n * @param options - Configuration options for the recorder (or getter)\n * @returns Object with recording state signals and control functions\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class ShortcutSettingsComponent {\n * shortcut = signal<Hotkey>('Mod+S')\n * recorder = injectHotkeyRecorder({\n * onRecord: (hotkey) => this.shortcut.set(hotkey),\n * onCancel: () => console.log('Recording cancelled'),\n * })\n *\n * constructor() {\n * injectHotkey(\n * () => this.shortcut(),\n * () => this.handleSave(),\n * () => ({ enabled: !this.recorder.isRecording() }),\n * )\n * }\n * }\n * ```\n */\nexport function injectHotkeyRecorder(\n options: HotkeyRecorderOptions | (() => HotkeyRecorderOptions),\n): AngularHotkeyRecorder {\n const defaultOptions = injectDefaultHotkeysOptions()\n const destroyRef = inject(DestroyRef)\n\n // Stable signal to lazy initialize the recorder\n const recorderSignal = computed(() =>\n untracked(() => {\n const resolvedOptions =\n typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkeyRecorder,\n ...resolvedOptions,\n } as HotkeyRecorderOptions\n\n return new HotkeyRecorder(mergedOptions)\n }),\n )\n\n // Subscribe to recorder state\n const recorderStore = computed(() => untracked(() => recorderSignal().store))\n const isRecording = injectLazyStore(\n recorderStore,\n (state) => state.isRecording,\n )\n const recordedHotkey = injectLazyStore(\n recorderStore,\n (state) => state.recordedHotkey,\n )\n\n // Sync options on every effect run (matches React's sync on render)\n effect(() => {\n const resolved = typeof options === 'function' ? options() : options\n recorderSignal().setOptions({\n ...defaultOptions.hotkeyRecorder,\n ...resolved,\n } as HotkeyRecorderOptions)\n })\n\n destroyRef.onDestroy(() => {\n recorderSignal().destroy()\n })\n\n return {\n isRecording,\n recordedHotkey,\n startRecording: () => recorderSignal().start(),\n stopRecording: () => recorderSignal().stop(),\n cancelRecording: () => recorderSignal().cancel(),\n }\n}\n\nfunction injectLazyStore<TState, TSelected = NoInfer<TState>>(\n storeSignal: Signal<Atom<TState> | ReadonlyAtom<TState>>,\n selector: (state: NoInfer<TState>) => TSelected,\n): Signal<TSelected> {\n const slice = linkedSignal(() => selector(storeSignal().get()))\n\n effect((onCleanup) => {\n const currentStore = storeSignal()\n slice.set(selector(currentStore.get()))\n const { unsubscribe } = currentStore.subscribe((s) => {\n slice.set(selector(s))\n })\n onCleanup(() => unsubscribe())\n })\n\n return slice.asReadonly()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,qBACd,SACuB;CACvB,MAAM,iBAAiB,6BAA6B;CACpD,MAAM,aAAa,OAAO,WAAW;CAGrC,MAAM,iBAAiB,eACrB,gBAAgB;EACd,MAAM,kBACJ,OAAO,YAAY,aAAa,SAAS,GAAG;AAO9C,SAAO,IAAI,eALW;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ,CAEuC;GACxC,CACH;CAGD,MAAM,gBAAgB,eAAe,gBAAgB,gBAAgB,CAAC,MAAM,CAAC;CAC7E,MAAM,cAAc,gBAClB,gBACC,UAAU,MAAM,YAClB;CACD,MAAM,iBAAiB,gBACrB,gBACC,UAAU,MAAM,eAClB;AAGD,cAAa;EACX,MAAM,WAAW,OAAO,YAAY,aAAa,SAAS,GAAG;AAC7D,kBAAgB,CAAC,WAAW;GAC1B,GAAG,eAAe;GAClB,GAAG;GACJ,CAA0B;GAC3B;AAEF,YAAW,gBAAgB;AACzB,kBAAgB,CAAC,SAAS;GAC1B;AAEF,QAAO;EACL;EACA;EACA,sBAAsB,gBAAgB,CAAC,OAAO;EAC9C,qBAAqB,gBAAgB,CAAC,MAAM;EAC5C,uBAAuB,gBAAgB,CAAC,QAAQ;EACjD;;AAGH,SAAS,gBACP,aACA,UACmB;CACnB,MAAM,QAAQ,mBAAmB,SAAS,aAAa,CAAC,KAAK,CAAC,CAAC;AAE/D,SAAQ,cAAc;EACpB,MAAM,eAAe,aAAa;AAClC,QAAM,IAAI,SAAS,aAAa,KAAK,CAAC,CAAC;EACvC,MAAM,EAAE,gBAAgB,aAAa,WAAW,MAAM;AACpD,SAAM,IAAI,SAAS,EAAE,CAAC;IACtB;AACF,kBAAgB,aAAa,CAAC;GAC9B;AAEF,QAAO,MAAM,YAAY"}
@@ -0,0 +1,55 @@
1
+ const require_hotkeys_provider = require('./hotkeys-provider.cjs');
2
+ let _tanstack_hotkeys = require("@tanstack/hotkeys");
3
+ let _angular_core = require("@angular/core");
4
+
5
+ //#region src/injectHotkeySequence.ts
6
+ /**
7
+ * Angular inject-based API for registering a keyboard shortcut sequence (Vim-style).
8
+ *
9
+ * Allows you to register multi-key sequences like 'g g' or 'd d' that trigger
10
+ * when the full sequence is pressed within a timeout.
11
+ *
12
+ * @param sequence - Array of hotkey strings that form the sequence (or getter function)
13
+ * @param callback - Function to call when the sequence is completed
14
+ * @param options - Options for the sequence behavior (or getter function)
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * @Component({ ... })
19
+ * export class VimEditorComponent {
20
+ * lastSequence = signal<string | null>(null)
21
+ *
22
+ * constructor() {
23
+ * injectHotkeySequence(['G', 'G'], () => this.lastSequence.set('gg → Go to top'))
24
+ * injectHotkeySequence(['D', 'D'], () => this.lastSequence.set('dd → Delete line'))
25
+ * injectHotkeySequence(['C', 'I', 'W'], () => this.lastSequence.set('ciw'), { timeout: 500 })
26
+ * }
27
+ * }
28
+ * ```
29
+ */
30
+ function injectHotkeySequence(sequence, callback, options = {}) {
31
+ const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
32
+ (0, _angular_core.effect)((onCleanup) => {
33
+ const resolvedSequence = typeof sequence === "function" ? sequence() : sequence;
34
+ const resolvedOptions = typeof options === "function" ? options() : options;
35
+ const { enabled = true, ...sequenceOptions } = {
36
+ ...defaultOptions.hotkeySequence,
37
+ ...resolvedOptions
38
+ };
39
+ if (!enabled || resolvedSequence.length === 0) return;
40
+ const manager = (0, _tanstack_hotkeys.getSequenceManager)();
41
+ const registerOptions = {
42
+ ...sequenceOptions,
43
+ enabled: true,
44
+ target: sequenceOptions.target ?? (typeof document !== "undefined" ? document : void 0)
45
+ };
46
+ const handle = manager.register(resolvedSequence, callback, registerOptions);
47
+ onCleanup(() => {
48
+ if (handle.isActive) handle.unregister();
49
+ });
50
+ });
51
+ }
52
+
53
+ //#endregion
54
+ exports.injectHotkeySequence = injectHotkeySequence;
55
+ //# sourceMappingURL=injectHotkeySequence.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectHotkeySequence.cjs","names":["injectDefaultHotkeysOptions"],"sources":["../src/injectHotkeySequence.ts"],"sourcesContent":["import { effect } from '@angular/core'\nimport { getSequenceManager } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n} from '@tanstack/hotkeys'\n\nexport interface InjectHotkeySequenceOptions extends Omit<\n SequenceOptions,\n 'enabled'\n> {\n /** Whether the sequence is enabled. Defaults to true. */\n enabled?: boolean\n}\n\n/**\n * Angular inject-based API for registering a keyboard shortcut sequence (Vim-style).\n *\n * Allows you to register multi-key sequences like 'g g' or 'd d' that trigger\n * when the full sequence is pressed within a timeout.\n *\n * @param sequence - Array of hotkey strings that form the sequence (or getter function)\n * @param callback - Function to call when the sequence is completed\n * @param options - Options for the sequence behavior (or getter function)\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class VimEditorComponent {\n * lastSequence = signal<string | null>(null)\n *\n * constructor() {\n * injectHotkeySequence(['G', 'G'], () => this.lastSequence.set('gg → Go to top'))\n * injectHotkeySequence(['D', 'D'], () => this.lastSequence.set('dd → Delete line'))\n * injectHotkeySequence(['C', 'I', 'W'], () => this.lastSequence.set('ciw'), { timeout: 500 })\n * }\n * }\n * ```\n */\nexport function injectHotkeySequence(\n sequence: HotkeySequence | (() => HotkeySequence),\n callback: HotkeyCallback,\n options:\n | InjectHotkeySequenceOptions\n | (() => InjectHotkeySequenceOptions) = {},\n): void {\n const defaultOptions = injectDefaultHotkeysOptions()\n\n effect((onCleanup) => {\n // Resolve reactive values\n const resolvedSequence =\n typeof sequence === 'function' ? sequence() : sequence\n const resolvedOptions = typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkeySequence,\n ...resolvedOptions,\n } as InjectHotkeySequenceOptions\n\n const { enabled = true, ...sequenceOptions } = mergedOptions\n\n if (!enabled || resolvedSequence.length === 0) {\n return\n }\n\n const manager = getSequenceManager()\n\n // Pass through options; default target to document when not provided\n const registerOptions: SequenceOptions = {\n ...sequenceOptions,\n enabled: true,\n target:\n sequenceOptions.target ??\n (typeof document !== 'undefined' ? document : undefined),\n }\n\n const handle = manager.register(resolvedSequence, callback, registerOptions)\n\n onCleanup(() => {\n if (handle.isActive) {\n handle.unregister()\n }\n })\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,qBACd,UACA,UACA,UAE0C,EAAE,EACtC;CACN,MAAM,iBAAiBA,sDAA6B;AAEpD,4BAAQ,cAAc;EAEpB,MAAM,mBACJ,OAAO,aAAa,aAAa,UAAU,GAAG;EAChD,MAAM,kBAAkB,OAAO,YAAY,aAAa,SAAS,GAAG;EAOpE,MAAM,EAAE,UAAU,MAAM,GAAG,oBALL;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ;AAID,MAAI,CAAC,WAAW,iBAAiB,WAAW,EAC1C;EAGF,MAAM,qDAA8B;EAGpC,MAAM,kBAAmC;GACvC,GAAG;GACH,SAAS;GACT,QACE,gBAAgB,WACf,OAAO,aAAa,cAAc,WAAW;GACjD;EAED,MAAM,SAAS,QAAQ,SAAS,kBAAkB,UAAU,gBAAgB;AAE5E,kBAAgB;AACd,OAAI,OAAO,SACT,QAAO,YAAY;IAErB;GACF"}
@@ -0,0 +1,35 @@
1
+ import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
+
3
+ //#region src/injectHotkeySequence.d.ts
4
+ interface InjectHotkeySequenceOptions extends Omit<SequenceOptions, 'enabled'> {
5
+ /** Whether the sequence is enabled. Defaults to true. */
6
+ enabled?: boolean;
7
+ }
8
+ /**
9
+ * Angular inject-based API for registering a keyboard shortcut sequence (Vim-style).
10
+ *
11
+ * Allows you to register multi-key sequences like 'g g' or 'd d' that trigger
12
+ * when the full sequence is pressed within a timeout.
13
+ *
14
+ * @param sequence - Array of hotkey strings that form the sequence (or getter function)
15
+ * @param callback - Function to call when the sequence is completed
16
+ * @param options - Options for the sequence behavior (or getter function)
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * @Component({ ... })
21
+ * export class VimEditorComponent {
22
+ * lastSequence = signal<string | null>(null)
23
+ *
24
+ * constructor() {
25
+ * injectHotkeySequence(['G', 'G'], () => this.lastSequence.set('gg → Go to top'))
26
+ * injectHotkeySequence(['D', 'D'], () => this.lastSequence.set('dd → Delete line'))
27
+ * injectHotkeySequence(['C', 'I', 'W'], () => this.lastSequence.set('ciw'), { timeout: 500 })
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ declare function injectHotkeySequence(sequence: HotkeySequence | (() => HotkeySequence), callback: HotkeyCallback, options?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions)): void;
33
+ //#endregion
34
+ export { InjectHotkeySequenceOptions, injectHotkeySequence };
35
+ //# sourceMappingURL=injectHotkeySequence.d.cts.map