@tanstack/angular-hotkeys 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/hotkeys-provider.d.ts +7 -10
  2. package/dist/hotkeys-provider.js +1 -2
  3. package/dist/injectHeldKeyCodes.d.ts +2 -5
  4. package/dist/injectHeldKeyCodes.js +3 -3
  5. package/dist/injectHeldKeys.d.ts +2 -5
  6. package/dist/injectHeldKeys.js +3 -3
  7. package/dist/injectHotkey.d.ts +3 -6
  8. package/dist/injectHotkey.js +3 -3
  9. package/dist/injectHotkeyHint.d.ts +2 -5
  10. package/dist/injectHotkeyHint.js +1 -2
  11. package/dist/injectHotkeyRecorder.d.ts +3 -6
  12. package/dist/injectHotkeyRecorder.js +4 -4
  13. package/dist/injectHotkeyRegistrations.d.ts +3 -6
  14. package/dist/injectHotkeyRegistrations.js +1 -2
  15. package/dist/injectHotkeySequence.d.ts +3 -6
  16. package/dist/injectHotkeySequence.js +1 -2
  17. package/dist/injectHotkeySequenceRecorder.d.ts +3 -6
  18. package/dist/injectHotkeySequenceRecorder.js +4 -4
  19. package/dist/injectHotkeySequences.d.ts +3 -6
  20. package/dist/injectHotkeySequences.js +1 -2
  21. package/dist/injectHotkeys.d.ts +3 -6
  22. package/dist/injectHotkeys.js +3 -3
  23. package/dist/injectKeyHold.d.ts +2 -5
  24. package/dist/injectKeyHold.js +3 -3
  25. package/package.json +12 -17
  26. package/dist/hotkeys-provider.cjs +0 -26
  27. package/dist/hotkeys-provider.cjs.map +0 -1
  28. package/dist/hotkeys-provider.d.cts +0 -22
  29. package/dist/hotkeys-provider.js.map +0 -1
  30. package/dist/index.cjs +0 -36
  31. package/dist/index.d.cts +0 -14
  32. package/dist/injectHeldKeyCodes.cjs +0 -34
  33. package/dist/injectHeldKeyCodes.cjs.map +0 -1
  34. package/dist/injectHeldKeyCodes.d.cts +0 -30
  35. package/dist/injectHeldKeyCodes.js.map +0 -1
  36. package/dist/injectHeldKeys.cjs +0 -29
  37. package/dist/injectHeldKeys.cjs.map +0 -1
  38. package/dist/injectHeldKeys.d.cts +0 -25
  39. package/dist/injectHeldKeys.js.map +0 -1
  40. package/dist/injectHotkey.cjs +0 -122
  41. package/dist/injectHotkey.cjs.map +0 -1
  42. package/dist/injectHotkey.d.cts +0 -75
  43. package/dist/injectHotkey.js.map +0 -1
  44. package/dist/injectHotkeyHint.cjs +0 -20
  45. package/dist/injectHotkeyHint.cjs.map +0 -1
  46. package/dist/injectHotkeyHint.d.cts +0 -15
  47. package/dist/injectHotkeyHint.js.map +0 -1
  48. package/dist/injectHotkeyRecorder.cjs +0 -82
  49. package/dist/injectHotkeyRecorder.cjs.map +0 -1
  50. package/dist/injectHotkeyRecorder.d.cts +0 -49
  51. package/dist/injectHotkeyRecorder.js.map +0 -1
  52. package/dist/injectHotkeyRegistrations.cjs +0 -28
  53. package/dist/injectHotkeyRegistrations.cjs.map +0 -1
  54. package/dist/injectHotkeyRegistrations.d.cts +0 -29
  55. package/dist/injectHotkeyRegistrations.js.map +0 -1
  56. package/dist/injectHotkeySequence.cjs +0 -93
  57. package/dist/injectHotkeySequence.cjs.map +0 -1
  58. package/dist/injectHotkeySequence.d.cts +0 -48
  59. package/dist/injectHotkeySequence.js.map +0 -1
  60. package/dist/injectHotkeySequenceRecorder.cjs +0 -58
  61. package/dist/injectHotkeySequenceRecorder.cjs.map +0 -1
  62. package/dist/injectHotkeySequenceRecorder.d.cts +0 -19
  63. package/dist/injectHotkeySequenceRecorder.js.map +0 -1
  64. package/dist/injectHotkeySequences.cjs +0 -105
  65. package/dist/injectHotkeySequences.cjs.map +0 -1
  66. package/dist/injectHotkeySequences.d.cts +0 -47
  67. package/dist/injectHotkeySequences.js.map +0 -1
  68. package/dist/injectHotkeys.cjs +0 -120
  69. package/dist/injectHotkeys.cjs.map +0 -1
  70. package/dist/injectHotkeys.d.cts +0 -66
  71. package/dist/injectHotkeys.js.map +0 -1
  72. package/dist/injectKeyHold.cjs +0 -49
  73. package/dist/injectKeyHold.cjs.map +0 -1
  74. package/dist/injectKeyHold.d.cts +0 -41
  75. package/dist/injectKeyHold.js.map +0 -1
  76. package/src/hotkeys-provider.ts +0 -44
  77. package/src/index.ts +0 -18
  78. package/src/injectHeldKeyCodes.ts +0 -31
  79. package/src/injectHeldKeys.ts +0 -26
  80. package/src/injectHotkey.ts +0 -171
  81. package/src/injectHotkeyHint.ts +0 -29
  82. package/src/injectHotkeyRecorder.ts +0 -128
  83. package/src/injectHotkeyRegistrations.ts +0 -48
  84. package/src/injectHotkeySequence.ts +0 -140
  85. package/src/injectHotkeySequenceRecorder.ts +0 -103
  86. package/src/injectHotkeySequences.ts +0 -176
  87. package/src/injectHotkeys.ts +0 -189
  88. package/src/injectKeyHold.ts +0 -57
@@ -1,93 +0,0 @@
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
- * Each step may include modifiers. You can chain the same modifier across
13
- * steps (e.g. `Shift+R` then `Shift+T`). Modifier-only keydown events (Shift,
14
- * Control, Alt, or Meta pressed alone) are ignored while matching—they do not
15
- * advance the sequence or reset progress.
16
- *
17
- * @param sequence - Array of hotkey strings that form the sequence (or getter function)
18
- * @param callback - Function to call when the sequence is completed
19
- * @param options - Options for the sequence behavior (or getter function). `enabled: false` still registers
20
- * the sequence (visible in devtools); only execution is suppressed.
21
- *
22
- * @example
23
- * ```ts
24
- * @Component({ ... })
25
- * export class VimEditorComponent {
26
- * lastSequence = signal<string | null>(null)
27
- *
28
- * constructor() {
29
- * injectHotkeySequence(['G', 'G'], () => this.lastSequence.set('gg → Go to top'))
30
- * injectHotkeySequence(['D', 'D'], () => this.lastSequence.set('dd → Delete line'))
31
- * injectHotkeySequence(['C', 'I', 'W'], () => this.lastSequence.set('ciw'), { timeout: 500 })
32
- * injectHotkeySequence(['Shift+R', 'Shift+T'], () => this.lastSequence.set('⇧R⇧T'))
33
- * }
34
- * }
35
- * ```
36
- */
37
- function injectHotkeySequence(sequence, callback, options = {}) {
38
- const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
39
- const manager = (0, _tanstack_hotkeys.getSequenceManager)();
40
- const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
41
- let handle = null;
42
- let lastSequenceKey = null;
43
- let lastTarget = null;
44
- destroyRef.onDestroy(() => {
45
- if (handle?.isActive) {
46
- handle.unregister();
47
- handle = null;
48
- }
49
- lastSequenceKey = null;
50
- lastTarget = null;
51
- });
52
- (0, _angular_core.effect)(() => {
53
- const resolvedSequence = typeof sequence === "function" ? sequence() : sequence;
54
- const resolvedOptions = typeof options === "function" ? options() : options;
55
- const { enabled = true, ...sequenceOptions } = {
56
- ...defaultOptions.hotkeySequence,
57
- ...resolvedOptions
58
- };
59
- const resolvedTarget = "target" in sequenceOptions ? sequenceOptions.target ?? null : typeof document !== "undefined" ? document : null;
60
- if (resolvedSequence.length === 0 || !resolvedTarget) {
61
- if (handle?.isActive) {
62
- handle.unregister();
63
- handle = null;
64
- }
65
- lastSequenceKey = null;
66
- lastTarget = null;
67
- return;
68
- }
69
- const sequenceKey = (0, _tanstack_hotkeys.formatHotkeySequence)(resolvedSequence);
70
- const registerPayload = {
71
- ...sequenceOptions,
72
- enabled,
73
- target: resolvedTarget
74
- };
75
- const { target: _t, ...optionsWithoutTarget } = registerPayload;
76
- if (handle?.isActive && lastSequenceKey === sequenceKey && lastTarget === resolvedTarget) {
77
- handle.callback = callback;
78
- handle.setOptions(optionsWithoutTarget);
79
- return;
80
- }
81
- if (handle?.isActive) {
82
- handle.unregister();
83
- handle = null;
84
- }
85
- handle = manager.register(resolvedSequence, callback, registerPayload);
86
- lastSequenceKey = sequenceKey;
87
- lastTarget = resolvedTarget;
88
- });
89
- }
90
-
91
- //#endregion
92
- exports.injectHotkeySequence = injectHotkeySequence;
93
- //# sourceMappingURL=injectHotkeySequence.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequence.cjs","names":["injectDefaultHotkeysOptions","DestroyRef"],"sources":["../src/injectHotkeySequence.ts"],"sourcesContent":["import { DestroyRef, effect, inject } from '@angular/core'\nimport { formatHotkeySequence, getSequenceManager } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\ntype SequenceTarget = Document | HTMLElement | Window\n\nexport interface InjectHotkeySequenceOptions extends Omit<\n SequenceOptions,\n 'enabled' | 'target'\n> {\n /** Whether the sequence is enabled. Defaults to true. */\n enabled?: boolean\n /**\n * The DOM element to attach the event listener to.\n * Can be a direct DOM element, an accessor target, or null.\n * Defaults to document when omitted.\n */\n target?: HTMLElement | Document | Window | null\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 * Each step may include modifiers. You can chain the same modifier across\n * steps (e.g. `Shift+R` then `Shift+T`). Modifier-only keydown events (Shift,\n * Control, Alt, or Meta pressed alone) are ignored while matching—they do not\n * advance the sequence or reset progress.\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). `enabled: false` still registers\n * the sequence (visible in devtools); only execution is suppressed.\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 * injectHotkeySequence(['Shift+R', 'Shift+T'], () => this.lastSequence.set('⇧R⇧T'))\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 const manager = getSequenceManager()\n const destroyRef = inject(DestroyRef)\n\n let handle: SequenceRegistrationHandle | null = null\n let lastSequenceKey: string | null = null\n let lastTarget: SequenceTarget | null = null\n\n destroyRef.onDestroy(() => {\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n lastSequenceKey = null\n lastTarget = null\n })\n\n effect(() => {\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 const resolvedTarget =\n 'target' in sequenceOptions\n ? (sequenceOptions.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (resolvedSequence.length === 0 || !resolvedTarget) {\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n lastSequenceKey = null\n lastTarget = null\n return\n }\n\n const sequenceKey = formatHotkeySequence(resolvedSequence)\n\n const registerPayload: SequenceOptions = {\n ...sequenceOptions,\n enabled,\n target: resolvedTarget,\n }\n const { target: _t, ...optionsWithoutTarget } = registerPayload\n\n if (\n handle?.isActive &&\n lastSequenceKey === sequenceKey &&\n lastTarget === resolvedTarget\n ) {\n handle.callback = callback\n handle.setOptions(optionsWithoutTarget)\n return\n }\n\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n\n handle = manager.register(resolvedSequence, callback, registerPayload)\n lastSequenceKey = sequenceKey\n lastTarget = resolvedTarget\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,qBACd,UACA,UACA,UAE0C,EAAE,EACtC;CACN,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,qDAA8B;CACpC,MAAM,uCAAoBC,yBAAW;CAErC,IAAI,SAA4C;CAChD,IAAI,kBAAiC;CACrC,IAAI,aAAoC;AAExC,YAAW,gBAAgB;AACzB,MAAI,QAAQ,UAAU;AACpB,UAAO,YAAY;AACnB,YAAS;;AAEX,oBAAkB;AAClB,eAAa;GACb;AAEF,iCAAa;EAEX,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;EAID,MAAM,iBACJ,YAAY,kBACP,gBAAgB,UAAU,OAC3B,OAAO,aAAa,cAClB,WACA;AAER,MAAI,iBAAiB,WAAW,KAAK,CAAC,gBAAgB;AACpD,OAAI,QAAQ,UAAU;AACpB,WAAO,YAAY;AACnB,aAAS;;AAEX,qBAAkB;AAClB,gBAAa;AACb;;EAGF,MAAM,0DAAmC,iBAAiB;EAE1D,MAAM,kBAAmC;GACvC,GAAG;GACH;GACA,QAAQ;GACT;EACD,MAAM,EAAE,QAAQ,IAAI,GAAG,yBAAyB;AAEhD,MACE,QAAQ,YACR,oBAAoB,eACpB,eAAe,gBACf;AACA,UAAO,WAAW;AAClB,UAAO,WAAW,qBAAqB;AACvC;;AAGF,MAAI,QAAQ,UAAU;AACpB,UAAO,YAAY;AACnB,YAAS;;AAGX,WAAS,QAAQ,SAAS,kBAAkB,UAAU,gBAAgB;AACtE,oBAAkB;AAClB,eAAa;GACb"}
@@ -1,48 +0,0 @@
1
- import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
-
3
- //#region src/injectHotkeySequence.d.ts
4
- interface InjectHotkeySequenceOptions extends Omit<SequenceOptions, 'enabled' | 'target'> {
5
- /** Whether the sequence is enabled. Defaults to true. */
6
- enabled?: boolean;
7
- /**
8
- * The DOM element to attach the event listener to.
9
- * Can be a direct DOM element, an accessor target, or null.
10
- * Defaults to document when omitted.
11
- */
12
- target?: HTMLElement | Document | Window | null;
13
- }
14
- /**
15
- * Angular inject-based API for registering a keyboard shortcut sequence (Vim-style).
16
- *
17
- * Allows you to register multi-key sequences like 'g g' or 'd d' that trigger
18
- * when the full sequence is pressed within a timeout.
19
- *
20
- * Each step may include modifiers. You can chain the same modifier across
21
- * steps (e.g. `Shift+R` then `Shift+T`). Modifier-only keydown events (Shift,
22
- * Control, Alt, or Meta pressed alone) are ignored while matching—they do not
23
- * advance the sequence or reset progress.
24
- *
25
- * @param sequence - Array of hotkey strings that form the sequence (or getter function)
26
- * @param callback - Function to call when the sequence is completed
27
- * @param options - Options for the sequence behavior (or getter function). `enabled: false` still registers
28
- * the sequence (visible in devtools); only execution is suppressed.
29
- *
30
- * @example
31
- * ```ts
32
- * @Component({ ... })
33
- * export class VimEditorComponent {
34
- * lastSequence = signal<string | null>(null)
35
- *
36
- * constructor() {
37
- * injectHotkeySequence(['G', 'G'], () => this.lastSequence.set('gg → Go to top'))
38
- * injectHotkeySequence(['D', 'D'], () => this.lastSequence.set('dd → Delete line'))
39
- * injectHotkeySequence(['C', 'I', 'W'], () => this.lastSequence.set('ciw'), { timeout: 500 })
40
- * injectHotkeySequence(['Shift+R', 'Shift+T'], () => this.lastSequence.set('⇧R⇧T'))
41
- * }
42
- * }
43
- * ```
44
- */
45
- declare function injectHotkeySequence(sequence: HotkeySequence | (() => HotkeySequence), callback: HotkeyCallback, options?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions)): void;
46
- //#endregion
47
- export { InjectHotkeySequenceOptions, injectHotkeySequence };
48
- //# sourceMappingURL=injectHotkeySequence.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequence.js","names":[],"sources":["../src/injectHotkeySequence.ts"],"sourcesContent":["import { DestroyRef, effect, inject } from '@angular/core'\nimport { formatHotkeySequence, getSequenceManager } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\ntype SequenceTarget = Document | HTMLElement | Window\n\nexport interface InjectHotkeySequenceOptions extends Omit<\n SequenceOptions,\n 'enabled' | 'target'\n> {\n /** Whether the sequence is enabled. Defaults to true. */\n enabled?: boolean\n /**\n * The DOM element to attach the event listener to.\n * Can be a direct DOM element, an accessor target, or null.\n * Defaults to document when omitted.\n */\n target?: HTMLElement | Document | Window | null\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 * Each step may include modifiers. You can chain the same modifier across\n * steps (e.g. `Shift+R` then `Shift+T`). Modifier-only keydown events (Shift,\n * Control, Alt, or Meta pressed alone) are ignored while matching—they do not\n * advance the sequence or reset progress.\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). `enabled: false` still registers\n * the sequence (visible in devtools); only execution is suppressed.\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 * injectHotkeySequence(['Shift+R', 'Shift+T'], () => this.lastSequence.set('⇧R⇧T'))\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 const manager = getSequenceManager()\n const destroyRef = inject(DestroyRef)\n\n let handle: SequenceRegistrationHandle | null = null\n let lastSequenceKey: string | null = null\n let lastTarget: SequenceTarget | null = null\n\n destroyRef.onDestroy(() => {\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n lastSequenceKey = null\n lastTarget = null\n })\n\n effect(() => {\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 const resolvedTarget =\n 'target' in sequenceOptions\n ? (sequenceOptions.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (resolvedSequence.length === 0 || !resolvedTarget) {\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n lastSequenceKey = null\n lastTarget = null\n return\n }\n\n const sequenceKey = formatHotkeySequence(resolvedSequence)\n\n const registerPayload: SequenceOptions = {\n ...sequenceOptions,\n enabled,\n target: resolvedTarget,\n }\n const { target: _t, ...optionsWithoutTarget } = registerPayload\n\n if (\n handle?.isActive &&\n lastSequenceKey === sequenceKey &&\n lastTarget === resolvedTarget\n ) {\n handle.callback = callback\n handle.setOptions(optionsWithoutTarget)\n return\n }\n\n if (handle?.isActive) {\n handle.unregister()\n handle = null\n }\n\n handle = manager.register(resolvedSequence, callback, registerPayload)\n lastSequenceKey = sequenceKey\n lastTarget = resolvedTarget\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,qBACd,UACA,UACA,UAE0C,EAAE,EACtC;CACN,MAAM,iBAAiB,6BAA6B;CACpD,MAAM,UAAU,oBAAoB;CACpC,MAAM,aAAa,OAAO,WAAW;CAErC,IAAI,SAA4C;CAChD,IAAI,kBAAiC;CACrC,IAAI,aAAoC;AAExC,YAAW,gBAAgB;AACzB,MAAI,QAAQ,UAAU;AACpB,UAAO,YAAY;AACnB,YAAS;;AAEX,oBAAkB;AAClB,eAAa;GACb;AAEF,cAAa;EAEX,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;EAID,MAAM,iBACJ,YAAY,kBACP,gBAAgB,UAAU,OAC3B,OAAO,aAAa,cAClB,WACA;AAER,MAAI,iBAAiB,WAAW,KAAK,CAAC,gBAAgB;AACpD,OAAI,QAAQ,UAAU;AACpB,WAAO,YAAY;AACnB,aAAS;;AAEX,qBAAkB;AAClB,gBAAa;AACb;;EAGF,MAAM,cAAc,qBAAqB,iBAAiB;EAE1D,MAAM,kBAAmC;GACvC,GAAG;GACH;GACA,QAAQ;GACT;EACD,MAAM,EAAE,QAAQ,IAAI,GAAG,yBAAyB;AAEhD,MACE,QAAQ,YACR,oBAAoB,eACpB,eAAe,gBACf;AACA,UAAO,WAAW;AAClB,UAAO,WAAW,qBAAqB;AACvC;;AAGF,MAAI,QAAQ,UAAU;AACpB,UAAO,YAAY;AACnB,YAAS;;AAGX,WAAS,QAAQ,SAAS,kBAAkB,UAAU,gBAAgB;AACtE,oBAAkB;AAClB,eAAa;GACb"}
@@ -1,58 +0,0 @@
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/injectHotkeySequenceRecorder.ts
6
- /**
7
- * Angular inject-based API for recording multi-chord sequences.
8
- */
9
- function injectHotkeySequenceRecorder(options) {
10
- const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
11
- const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
12
- const recorderSignal = (0, _angular_core.computed)(() => (0, _angular_core.untracked)(() => {
13
- const resolvedOptions = typeof options === "function" ? options() : options;
14
- return new _tanstack_hotkeys.HotkeySequenceRecorder({
15
- ...defaultOptions.hotkeySequenceRecorder,
16
- ...resolvedOptions
17
- });
18
- }));
19
- const recorderStore = (0, _angular_core.computed)(() => (0, _angular_core.untracked)(() => recorderSignal().store));
20
- const isRecording = injectLazyStore(recorderStore, (state) => state.isRecording);
21
- const steps = injectLazyStore(recorderStore, (state) => state.steps);
22
- const recordedSequence = injectLazyStore(recorderStore, (state) => state.recordedSequence);
23
- (0, _angular_core.effect)(() => {
24
- const resolved = typeof options === "function" ? options() : options;
25
- recorderSignal().setOptions({
26
- ...defaultOptions.hotkeySequenceRecorder,
27
- ...resolved
28
- });
29
- });
30
- destroyRef.onDestroy(() => {
31
- recorderSignal().destroy();
32
- });
33
- return {
34
- isRecording,
35
- steps,
36
- recordedSequence,
37
- startRecording: () => recorderSignal().start(),
38
- stopRecording: () => recorderSignal().stop(),
39
- cancelRecording: () => recorderSignal().cancel(),
40
- commitRecording: () => recorderSignal().commit()
41
- };
42
- }
43
- function injectLazyStore(storeSignal, selector) {
44
- const slice = (0, _angular_core.linkedSignal)(() => selector(storeSignal().get()));
45
- (0, _angular_core.effect)((onCleanup) => {
46
- const currentStore = storeSignal();
47
- slice.set(selector(currentStore.get()));
48
- const { unsubscribe } = currentStore.subscribe((s) => {
49
- slice.set(selector(s));
50
- });
51
- onCleanup(() => unsubscribe());
52
- });
53
- return slice.asReadonly();
54
- }
55
-
56
- //#endregion
57
- exports.injectHotkeySequenceRecorder = injectHotkeySequenceRecorder;
58
- //# sourceMappingURL=injectHotkeySequenceRecorder.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequenceRecorder.cjs","names":["injectDefaultHotkeysOptions","DestroyRef","HotkeySequenceRecorder"],"sources":["../src/injectHotkeySequenceRecorder.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n linkedSignal,\n untracked,\n} from '@angular/core'\nimport { HotkeySequenceRecorder } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { Atom, ReadonlyAtom } from '@tanstack/angular-store'\nimport type { Signal } from '@angular/core'\nimport type {\n HotkeySequence,\n HotkeySequenceRecorderOptions,\n} from '@tanstack/hotkeys'\n\nexport interface AngularHotkeySequenceRecorder {\n readonly isRecording: () => boolean\n readonly steps: () => HotkeySequence\n readonly recordedSequence: () => HotkeySequence | null\n readonly startRecording: () => void\n readonly stopRecording: () => void\n readonly cancelRecording: () => void\n readonly commitRecording: () => void\n}\n\n/**\n * Angular inject-based API for recording multi-chord sequences.\n */\nexport function injectHotkeySequenceRecorder(\n options:\n | HotkeySequenceRecorderOptions\n | (() => HotkeySequenceRecorderOptions),\n): AngularHotkeySequenceRecorder {\n const defaultOptions = injectDefaultHotkeysOptions()\n const destroyRef = inject(DestroyRef)\n\n const recorderSignal = computed(() =>\n untracked(() => {\n const resolvedOptions =\n typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkeySequenceRecorder,\n ...resolvedOptions,\n } as HotkeySequenceRecorderOptions\n\n return new HotkeySequenceRecorder(mergedOptions)\n }),\n )\n\n const recorderStore = computed(() => untracked(() => recorderSignal().store))\n const isRecording = injectLazyStore(\n recorderStore,\n (state) => state.isRecording,\n )\n const steps = injectLazyStore(recorderStore, (state) => state.steps)\n const recordedSequence = injectLazyStore(\n recorderStore,\n (state) => state.recordedSequence,\n )\n\n effect(() => {\n const resolved = typeof options === 'function' ? options() : options\n recorderSignal().setOptions({\n ...defaultOptions.hotkeySequenceRecorder,\n ...resolved,\n } as HotkeySequenceRecorderOptions)\n })\n\n destroyRef.onDestroy(() => {\n recorderSignal().destroy()\n })\n\n return {\n isRecording,\n steps,\n recordedSequence,\n startRecording: () => recorderSignal().start(),\n stopRecording: () => recorderSignal().stop(),\n cancelRecording: () => recorderSignal().cancel(),\n commitRecording: () => recorderSignal().commit(),\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":";;;;;;;;AA8BA,SAAgB,6BACd,SAG+B;CAC/B,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,uCAAoBC,yBAAW;CAErC,MAAM,sFACY;EACd,MAAM,kBACJ,OAAO,YAAY,aAAa,SAAS,GAAG;AAO9C,SAAO,IAAIC,yCALW;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ,CAE+C;GAChD,CACH;CAED,MAAM,qFAA+C,gBAAgB,CAAC,MAAM,CAAC;CAC7E,MAAM,cAAc,gBAClB,gBACC,UAAU,MAAM,YAClB;CACD,MAAM,QAAQ,gBAAgB,gBAAgB,UAAU,MAAM,MAAM;CACpE,MAAM,mBAAmB,gBACvB,gBACC,UAAU,MAAM,iBAClB;AAED,iCAAa;EACX,MAAM,WAAW,OAAO,YAAY,aAAa,SAAS,GAAG;AAC7D,kBAAgB,CAAC,WAAW;GAC1B,GAAG,eAAe;GAClB,GAAG;GACJ,CAAkC;GACnC;AAEF,YAAW,gBAAgB;AACzB,kBAAgB,CAAC,SAAS;GAC1B;AAEF,QAAO;EACL;EACA;EACA;EACA,sBAAsB,gBAAgB,CAAC,OAAO;EAC9C,qBAAqB,gBAAgB,CAAC,MAAM;EAC5C,uBAAuB,gBAAgB,CAAC,QAAQ;EAChD,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"}
@@ -1,19 +0,0 @@
1
- import { HotkeySequence, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
2
-
3
- //#region src/injectHotkeySequenceRecorder.d.ts
4
- interface AngularHotkeySequenceRecorder {
5
- readonly isRecording: () => boolean;
6
- readonly steps: () => HotkeySequence;
7
- readonly recordedSequence: () => HotkeySequence | null;
8
- readonly startRecording: () => void;
9
- readonly stopRecording: () => void;
10
- readonly cancelRecording: () => void;
11
- readonly commitRecording: () => void;
12
- }
13
- /**
14
- * Angular inject-based API for recording multi-chord sequences.
15
- */
16
- declare function injectHotkeySequenceRecorder(options: HotkeySequenceRecorderOptions | (() => HotkeySequenceRecorderOptions)): AngularHotkeySequenceRecorder;
17
- //#endregion
18
- export { AngularHotkeySequenceRecorder, injectHotkeySequenceRecorder };
19
- //# sourceMappingURL=injectHotkeySequenceRecorder.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequenceRecorder.js","names":[],"sources":["../src/injectHotkeySequenceRecorder.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n linkedSignal,\n untracked,\n} from '@angular/core'\nimport { HotkeySequenceRecorder } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { Atom, ReadonlyAtom } from '@tanstack/angular-store'\nimport type { Signal } from '@angular/core'\nimport type {\n HotkeySequence,\n HotkeySequenceRecorderOptions,\n} from '@tanstack/hotkeys'\n\nexport interface AngularHotkeySequenceRecorder {\n readonly isRecording: () => boolean\n readonly steps: () => HotkeySequence\n readonly recordedSequence: () => HotkeySequence | null\n readonly startRecording: () => void\n readonly stopRecording: () => void\n readonly cancelRecording: () => void\n readonly commitRecording: () => void\n}\n\n/**\n * Angular inject-based API for recording multi-chord sequences.\n */\nexport function injectHotkeySequenceRecorder(\n options:\n | HotkeySequenceRecorderOptions\n | (() => HotkeySequenceRecorderOptions),\n): AngularHotkeySequenceRecorder {\n const defaultOptions = injectDefaultHotkeysOptions()\n const destroyRef = inject(DestroyRef)\n\n const recorderSignal = computed(() =>\n untracked(() => {\n const resolvedOptions =\n typeof options === 'function' ? options() : options\n\n const mergedOptions = {\n ...defaultOptions.hotkeySequenceRecorder,\n ...resolvedOptions,\n } as HotkeySequenceRecorderOptions\n\n return new HotkeySequenceRecorder(mergedOptions)\n }),\n )\n\n const recorderStore = computed(() => untracked(() => recorderSignal().store))\n const isRecording = injectLazyStore(\n recorderStore,\n (state) => state.isRecording,\n )\n const steps = injectLazyStore(recorderStore, (state) => state.steps)\n const recordedSequence = injectLazyStore(\n recorderStore,\n (state) => state.recordedSequence,\n )\n\n effect(() => {\n const resolved = typeof options === 'function' ? options() : options\n recorderSignal().setOptions({\n ...defaultOptions.hotkeySequenceRecorder,\n ...resolved,\n } as HotkeySequenceRecorderOptions)\n })\n\n destroyRef.onDestroy(() => {\n recorderSignal().destroy()\n })\n\n return {\n isRecording,\n steps,\n recordedSequence,\n startRecording: () => recorderSignal().start(),\n stopRecording: () => recorderSignal().stop(),\n cancelRecording: () => recorderSignal().cancel(),\n commitRecording: () => recorderSignal().commit(),\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":";;;;;;;;AA8BA,SAAgB,6BACd,SAG+B;CAC/B,MAAM,iBAAiB,6BAA6B;CACpD,MAAM,aAAa,OAAO,WAAW;CAErC,MAAM,iBAAiB,eACrB,gBAAgB;EACd,MAAM,kBACJ,OAAO,YAAY,aAAa,SAAS,GAAG;AAO9C,SAAO,IAAI,uBALW;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ,CAE+C;GAChD,CACH;CAED,MAAM,gBAAgB,eAAe,gBAAgB,gBAAgB,CAAC,MAAM,CAAC;CAC7E,MAAM,cAAc,gBAClB,gBACC,UAAU,MAAM,YAClB;CACD,MAAM,QAAQ,gBAAgB,gBAAgB,UAAU,MAAM,MAAM;CACpE,MAAM,mBAAmB,gBACvB,gBACC,UAAU,MAAM,iBAClB;AAED,cAAa;EACX,MAAM,WAAW,OAAO,YAAY,aAAa,SAAS,GAAG;AAC7D,kBAAgB,CAAC,WAAW;GAC1B,GAAG,eAAe;GAClB,GAAG;GACJ,CAAkC;GACnC;AAEF,YAAW,gBAAgB;AACzB,kBAAgB,CAAC,SAAS;GAC1B;AAEF,QAAO;EACL;EACA;EACA;EACA,sBAAsB,gBAAgB,CAAC,OAAO;EAC9C,qBAAqB,gBAAgB,CAAC,MAAM;EAC5C,uBAAuB,gBAAgB,CAAC,QAAQ;EAChD,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"}
@@ -1,105 +0,0 @@
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/injectHotkeySequences.ts
6
- /**
7
- * Angular inject-based API for registering multiple keyboard shortcut sequences at once (Vim-style).
8
- *
9
- * Uses the singleton SequenceManager. Call in an injection context (e.g. constructor).
10
- * Uses `effect()` to track reactive dependencies when definitions or options are getters.
11
- *
12
- * Options are merged in this order:
13
- * provideHotkeys defaults < commonOptions < per-definition options
14
- *
15
- * Definitions with an empty `sequence` are skipped. Disabled sequences (`enabled: false`)
16
- * remain registered so they stay visible in devtools; the core manager suppresses execution.
17
- *
18
- * @param sequences - Array of sequence definitions, or getter returning them
19
- * @param commonOptions - Shared options for all sequences, or getter
20
- *
21
- * @example
22
- * ```ts
23
- * @Component({ ... })
24
- * export class VimComponent {
25
- * constructor() {
26
- * injectHotkeySequences([
27
- * { sequence: ['G', 'G'], callback: () => this.goTop() },
28
- * { sequence: ['D', 'D'], callback: () => this.deleteLine() },
29
- * ])
30
- * }
31
- * }
32
- * ```
33
- */
34
- function injectHotkeySequences(sequences, commonOptions = {}) {
35
- const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
36
- const manager = (0, _tanstack_hotkeys.getSequenceManager)();
37
- const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
38
- const registrations = /* @__PURE__ */ new Map();
39
- destroyRef.onDestroy(() => {
40
- for (const { handle } of registrations.values()) if (handle.isActive) handle.unregister();
41
- registrations.clear();
42
- });
43
- (0, _angular_core.effect)(() => {
44
- const resolvedSequences = typeof sequences === "function" ? sequences() : sequences;
45
- const resolvedCommonOptions = typeof commonOptions === "function" ? commonOptions() : commonOptions;
46
- const nextKeys = /* @__PURE__ */ new Set();
47
- const prepared = [];
48
- for (let i = 0; i < resolvedSequences.length; i++) {
49
- const def = resolvedSequences[i];
50
- const resolvedSequence = typeof def.sequence === "function" ? def.sequence() : def.sequence;
51
- const resolvedDefOptions = typeof def.options === "function" ? def.options() : def.options ?? {};
52
- const { enabled = true, ...sequenceOpts } = {
53
- ...defaultOptions.hotkeySequence,
54
- ...resolvedCommonOptions,
55
- ...resolvedDefOptions
56
- };
57
- if (resolvedSequence.length === 0) continue;
58
- const resolvedTarget = "target" in sequenceOpts ? sequenceOpts.target ?? null : typeof document !== "undefined" ? document : null;
59
- if (!resolvedTarget) continue;
60
- const registrationKey = `${i}:${(0, _tanstack_hotkeys.formatHotkeySequence)(resolvedSequence)}`;
61
- nextKeys.add(registrationKey);
62
- prepared.push({
63
- registrationKey,
64
- def,
65
- resolvedSequence,
66
- enabled,
67
- sequenceOpts,
68
- resolvedTarget
69
- });
70
- }
71
- for (const [key, record] of [...registrations.entries()]) if (!nextKeys.has(key)) {
72
- if (record.handle.isActive) record.handle.unregister();
73
- registrations.delete(key);
74
- }
75
- for (const p of prepared) {
76
- const existing = registrations.get(p.registrationKey);
77
- if (existing?.handle.isActive && existing.target === p.resolvedTarget) {
78
- existing.handle.callback = p.def.callback;
79
- const { target: _target, ...optionsWithoutTarget } = p.sequenceOpts;
80
- existing.handle.setOptions({
81
- ...optionsWithoutTarget,
82
- enabled: p.enabled
83
- });
84
- continue;
85
- }
86
- if (existing) {
87
- if (existing.handle.isActive) existing.handle.unregister();
88
- registrations.delete(p.registrationKey);
89
- }
90
- const handle = manager.register(p.resolvedSequence, p.def.callback, {
91
- ...p.sequenceOpts,
92
- enabled: p.enabled,
93
- target: p.resolvedTarget
94
- });
95
- registrations.set(p.registrationKey, {
96
- handle,
97
- target: p.resolvedTarget
98
- });
99
- }
100
- });
101
- }
102
-
103
- //#endregion
104
- exports.injectHotkeySequences = injectHotkeySequences;
105
- //# sourceMappingURL=injectHotkeySequences.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequences.cjs","names":["injectDefaultHotkeysOptions","DestroyRef"],"sources":["../src/injectHotkeySequences.ts"],"sourcesContent":["import { DestroyRef, effect, inject } from '@angular/core'\nimport { formatHotkeySequence, getSequenceManager } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { InjectHotkeySequenceOptions } from './injectHotkeySequence'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\n/**\n * A single sequence definition for use with `injectHotkeySequences`.\n */\nexport interface InjectHotkeySequenceDefinition {\n /** Array of hotkey strings that form the sequence */\n sequence: HotkeySequence | (() => HotkeySequence)\n /** The function to call when the sequence is completed */\n callback: HotkeyCallback\n /** Per-sequence options (merged on top of commonOptions) */\n options?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions)\n}\n\n/**\n * Angular inject-based API for registering multiple keyboard shortcut sequences at once (Vim-style).\n *\n * Uses the singleton SequenceManager. Call in an injection context (e.g. constructor).\n * Uses `effect()` to track reactive dependencies when definitions or options are getters.\n *\n * Options are merged in this order:\n * provideHotkeys defaults < commonOptions < per-definition options\n *\n * Definitions with an empty `sequence` are skipped. Disabled sequences (`enabled: false`)\n * remain registered so they stay visible in devtools; the core manager suppresses execution.\n *\n * @param sequences - Array of sequence definitions, or getter returning them\n * @param commonOptions - Shared options for all sequences, or getter\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class VimComponent {\n * constructor() {\n * injectHotkeySequences([\n * { sequence: ['G', 'G'], callback: () => this.goTop() },\n * { sequence: ['D', 'D'], callback: () => this.deleteLine() },\n * ])\n * }\n * }\n * ```\n */\nexport function injectHotkeySequences(\n sequences:\n | Array<InjectHotkeySequenceDefinition>\n | (() => Array<InjectHotkeySequenceDefinition>),\n commonOptions:\n | InjectHotkeySequenceOptions\n | (() => InjectHotkeySequenceOptions) = {},\n): void {\n type RegistrationRecord = {\n handle: SequenceRegistrationHandle\n target: Document | HTMLElement | Window\n }\n\n const defaultOptions = injectDefaultHotkeysOptions()\n const manager = getSequenceManager()\n const destroyRef = inject(DestroyRef)\n\n const registrations = new Map<string, RegistrationRecord>()\n\n destroyRef.onDestroy(() => {\n for (const { handle } of registrations.values()) {\n if (handle.isActive) {\n handle.unregister()\n }\n }\n registrations.clear()\n })\n\n effect(() => {\n const resolvedSequences =\n typeof sequences === 'function' ? sequences() : sequences\n const resolvedCommonOptions =\n typeof commonOptions === 'function' ? commonOptions() : commonOptions\n\n const nextKeys = new Set<string>()\n const prepared: Array<{\n registrationKey: string\n def: InjectHotkeySequenceDefinition\n resolvedSequence: HotkeySequence\n enabled: boolean\n sequenceOpts: Omit<InjectHotkeySequenceOptions, 'enabled'>\n resolvedTarget: Document | HTMLElement | Window\n }> = []\n\n for (let i = 0; i < resolvedSequences.length; i++) {\n const def = resolvedSequences[i]!\n const resolvedSequence =\n typeof def.sequence === 'function' ? def.sequence() : def.sequence\n const resolvedDefOptions =\n typeof def.options === 'function' ? def.options() : (def.options ?? {})\n\n const mergedOptions = {\n ...defaultOptions.hotkeySequence,\n ...resolvedCommonOptions,\n ...resolvedDefOptions,\n } as InjectHotkeySequenceOptions\n\n const { enabled = true, ...sequenceOpts } = mergedOptions\n\n if (resolvedSequence.length === 0) {\n continue\n }\n\n const resolvedTarget =\n 'target' in sequenceOpts\n ? (sequenceOpts.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (!resolvedTarget) {\n continue\n }\n\n const registrationKey = `${i}:${formatHotkeySequence(resolvedSequence)}`\n nextKeys.add(registrationKey)\n prepared.push({\n registrationKey,\n def,\n resolvedSequence,\n enabled,\n sequenceOpts,\n resolvedTarget,\n })\n }\n\n for (const [key, record] of [...registrations.entries()]) {\n if (!nextKeys.has(key)) {\n if (record.handle.isActive) {\n record.handle.unregister()\n }\n registrations.delete(key)\n }\n }\n\n for (const p of prepared) {\n const existing = registrations.get(p.registrationKey)\n if (existing?.handle.isActive && existing.target === p.resolvedTarget) {\n existing.handle.callback = p.def.callback\n const { target: _target, ...optionsWithoutTarget } = p.sequenceOpts\n existing.handle.setOptions({\n ...optionsWithoutTarget,\n enabled: p.enabled,\n })\n continue\n }\n\n if (existing) {\n if (existing.handle.isActive) {\n existing.handle.unregister()\n }\n registrations.delete(p.registrationKey)\n }\n\n const handle = manager.register(p.resolvedSequence, p.def.callback, {\n ...p.sequenceOpts,\n enabled: p.enabled,\n target: p.resolvedTarget,\n })\n registrations.set(p.registrationKey, {\n handle,\n target: p.resolvedTarget,\n })\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,sBACd,WAGA,gBAE0C,EAAE,EACtC;CAMN,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,qDAA8B;CACpC,MAAM,uCAAoBC,yBAAW;CAErC,MAAM,gCAAgB,IAAI,KAAiC;AAE3D,YAAW,gBAAgB;AACzB,OAAK,MAAM,EAAE,YAAY,cAAc,QAAQ,CAC7C,KAAI,OAAO,SACT,QAAO,YAAY;AAGvB,gBAAc,OAAO;GACrB;AAEF,iCAAa;EACX,MAAM,oBACJ,OAAO,cAAc,aAAa,WAAW,GAAG;EAClD,MAAM,wBACJ,OAAO,kBAAkB,aAAa,eAAe,GAAG;EAE1D,MAAM,2BAAW,IAAI,KAAa;EAClC,MAAM,WAOD,EAAE;AAEP,OAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,QAAQ,KAAK;GACjD,MAAM,MAAM,kBAAkB;GAC9B,MAAM,mBACJ,OAAO,IAAI,aAAa,aAAa,IAAI,UAAU,GAAG,IAAI;GAC5D,MAAM,qBACJ,OAAO,IAAI,YAAY,aAAa,IAAI,SAAS,GAAI,IAAI,WAAW,EAAE;GAQxE,MAAM,EAAE,UAAU,MAAM,GAAG,iBANL;IACpB,GAAG,eAAe;IAClB,GAAG;IACH,GAAG;IACJ;AAID,OAAI,iBAAiB,WAAW,EAC9B;GAGF,MAAM,iBACJ,YAAY,eACP,aAAa,UAAU,OACxB,OAAO,aAAa,cAClB,WACA;AAER,OAAI,CAAC,eACH;GAGF,MAAM,kBAAkB,GAAG,EAAE,+CAAwB,iBAAiB;AACtE,YAAS,IAAI,gBAAgB;AAC7B,YAAS,KAAK;IACZ;IACA;IACA;IACA;IACA;IACA;IACD,CAAC;;AAGJ,OAAK,MAAM,CAAC,KAAK,WAAW,CAAC,GAAG,cAAc,SAAS,CAAC,CACtD,KAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AACtB,OAAI,OAAO,OAAO,SAChB,QAAO,OAAO,YAAY;AAE5B,iBAAc,OAAO,IAAI;;AAI7B,OAAK,MAAM,KAAK,UAAU;GACxB,MAAM,WAAW,cAAc,IAAI,EAAE,gBAAgB;AACrD,OAAI,UAAU,OAAO,YAAY,SAAS,WAAW,EAAE,gBAAgB;AACrE,aAAS,OAAO,WAAW,EAAE,IAAI;IACjC,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB,EAAE;AACvD,aAAS,OAAO,WAAW;KACzB,GAAG;KACH,SAAS,EAAE;KACZ,CAAC;AACF;;AAGF,OAAI,UAAU;AACZ,QAAI,SAAS,OAAO,SAClB,UAAS,OAAO,YAAY;AAE9B,kBAAc,OAAO,EAAE,gBAAgB;;GAGzC,MAAM,SAAS,QAAQ,SAAS,EAAE,kBAAkB,EAAE,IAAI,UAAU;IAClE,GAAG,EAAE;IACL,SAAS,EAAE;IACX,QAAQ,EAAE;IACX,CAAC;AACF,iBAAc,IAAI,EAAE,iBAAiB;IACnC;IACA,QAAQ,EAAE;IACX,CAAC;;GAEJ"}
@@ -1,47 +0,0 @@
1
- import { InjectHotkeySequenceOptions } from "./injectHotkeySequence.cjs";
2
- import { HotkeyCallback, HotkeySequence } from "@tanstack/hotkeys";
3
-
4
- //#region src/injectHotkeySequences.d.ts
5
- /**
6
- * A single sequence definition for use with `injectHotkeySequences`.
7
- */
8
- interface InjectHotkeySequenceDefinition {
9
- /** Array of hotkey strings that form the sequence */
10
- sequence: HotkeySequence | (() => HotkeySequence);
11
- /** The function to call when the sequence is completed */
12
- callback: HotkeyCallback;
13
- /** Per-sequence options (merged on top of commonOptions) */
14
- options?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions);
15
- }
16
- /**
17
- * Angular inject-based API for registering multiple keyboard shortcut sequences at once (Vim-style).
18
- *
19
- * Uses the singleton SequenceManager. Call in an injection context (e.g. constructor).
20
- * Uses `effect()` to track reactive dependencies when definitions or options are getters.
21
- *
22
- * Options are merged in this order:
23
- * provideHotkeys defaults < commonOptions < per-definition options
24
- *
25
- * Definitions with an empty `sequence` are skipped. Disabled sequences (`enabled: false`)
26
- * remain registered so they stay visible in devtools; the core manager suppresses execution.
27
- *
28
- * @param sequences - Array of sequence definitions, or getter returning them
29
- * @param commonOptions - Shared options for all sequences, or getter
30
- *
31
- * @example
32
- * ```ts
33
- * @Component({ ... })
34
- * export class VimComponent {
35
- * constructor() {
36
- * injectHotkeySequences([
37
- * { sequence: ['G', 'G'], callback: () => this.goTop() },
38
- * { sequence: ['D', 'D'], callback: () => this.deleteLine() },
39
- * ])
40
- * }
41
- * }
42
- * ```
43
- */
44
- declare function injectHotkeySequences(sequences: Array<InjectHotkeySequenceDefinition> | (() => Array<InjectHotkeySequenceDefinition>), commonOptions?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions)): void;
45
- //#endregion
46
- export { InjectHotkeySequenceDefinition, injectHotkeySequences };
47
- //# sourceMappingURL=injectHotkeySequences.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeySequences.js","names":[],"sources":["../src/injectHotkeySequences.ts"],"sourcesContent":["import { DestroyRef, effect, inject } from '@angular/core'\nimport { formatHotkeySequence, getSequenceManager } from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { InjectHotkeySequenceOptions } from './injectHotkeySequence'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\n/**\n * A single sequence definition for use with `injectHotkeySequences`.\n */\nexport interface InjectHotkeySequenceDefinition {\n /** Array of hotkey strings that form the sequence */\n sequence: HotkeySequence | (() => HotkeySequence)\n /** The function to call when the sequence is completed */\n callback: HotkeyCallback\n /** Per-sequence options (merged on top of commonOptions) */\n options?: InjectHotkeySequenceOptions | (() => InjectHotkeySequenceOptions)\n}\n\n/**\n * Angular inject-based API for registering multiple keyboard shortcut sequences at once (Vim-style).\n *\n * Uses the singleton SequenceManager. Call in an injection context (e.g. constructor).\n * Uses `effect()` to track reactive dependencies when definitions or options are getters.\n *\n * Options are merged in this order:\n * provideHotkeys defaults < commonOptions < per-definition options\n *\n * Definitions with an empty `sequence` are skipped. Disabled sequences (`enabled: false`)\n * remain registered so they stay visible in devtools; the core manager suppresses execution.\n *\n * @param sequences - Array of sequence definitions, or getter returning them\n * @param commonOptions - Shared options for all sequences, or getter\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class VimComponent {\n * constructor() {\n * injectHotkeySequences([\n * { sequence: ['G', 'G'], callback: () => this.goTop() },\n * { sequence: ['D', 'D'], callback: () => this.deleteLine() },\n * ])\n * }\n * }\n * ```\n */\nexport function injectHotkeySequences(\n sequences:\n | Array<InjectHotkeySequenceDefinition>\n | (() => Array<InjectHotkeySequenceDefinition>),\n commonOptions:\n | InjectHotkeySequenceOptions\n | (() => InjectHotkeySequenceOptions) = {},\n): void {\n type RegistrationRecord = {\n handle: SequenceRegistrationHandle\n target: Document | HTMLElement | Window\n }\n\n const defaultOptions = injectDefaultHotkeysOptions()\n const manager = getSequenceManager()\n const destroyRef = inject(DestroyRef)\n\n const registrations = new Map<string, RegistrationRecord>()\n\n destroyRef.onDestroy(() => {\n for (const { handle } of registrations.values()) {\n if (handle.isActive) {\n handle.unregister()\n }\n }\n registrations.clear()\n })\n\n effect(() => {\n const resolvedSequences =\n typeof sequences === 'function' ? sequences() : sequences\n const resolvedCommonOptions =\n typeof commonOptions === 'function' ? commonOptions() : commonOptions\n\n const nextKeys = new Set<string>()\n const prepared: Array<{\n registrationKey: string\n def: InjectHotkeySequenceDefinition\n resolvedSequence: HotkeySequence\n enabled: boolean\n sequenceOpts: Omit<InjectHotkeySequenceOptions, 'enabled'>\n resolvedTarget: Document | HTMLElement | Window\n }> = []\n\n for (let i = 0; i < resolvedSequences.length; i++) {\n const def = resolvedSequences[i]!\n const resolvedSequence =\n typeof def.sequence === 'function' ? def.sequence() : def.sequence\n const resolvedDefOptions =\n typeof def.options === 'function' ? def.options() : (def.options ?? {})\n\n const mergedOptions = {\n ...defaultOptions.hotkeySequence,\n ...resolvedCommonOptions,\n ...resolvedDefOptions,\n } as InjectHotkeySequenceOptions\n\n const { enabled = true, ...sequenceOpts } = mergedOptions\n\n if (resolvedSequence.length === 0) {\n continue\n }\n\n const resolvedTarget =\n 'target' in sequenceOpts\n ? (sequenceOpts.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (!resolvedTarget) {\n continue\n }\n\n const registrationKey = `${i}:${formatHotkeySequence(resolvedSequence)}`\n nextKeys.add(registrationKey)\n prepared.push({\n registrationKey,\n def,\n resolvedSequence,\n enabled,\n sequenceOpts,\n resolvedTarget,\n })\n }\n\n for (const [key, record] of [...registrations.entries()]) {\n if (!nextKeys.has(key)) {\n if (record.handle.isActive) {\n record.handle.unregister()\n }\n registrations.delete(key)\n }\n }\n\n for (const p of prepared) {\n const existing = registrations.get(p.registrationKey)\n if (existing?.handle.isActive && existing.target === p.resolvedTarget) {\n existing.handle.callback = p.def.callback\n const { target: _target, ...optionsWithoutTarget } = p.sequenceOpts\n existing.handle.setOptions({\n ...optionsWithoutTarget,\n enabled: p.enabled,\n })\n continue\n }\n\n if (existing) {\n if (existing.handle.isActive) {\n existing.handle.unregister()\n }\n registrations.delete(p.registrationKey)\n }\n\n const handle = manager.register(p.resolvedSequence, p.def.callback, {\n ...p.sequenceOpts,\n enabled: p.enabled,\n target: p.resolvedTarget,\n })\n registrations.set(p.registrationKey, {\n handle,\n target: p.resolvedTarget,\n })\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,sBACd,WAGA,gBAE0C,EAAE,EACtC;CAMN,MAAM,iBAAiB,6BAA6B;CACpD,MAAM,UAAU,oBAAoB;CACpC,MAAM,aAAa,OAAO,WAAW;CAErC,MAAM,gCAAgB,IAAI,KAAiC;AAE3D,YAAW,gBAAgB;AACzB,OAAK,MAAM,EAAE,YAAY,cAAc,QAAQ,CAC7C,KAAI,OAAO,SACT,QAAO,YAAY;AAGvB,gBAAc,OAAO;GACrB;AAEF,cAAa;EACX,MAAM,oBACJ,OAAO,cAAc,aAAa,WAAW,GAAG;EAClD,MAAM,wBACJ,OAAO,kBAAkB,aAAa,eAAe,GAAG;EAE1D,MAAM,2BAAW,IAAI,KAAa;EAClC,MAAM,WAOD,EAAE;AAEP,OAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,QAAQ,KAAK;GACjD,MAAM,MAAM,kBAAkB;GAC9B,MAAM,mBACJ,OAAO,IAAI,aAAa,aAAa,IAAI,UAAU,GAAG,IAAI;GAC5D,MAAM,qBACJ,OAAO,IAAI,YAAY,aAAa,IAAI,SAAS,GAAI,IAAI,WAAW,EAAE;GAQxE,MAAM,EAAE,UAAU,MAAM,GAAG,iBANL;IACpB,GAAG,eAAe;IAClB,GAAG;IACH,GAAG;IACJ;AAID,OAAI,iBAAiB,WAAW,EAC9B;GAGF,MAAM,iBACJ,YAAY,eACP,aAAa,UAAU,OACxB,OAAO,aAAa,cAClB,WACA;AAER,OAAI,CAAC,eACH;GAGF,MAAM,kBAAkB,GAAG,EAAE,GAAG,qBAAqB,iBAAiB;AACtE,YAAS,IAAI,gBAAgB;AAC7B,YAAS,KAAK;IACZ;IACA;IACA;IACA;IACA;IACA;IACD,CAAC;;AAGJ,OAAK,MAAM,CAAC,KAAK,WAAW,CAAC,GAAG,cAAc,SAAS,CAAC,CACtD,KAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AACtB,OAAI,OAAO,OAAO,SAChB,QAAO,OAAO,YAAY;AAE5B,iBAAc,OAAO,IAAI;;AAI7B,OAAK,MAAM,KAAK,UAAU;GACxB,MAAM,WAAW,cAAc,IAAI,EAAE,gBAAgB;AACrD,OAAI,UAAU,OAAO,YAAY,SAAS,WAAW,EAAE,gBAAgB;AACrE,aAAS,OAAO,WAAW,EAAE,IAAI;IACjC,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB,EAAE;AACvD,aAAS,OAAO,WAAW;KACzB,GAAG;KACH,SAAS,EAAE;KACZ,CAAC;AACF;;AAGF,OAAI,UAAU;AACZ,QAAI,SAAS,OAAO,SAClB,UAAS,OAAO,YAAY;AAE9B,kBAAc,OAAO,EAAE,gBAAgB;;GAGzC,MAAM,SAAS,QAAQ,SAAS,EAAE,kBAAkB,EAAE,IAAI,UAAU;IAClE,GAAG,EAAE;IACL,SAAS,EAAE;IACX,QAAQ,EAAE;IACX,CAAC;AACF,iBAAc,IAAI,EAAE,iBAAiB;IACnC;IACA,QAAQ,EAAE;IACX,CAAC;;GAEJ"}
@@ -1,120 +0,0 @@
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/injectHotkeys.ts
6
- /**
7
- * Angular inject-based API for registering multiple keyboard hotkeys at once.
8
- *
9
- * Uses the singleton HotkeyManager for efficient event handling.
10
- * Accepts a dynamic array of hotkey definitions.
11
- *
12
- * Call in an injection context (e.g. constructor or field initializer).
13
- * Uses effect() to track reactive dependencies and update registrations
14
- * when options or the callback change.
15
- *
16
- * Options are merged in this order:
17
- * provideHotkeys defaults < commonOptions < per-definition options
18
- *
19
- * @param hotkeys - Array of hotkey definitions, or getter returning them
20
- * @param commonOptions - Shared options for all hotkeys, or getter
21
- *
22
- * @example
23
- * ```ts
24
- * @Component({ ... })
25
- * export class EditorComponent {
26
- * constructor() {
27
- * injectHotkeys([
28
- * { hotkey: 'Mod+S', callback: () => this.save() },
29
- * { hotkey: 'Mod+Z', callback: () => this.undo() },
30
- * { hotkey: 'Escape', callback: () => this.close() },
31
- * ])
32
- * }
33
- * }
34
- * ```
35
- *
36
- * @example
37
- * ```ts
38
- * @Component({ ... })
39
- * export class DynamicShortcuts {
40
- * shortcuts = signal([...])
41
- *
42
- * constructor() {
43
- * injectHotkeys(
44
- * () => this.shortcuts().map((s) => ({
45
- * hotkey: s.key,
46
- * callback: s.action,
47
- * })),
48
- * )
49
- * }
50
- * }
51
- * ```
52
- */
53
- function injectHotkeys(hotkeys, commonOptions = {}) {
54
- const defaultOptions = require_hotkeys_provider.injectDefaultHotkeysOptions();
55
- const manager = (0, _tanstack_hotkeys.getHotkeyManager)();
56
- const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
57
- const registrations = /* @__PURE__ */ new Map();
58
- destroyRef.onDestroy(() => {
59
- for (const { handle } of registrations.values()) if (handle.isActive) handle.unregister();
60
- registrations.clear();
61
- });
62
- (0, _angular_core.effect)(() => {
63
- const resolvedHotkeys = typeof hotkeys === "function" ? hotkeys() : hotkeys;
64
- const resolvedCommonOptions = typeof commonOptions === "function" ? commonOptions() : commonOptions;
65
- const nextKeys = /* @__PURE__ */ new Set();
66
- const prepared = [];
67
- for (let i = 0; i < resolvedHotkeys.length; i++) {
68
- const def = resolvedHotkeys[i];
69
- const resolvedHotkey = typeof def.hotkey === "function" ? def.hotkey() : def.hotkey;
70
- const resolvedDefOptions = typeof def.options === "function" ? def.options() : def.options ?? {};
71
- const mergedOptions = {
72
- ...defaultOptions.hotkey,
73
- ...resolvedCommonOptions,
74
- ...resolvedDefOptions
75
- };
76
- const hotkeyString = (0, _tanstack_hotkeys.normalizeRegisterableHotkey)(resolvedHotkey, mergedOptions.platform ?? (0, _tanstack_hotkeys.detectPlatform)());
77
- const resolvedTarget = "target" in mergedOptions ? mergedOptions.target ?? null : typeof document !== "undefined" ? document : null;
78
- if (!resolvedTarget) continue;
79
- const registrationKey = `${i}:${hotkeyString}`;
80
- nextKeys.add(registrationKey);
81
- prepared.push({
82
- registrationKey,
83
- def,
84
- mergedOptions,
85
- hotkeyString,
86
- resolvedTarget
87
- });
88
- }
89
- for (const [key, record] of [...registrations.entries()]) if (!nextKeys.has(key)) {
90
- if (record.handle.isActive) record.handle.unregister();
91
- registrations.delete(key);
92
- }
93
- for (const p of prepared) {
94
- const existing = registrations.get(p.registrationKey);
95
- if (existing?.handle.isActive && existing.target === p.resolvedTarget) {
96
- existing.handle.callback = p.def.callback;
97
- const { target: _target, ...optionsWithoutTarget } = p.mergedOptions;
98
- existing.handle.setOptions(optionsWithoutTarget);
99
- continue;
100
- }
101
- if (existing) {
102
- if (existing.handle.isActive) existing.handle.unregister();
103
- registrations.delete(p.registrationKey);
104
- }
105
- const { target: _target, ...optionsWithoutTarget } = p.mergedOptions;
106
- const handle = manager.register(p.hotkeyString, p.def.callback, {
107
- ...optionsWithoutTarget,
108
- target: p.resolvedTarget
109
- });
110
- registrations.set(p.registrationKey, {
111
- handle,
112
- target: p.resolvedTarget
113
- });
114
- }
115
- });
116
- }
117
-
118
- //#endregion
119
- exports.injectHotkeys = injectHotkeys;
120
- //# sourceMappingURL=injectHotkeys.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectHotkeys.cjs","names":["injectDefaultHotkeysOptions","DestroyRef"],"sources":["../src/injectHotkeys.ts"],"sourcesContent":["import { DestroyRef, effect, inject } from '@angular/core'\nimport {\n detectPlatform,\n getHotkeyManager,\n normalizeRegisterableHotkey,\n} from '@tanstack/hotkeys'\nimport { injectDefaultHotkeysOptions } from './hotkeys-provider'\nimport type { InjectHotkeyOptions } from './injectHotkey'\nimport type {\n Hotkey,\n HotkeyCallback,\n HotkeyRegistrationHandle,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\n/**\n * A single hotkey definition for use with `injectHotkeys`.\n */\nexport interface InjectHotkeyDefinition {\n /** The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object */\n hotkey: RegisterableHotkey | (() => RegisterableHotkey)\n /** The function to call when the hotkey is pressed */\n callback: HotkeyCallback\n /** Per-hotkey options (merged on top of commonOptions) */\n options?: InjectHotkeyOptions | (() => InjectHotkeyOptions)\n}\n\n/**\n * Angular inject-based API for registering multiple keyboard hotkeys at once.\n *\n * Uses the singleton HotkeyManager for efficient event handling.\n * Accepts a dynamic array of hotkey definitions.\n *\n * Call in an injection context (e.g. constructor or field initializer).\n * Uses effect() to track reactive dependencies and update registrations\n * when options or the callback change.\n *\n * Options are merged in this order:\n * provideHotkeys defaults < commonOptions < per-definition options\n *\n * @param hotkeys - Array of hotkey definitions, or getter returning them\n * @param commonOptions - Shared options for all hotkeys, or getter\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class EditorComponent {\n * constructor() {\n * injectHotkeys([\n * { hotkey: 'Mod+S', callback: () => this.save() },\n * { hotkey: 'Mod+Z', callback: () => this.undo() },\n * { hotkey: 'Escape', callback: () => this.close() },\n * ])\n * }\n * }\n * ```\n *\n * @example\n * ```ts\n * @Component({ ... })\n * export class DynamicShortcuts {\n * shortcuts = signal([...])\n *\n * constructor() {\n * injectHotkeys(\n * () => this.shortcuts().map((s) => ({\n * hotkey: s.key,\n * callback: s.action,\n * })),\n * )\n * }\n * }\n * ```\n */\nexport function injectHotkeys(\n hotkeys:\n | Array<InjectHotkeyDefinition>\n | (() => Array<InjectHotkeyDefinition>),\n commonOptions: InjectHotkeyOptions | (() => InjectHotkeyOptions) = {},\n): void {\n type RegistrationRecord = {\n handle: HotkeyRegistrationHandle\n target: Document | HTMLElement | Window\n }\n\n const defaultOptions = injectDefaultHotkeysOptions()\n const manager = getHotkeyManager()\n const destroyRef = inject(DestroyRef)\n\n const registrations = new Map<string, RegistrationRecord>()\n\n destroyRef.onDestroy(() => {\n for (const { handle } of registrations.values()) {\n if (handle.isActive) {\n handle.unregister()\n }\n }\n registrations.clear()\n })\n\n effect(() => {\n const resolvedHotkeys = typeof hotkeys === 'function' ? hotkeys() : hotkeys\n const resolvedCommonOptions =\n typeof commonOptions === 'function' ? commonOptions() : commonOptions\n\n const nextKeys = new Set<string>()\n const prepared: Array<{\n registrationKey: string\n def: InjectHotkeyDefinition\n mergedOptions: InjectHotkeyOptions\n hotkeyString: Hotkey\n resolvedTarget: Document | HTMLElement | Window\n }> = []\n\n for (let i = 0; i < resolvedHotkeys.length; i++) {\n const def = resolvedHotkeys[i]!\n const resolvedHotkey =\n typeof def.hotkey === 'function' ? def.hotkey() : def.hotkey\n const resolvedDefOptions =\n typeof def.options === 'function' ? def.options() : (def.options ?? {})\n\n const mergedOptions = {\n ...defaultOptions.hotkey,\n ...resolvedCommonOptions,\n ...resolvedDefOptions,\n } as InjectHotkeyOptions\n\n const platform = mergedOptions.platform ?? detectPlatform()\n const hotkeyString = normalizeRegisterableHotkey(resolvedHotkey, platform)\n\n const resolvedTarget =\n 'target' in mergedOptions\n ? (mergedOptions.target ?? null)\n : typeof document !== 'undefined'\n ? document\n : null\n\n if (!resolvedTarget) {\n continue\n }\n\n const registrationKey = `${i}:${hotkeyString}`\n nextKeys.add(registrationKey)\n prepared.push({\n registrationKey,\n def,\n mergedOptions,\n hotkeyString,\n resolvedTarget,\n })\n }\n\n for (const [key, record] of [...registrations.entries()]) {\n if (!nextKeys.has(key)) {\n if (record.handle.isActive) {\n record.handle.unregister()\n }\n registrations.delete(key)\n }\n }\n\n for (const p of prepared) {\n const existing = registrations.get(p.registrationKey)\n if (existing?.handle.isActive && existing.target === p.resolvedTarget) {\n existing.handle.callback = p.def.callback\n const { target: _target, ...optionsWithoutTarget } = p.mergedOptions\n existing.handle.setOptions(optionsWithoutTarget)\n continue\n }\n\n if (existing) {\n if (existing.handle.isActive) {\n existing.handle.unregister()\n }\n registrations.delete(p.registrationKey)\n }\n\n const { target: _target, ...optionsWithoutTarget } = p.mergedOptions\n const handle = manager.register(p.hotkeyString, p.def.callback, {\n ...optionsWithoutTarget,\n target: p.resolvedTarget,\n })\n registrations.set(p.registrationKey, {\n handle,\n target: p.resolvedTarget,\n })\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,cACd,SAGA,gBAAmE,EAAE,EAC/D;CAMN,MAAM,iBAAiBA,sDAA6B;CACpD,MAAM,mDAA4B;CAClC,MAAM,uCAAoBC,yBAAW;CAErC,MAAM,gCAAgB,IAAI,KAAiC;AAE3D,YAAW,gBAAgB;AACzB,OAAK,MAAM,EAAE,YAAY,cAAc,QAAQ,CAC7C,KAAI,OAAO,SACT,QAAO,YAAY;AAGvB,gBAAc,OAAO;GACrB;AAEF,iCAAa;EACX,MAAM,kBAAkB,OAAO,YAAY,aAAa,SAAS,GAAG;EACpE,MAAM,wBACJ,OAAO,kBAAkB,aAAa,eAAe,GAAG;EAE1D,MAAM,2BAAW,IAAI,KAAa;EAClC,MAAM,WAMD,EAAE;AAEP,OAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;GAC/C,MAAM,MAAM,gBAAgB;GAC5B,MAAM,iBACJ,OAAO,IAAI,WAAW,aAAa,IAAI,QAAQ,GAAG,IAAI;GACxD,MAAM,qBACJ,OAAO,IAAI,YAAY,aAAa,IAAI,SAAS,GAAI,IAAI,WAAW,EAAE;GAExE,MAAM,gBAAgB;IACpB,GAAG,eAAe;IAClB,GAAG;IACH,GAAG;IACJ;GAGD,MAAM,kEAA2C,gBADhC,cAAc,mDAA4B,CACe;GAE1E,MAAM,iBACJ,YAAY,gBACP,cAAc,UAAU,OACzB,OAAO,aAAa,cAClB,WACA;AAER,OAAI,CAAC,eACH;GAGF,MAAM,kBAAkB,GAAG,EAAE,GAAG;AAChC,YAAS,IAAI,gBAAgB;AAC7B,YAAS,KAAK;IACZ;IACA;IACA;IACA;IACA;IACD,CAAC;;AAGJ,OAAK,MAAM,CAAC,KAAK,WAAW,CAAC,GAAG,cAAc,SAAS,CAAC,CACtD,KAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AACtB,OAAI,OAAO,OAAO,SAChB,QAAO,OAAO,YAAY;AAE5B,iBAAc,OAAO,IAAI;;AAI7B,OAAK,MAAM,KAAK,UAAU;GACxB,MAAM,WAAW,cAAc,IAAI,EAAE,gBAAgB;AACrD,OAAI,UAAU,OAAO,YAAY,SAAS,WAAW,EAAE,gBAAgB;AACrE,aAAS,OAAO,WAAW,EAAE,IAAI;IACjC,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB,EAAE;AACvD,aAAS,OAAO,WAAW,qBAAqB;AAChD;;AAGF,OAAI,UAAU;AACZ,QAAI,SAAS,OAAO,SAClB,UAAS,OAAO,YAAY;AAE9B,kBAAc,OAAO,EAAE,gBAAgB;;GAGzC,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB,EAAE;GACvD,MAAM,SAAS,QAAQ,SAAS,EAAE,cAAc,EAAE,IAAI,UAAU;IAC9D,GAAG;IACH,QAAQ,EAAE;IACX,CAAC;AACF,iBAAc,IAAI,EAAE,iBAAiB;IACnC;IACA,QAAQ,EAAE;IACX,CAAC;;GAEJ"}