@tanstack/vue-hotkeys 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +122 -0
  2. package/dist/HotkeysProvider.cjs +31 -0
  3. package/dist/HotkeysProvider.cjs.map +1 -0
  4. package/dist/HotkeysProvider.d.cts +34 -0
  5. package/dist/HotkeysProvider.d.ts +34 -0
  6. package/dist/HotkeysProvider.js +31 -0
  7. package/dist/HotkeysProvider.js.map +1 -0
  8. package/dist/HotkeysProviderContext.cjs +20 -0
  9. package/dist/HotkeysProviderContext.cjs.map +1 -0
  10. package/dist/HotkeysProviderContext.d.cts +19 -0
  11. package/dist/HotkeysProviderContext.d.ts +19 -0
  12. package/dist/HotkeysProviderContext.js +18 -0
  13. package/dist/HotkeysProviderContext.js.map +1 -0
  14. package/dist/index.cjs +27 -0
  15. package/dist/index.d.cts +10 -0
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.js +12 -0
  18. package/dist/useHeldKeyCodes.cjs +37 -0
  19. package/dist/useHeldKeyCodes.cjs.map +1 -0
  20. package/dist/useHeldKeyCodes.d.cts +33 -0
  21. package/dist/useHeldKeyCodes.d.ts +33 -0
  22. package/dist/useHeldKeyCodes.js +37 -0
  23. package/dist/useHeldKeyCodes.js.map +1 -0
  24. package/dist/useHeldKeys.cjs +35 -0
  25. package/dist/useHeldKeys.cjs.map +1 -0
  26. package/dist/useHeldKeys.d.cts +31 -0
  27. package/dist/useHeldKeys.d.ts +31 -0
  28. package/dist/useHeldKeys.js +35 -0
  29. package/dist/useHeldKeys.js.map +1 -0
  30. package/dist/useHotkey.cjs +124 -0
  31. package/dist/useHotkey.cjs.map +1 -0
  32. package/dist/useHotkey.d.cts +86 -0
  33. package/dist/useHotkey.d.ts +86 -0
  34. package/dist/useHotkey.js +124 -0
  35. package/dist/useHotkey.js.map +1 -0
  36. package/dist/useHotkeyRecorder.cjs +80 -0
  37. package/dist/useHotkeyRecorder.cjs.map +1 -0
  38. package/dist/useHotkeyRecorder.d.cts +61 -0
  39. package/dist/useHotkeyRecorder.d.ts +61 -0
  40. package/dist/useHotkeyRecorder.js +80 -0
  41. package/dist/useHotkeyRecorder.js.map +1 -0
  42. package/dist/useHotkeySequence.cjs +95 -0
  43. package/dist/useHotkeySequence.cjs.map +1 -0
  44. package/dist/useHotkeySequence.d.cts +58 -0
  45. package/dist/useHotkeySequence.d.ts +58 -0
  46. package/dist/useHotkeySequence.js +95 -0
  47. package/dist/useHotkeySequence.js.map +1 -0
  48. package/dist/useKeyHold.cjs +60 -0
  49. package/dist/useKeyHold.cjs.map +1 -0
  50. package/dist/useKeyHold.d.cts +52 -0
  51. package/dist/useKeyHold.d.ts +52 -0
  52. package/dist/useKeyHold.js +60 -0
  53. package/dist/useKeyHold.js.map +1 -0
  54. package/package.json +66 -0
  55. package/src/HotkeysProvider.tsx +29 -0
  56. package/src/HotkeysProviderContext.ts +37 -0
  57. package/src/index.ts +14 -0
  58. package/src/useHeldKeyCodes.ts +34 -0
  59. package/src/useHeldKeys.ts +32 -0
  60. package/src/useHotkey.ts +197 -0
  61. package/src/useHotkeyRecorder.ts +112 -0
  62. package/src/useHotkeySequence.ts +158 -0
  63. package/src/useKeyHold.ts +65 -0
  64. package/src/vue.d.ts +6 -0
@@ -0,0 +1,61 @@
1
+ import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
2
+ import { MaybeRefOrGetter, Ref } from "vue";
3
+
4
+ //#region src/useHotkeyRecorder.d.ts
5
+ interface VueHotkeyRecorder {
6
+ /** Whether recording is currently active */
7
+ isRecording: Ref<boolean>;
8
+ /** The currently recorded hotkey (for live preview) */
9
+ recordedHotkey: Ref<Hotkey | null>;
10
+ /** Start recording a new hotkey */
11
+ startRecording: () => void;
12
+ /** Stop recording (same as cancel) */
13
+ stopRecording: () => void;
14
+ /** Cancel recording without saving */
15
+ cancelRecording: () => void;
16
+ }
17
+ /**
18
+ * Vue composable for recording keyboard shortcuts.
19
+ *
20
+ * This composable provides a thin wrapper around the framework-agnostic `HotkeyRecorder`
21
+ * class, managing all the complexity of capturing keyboard events, converting them
22
+ * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete
23
+ * to clear.
24
+ *
25
+ * @param options - Configuration options for the recorder
26
+ * @returns An object with recording state and control functions
27
+ *
28
+ * @example
29
+ * ```vue
30
+ * <script setup>
31
+ * import { ref } from 'vue'
32
+ * import { useHotkeyRecorder } from '@tanstack/vue-hotkeys'
33
+ *
34
+ * const shortcut = ref<Hotkey>('Mod+S')
35
+ *
36
+ * const recorder = useHotkeyRecorder({
37
+ * onRecord: (hotkey) => {
38
+ * shortcut.value = hotkey
39
+ * },
40
+ * onCancel: () => {
41
+ * console.log('Recording cancelled')
42
+ * },
43
+ * })
44
+ * </script>
45
+ *
46
+ * <template>
47
+ * <div>
48
+ * <button @click="recorder.startRecording()">
49
+ * {{ recorder.isRecording ? 'Recording...' : 'Edit Shortcut' }}
50
+ * </button>
51
+ * <div v-if="recorder.recordedHotkey">
52
+ * Recording: {{ recorder.recordedHotkey }}
53
+ * </div>
54
+ * </div>
55
+ * </template>
56
+ * ```
57
+ */
58
+ declare function useHotkeyRecorder(options: MaybeRefOrGetter<HotkeyRecorderOptions>): VueHotkeyRecorder;
59
+ //#endregion
60
+ export { VueHotkeyRecorder, useHotkeyRecorder };
61
+ //# sourceMappingURL=useHotkeyRecorder.d.cts.map
@@ -0,0 +1,61 @@
1
+ import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
2
+ import { MaybeRefOrGetter, Ref } from "vue";
3
+
4
+ //#region src/useHotkeyRecorder.d.ts
5
+ interface VueHotkeyRecorder {
6
+ /** Whether recording is currently active */
7
+ isRecording: Ref<boolean>;
8
+ /** The currently recorded hotkey (for live preview) */
9
+ recordedHotkey: Ref<Hotkey | null>;
10
+ /** Start recording a new hotkey */
11
+ startRecording: () => void;
12
+ /** Stop recording (same as cancel) */
13
+ stopRecording: () => void;
14
+ /** Cancel recording without saving */
15
+ cancelRecording: () => void;
16
+ }
17
+ /**
18
+ * Vue composable for recording keyboard shortcuts.
19
+ *
20
+ * This composable provides a thin wrapper around the framework-agnostic `HotkeyRecorder`
21
+ * class, managing all the complexity of capturing keyboard events, converting them
22
+ * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete
23
+ * to clear.
24
+ *
25
+ * @param options - Configuration options for the recorder
26
+ * @returns An object with recording state and control functions
27
+ *
28
+ * @example
29
+ * ```vue
30
+ * <script setup>
31
+ * import { ref } from 'vue'
32
+ * import { useHotkeyRecorder } from '@tanstack/vue-hotkeys'
33
+ *
34
+ * const shortcut = ref<Hotkey>('Mod+S')
35
+ *
36
+ * const recorder = useHotkeyRecorder({
37
+ * onRecord: (hotkey) => {
38
+ * shortcut.value = hotkey
39
+ * },
40
+ * onCancel: () => {
41
+ * console.log('Recording cancelled')
42
+ * },
43
+ * })
44
+ * </script>
45
+ *
46
+ * <template>
47
+ * <div>
48
+ * <button @click="recorder.startRecording()">
49
+ * {{ recorder.isRecording ? 'Recording...' : 'Edit Shortcut' }}
50
+ * </button>
51
+ * <div v-if="recorder.recordedHotkey">
52
+ * Recording: {{ recorder.recordedHotkey }}
53
+ * </div>
54
+ * </div>
55
+ * </template>
56
+ * ```
57
+ */
58
+ declare function useHotkeyRecorder(options: MaybeRefOrGetter<HotkeyRecorderOptions>): VueHotkeyRecorder;
59
+ //#endregion
60
+ export { VueHotkeyRecorder, useHotkeyRecorder };
61
+ //# sourceMappingURL=useHotkeyRecorder.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { useDefaultHotkeysOptions } from "./HotkeysProviderContext.js";
2
+ import { HotkeyRecorder } from "@tanstack/hotkeys";
3
+ import { onUnmounted, unref, watch } from "vue";
4
+ import { useStore } from "@tanstack/vue-store";
5
+
6
+ //#region src/useHotkeyRecorder.ts
7
+ /**
8
+ * Vue composable for recording keyboard shortcuts.
9
+ *
10
+ * This composable provides a thin wrapper around the framework-agnostic `HotkeyRecorder`
11
+ * class, managing all the complexity of capturing keyboard events, converting them
12
+ * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete
13
+ * to clear.
14
+ *
15
+ * @param options - Configuration options for the recorder
16
+ * @returns An object with recording state and control functions
17
+ *
18
+ * @example
19
+ * ```vue
20
+ * <script setup>
21
+ * import { ref } from 'vue'
22
+ * import { useHotkeyRecorder } from '@tanstack/vue-hotkeys'
23
+ *
24
+ * const shortcut = ref<Hotkey>('Mod+S')
25
+ *
26
+ * const recorder = useHotkeyRecorder({
27
+ * onRecord: (hotkey) => {
28
+ * shortcut.value = hotkey
29
+ * },
30
+ * onCancel: () => {
31
+ * console.log('Recording cancelled')
32
+ * },
33
+ * })
34
+ * <\/script>
35
+ *
36
+ * <template>
37
+ * <div>
38
+ * <button @click="recorder.startRecording()">
39
+ * {{ recorder.isRecording ? 'Recording...' : 'Edit Shortcut' }}
40
+ * </button>
41
+ * <div v-if="recorder.recordedHotkey">
42
+ * Recording: {{ recorder.recordedHotkey }}
43
+ * </div>
44
+ * </div>
45
+ * </template>
46
+ * ```
47
+ */
48
+ function useHotkeyRecorder(options) {
49
+ const defaultOptions = useDefaultHotkeysOptions();
50
+ const recorder = new HotkeyRecorder(resolveRecorderOptions(options, defaultOptions));
51
+ const isRecording = useStore(recorder.store, (state) => state.isRecording);
52
+ const recordedHotkey = useStore(recorder.store, (state) => state.recordedHotkey);
53
+ const stopWatcher = watch(() => resolveRecorderOptions(options, defaultOptions), (resolvedOptions) => {
54
+ recorder.setOptions(resolvedOptions);
55
+ }, { immediate: true });
56
+ onUnmounted(() => {
57
+ stopWatcher();
58
+ recorder.destroy();
59
+ });
60
+ return {
61
+ isRecording,
62
+ recordedHotkey,
63
+ startRecording: () => recorder.start(),
64
+ stopRecording: () => recorder.stop(),
65
+ cancelRecording: () => recorder.cancel()
66
+ };
67
+ }
68
+ function resolveRecorderOptions(options, defaultOptions) {
69
+ return {
70
+ ...defaultOptions.hotkeyRecorder,
71
+ ...resolveMaybeRefOrGetter(options)
72
+ };
73
+ }
74
+ function resolveMaybeRefOrGetter(value) {
75
+ return typeof value === "function" ? value() : unref(value);
76
+ }
77
+
78
+ //#endregion
79
+ export { useHotkeyRecorder };
80
+ //# sourceMappingURL=useHotkeyRecorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHotkeyRecorder.js","names":[],"sources":["../src/useHotkeyRecorder.ts"],"sourcesContent":["import { onUnmounted, unref, watch } from 'vue'\nimport { useStore } from '@tanstack/vue-store'\nimport { HotkeyRecorder } from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProviderContext'\nimport type { MaybeRefOrGetter, Ref } from 'vue'\nimport type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'\n\nexport interface VueHotkeyRecorder {\n /** Whether recording is currently active */\n isRecording: Ref<boolean>\n /** The currently recorded hotkey (for live preview) */\n recordedHotkey: Ref<Hotkey | null>\n /** Start recording a new hotkey */\n startRecording: () => void\n /** Stop recording (same as cancel) */\n stopRecording: () => void\n /** Cancel recording without saving */\n cancelRecording: () => void\n}\n\n/**\n * Vue composable for recording keyboard shortcuts.\n *\n * This composable provides a thin wrapper around the framework-agnostic `HotkeyRecorder`\n * class, managing all the complexity of capturing keyboard events, converting them\n * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete\n * to clear.\n *\n * @param options - Configuration options for the recorder\n * @returns An object with recording state and control functions\n *\n * @example\n * ```vue\n * <script setup>\n * import { ref } from 'vue'\n * import { useHotkeyRecorder } from '@tanstack/vue-hotkeys'\n *\n * const shortcut = ref<Hotkey>('Mod+S')\n *\n * const recorder = useHotkeyRecorder({\n * onRecord: (hotkey) => {\n * shortcut.value = hotkey\n * },\n * onCancel: () => {\n * console.log('Recording cancelled')\n * },\n * })\n * </script>\n *\n * <template>\n * <div>\n * <button @click=\"recorder.startRecording()\">\n * {{ recorder.isRecording ? 'Recording...' : 'Edit Shortcut' }}\n * </button>\n * <div v-if=\"recorder.recordedHotkey\">\n * Recording: {{ recorder.recordedHotkey }}\n * </div>\n * </div>\n * </template>\n * ```\n */\nexport function useHotkeyRecorder(\n options: MaybeRefOrGetter<HotkeyRecorderOptions>,\n): VueHotkeyRecorder {\n const defaultOptions = useDefaultHotkeysOptions()\n const recorder = new HotkeyRecorder(\n resolveRecorderOptions(options, defaultOptions),\n )\n\n // Subscribe to recorder state using useStore\n const isRecording = useStore(recorder.store, (state) => state.isRecording)\n const recordedHotkey = useStore(\n recorder.store,\n (state) => state.recordedHotkey,\n )\n\n const stopWatcher = watch(\n () => resolveRecorderOptions(options, defaultOptions),\n (resolvedOptions) => {\n recorder.setOptions(resolvedOptions)\n },\n { immediate: true },\n )\n\n // Cleanup on unmount\n onUnmounted(() => {\n stopWatcher()\n recorder.destroy()\n })\n\n return {\n isRecording: isRecording as Ref<boolean>,\n recordedHotkey: recordedHotkey as Ref<Hotkey | null>,\n startRecording: () => recorder.start(),\n stopRecording: () => recorder.stop(),\n cancelRecording: () => recorder.cancel(),\n }\n}\n\nfunction resolveRecorderOptions(\n options: MaybeRefOrGetter<HotkeyRecorderOptions>,\n defaultOptions: ReturnType<typeof useDefaultHotkeysOptions>,\n): HotkeyRecorderOptions {\n return {\n ...defaultOptions.hotkeyRecorder,\n ...resolveMaybeRefOrGetter(options),\n } as HotkeyRecorderOptions\n}\n\nfunction resolveMaybeRefOrGetter<T>(value: MaybeRefOrGetter<T>): T {\n return typeof value === 'function' ? (value as () => T)() : unref(value)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,kBACd,SACmB;CACnB,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,WAAW,IAAI,eACnB,uBAAuB,SAAS,eAAe,CAChD;CAGD,MAAM,cAAc,SAAS,SAAS,QAAQ,UAAU,MAAM,YAAY;CAC1E,MAAM,iBAAiB,SACrB,SAAS,QACR,UAAU,MAAM,eAClB;CAED,MAAM,cAAc,YACZ,uBAAuB,SAAS,eAAe,GACpD,oBAAoB;AACnB,WAAS,WAAW,gBAAgB;IAEtC,EAAE,WAAW,MAAM,CACpB;AAGD,mBAAkB;AAChB,eAAa;AACb,WAAS,SAAS;GAClB;AAEF,QAAO;EACQ;EACG;EAChB,sBAAsB,SAAS,OAAO;EACtC,qBAAqB,SAAS,MAAM;EACpC,uBAAuB,SAAS,QAAQ;EACzC;;AAGH,SAAS,uBACP,SACA,gBACuB;AACvB,QAAO;EACL,GAAG,eAAe;EAClB,GAAG,wBAAwB,QAAQ;EACpC;;AAGH,SAAS,wBAA2B,OAA+B;AACjE,QAAO,OAAO,UAAU,aAAc,OAAmB,GAAG,MAAM,MAAM"}
@@ -0,0 +1,95 @@
1
+ const require_HotkeysProviderContext = require('./HotkeysProviderContext.cjs');
2
+ let _tanstack_hotkeys = require("@tanstack/hotkeys");
3
+ let vue = require("vue");
4
+
5
+ //#region src/useHotkeySequence.ts
6
+ /**
7
+ * Vue composable for registering a keyboard shortcut sequence (Vim-style).
8
+ *
9
+ * This composable allows you to register multi-key sequences like 'g g' or 'd d'
10
+ * that trigger when the full sequence is pressed within a timeout.
11
+ *
12
+ * @param sequence - Array of hotkey strings that form the sequence
13
+ * @param callback - Function to call when the sequence is completed
14
+ * @param options - Options for the sequence behavior
15
+ *
16
+ * @example
17
+ * ```vue
18
+ * <script setup>
19
+ * import { useHotkeySequence } from '@tanstack/vue-hotkeys'
20
+ *
21
+ * // 'g g' to go to top
22
+ * useHotkeySequence(['G', 'G'], () => {
23
+ * scrollToTop()
24
+ * })
25
+ *
26
+ * // 'd d' to delete line
27
+ * useHotkeySequence(['D', 'D'], () => {
28
+ * deleteLine()
29
+ * })
30
+ *
31
+ * // 'd i w' to delete inner word
32
+ * useHotkeySequence(['D', 'I', 'W'], () => {
33
+ * deleteInnerWord()
34
+ * }, { timeout: 500 })
35
+ * <\/script>
36
+ *
37
+ * <template>
38
+ * <div>...</div>
39
+ * </template>
40
+ * ```
41
+ */
42
+ function useHotkeySequence(sequence, callback, options = {}) {
43
+ const defaultOptions = require_HotkeysProviderContext.useDefaultHotkeysOptions();
44
+ const manager = (0, _tanstack_hotkeys.getSequenceManager)();
45
+ let registration = null;
46
+ const stopWatcher = (0, vue.watch)(() => {
47
+ const resolvedSequence = resolveMaybeRefOrGetter(sequence);
48
+ const resolvedOptions = resolveMaybeRefOrGetter(options);
49
+ const mergedOptions = {
50
+ ...defaultOptions.hotkeySequence,
51
+ ...resolvedOptions
52
+ };
53
+ return {
54
+ resolvedSequence,
55
+ mergedOptions,
56
+ resolvedEnabled: mergedOptions.enabled === void 0 ? void 0 : resolveMaybeRefOrGetter(mergedOptions.enabled),
57
+ resolvedTarget: mergedOptions.target === void 0 ? void 0 : resolveMaybeRefOrGetter(mergedOptions.target)
58
+ };
59
+ }, ({ resolvedSequence, mergedOptions, resolvedEnabled, resolvedTarget }) => {
60
+ if (resolvedEnabled === false || resolvedSequence.length === 0) return;
61
+ const finalTarget = resolvedTarget ?? (typeof document !== "undefined" ? document : null);
62
+ if (!finalTarget) return;
63
+ if (registration?.isActive) {
64
+ registration.unregister();
65
+ registration = null;
66
+ }
67
+ const { target: _target, enabled: _enabled, ...restOptions } = mergedOptions;
68
+ const optionsWithoutTarget = {
69
+ ...restOptions,
70
+ ...resolvedEnabled === void 0 ? {} : { enabled: resolvedEnabled }
71
+ };
72
+ registration = manager.register(resolvedSequence, callback, {
73
+ ...optionsWithoutTarget,
74
+ target: finalTarget
75
+ });
76
+ if (registration.isActive) {
77
+ registration.callback = callback;
78
+ registration.setOptions(optionsWithoutTarget);
79
+ }
80
+ }, { immediate: true });
81
+ (0, vue.onUnmounted)(() => {
82
+ stopWatcher();
83
+ if (registration?.isActive) {
84
+ registration.unregister();
85
+ registration = null;
86
+ }
87
+ });
88
+ }
89
+ function resolveMaybeRefOrGetter(value) {
90
+ return typeof value === "function" ? value() : (0, vue.unref)(value);
91
+ }
92
+
93
+ //#endregion
94
+ exports.useHotkeySequence = useHotkeySequence;
95
+ //# sourceMappingURL=useHotkeySequence.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHotkeySequence.cjs","names":["useDefaultHotkeysOptions"],"sources":["../src/useHotkeySequence.ts"],"sourcesContent":["import { onUnmounted, unref, watch } from 'vue'\nimport { getSequenceManager } from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProviderContext'\nimport type { MaybeRefOrGetter } from 'vue'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\nexport interface UseHotkeySequenceOptions extends Omit<\n SequenceOptions,\n 'enabled' | 'target'\n> {\n /**\n * Whether the sequence is active.\n * Can be a Ref, a getter function, or a boolean value.\n * Defaults to true.\n */\n enabled?: MaybeRefOrGetter<boolean>\n /**\n * The DOM element to attach the event listener to.\n * Can be a Ref, a getter function, direct DOM element, or null.\n * Defaults to document.\n */\n target?: MaybeRefOrGetter<HTMLElement | Document | Window | null>\n}\n\n/**\n * Vue composable for registering a keyboard shortcut sequence (Vim-style).\n *\n * This composable allows you to register multi-key sequences like 'g g' or 'd d'\n * that trigger when the full sequence is pressed within a timeout.\n *\n * @param sequence - Array of hotkey strings that form the sequence\n * @param callback - Function to call when the sequence is completed\n * @param options - Options for the sequence behavior\n *\n * @example\n * ```vue\n * <script setup>\n * import { useHotkeySequence } from '@tanstack/vue-hotkeys'\n *\n * // 'g g' to go to top\n * useHotkeySequence(['G', 'G'], () => {\n * scrollToTop()\n * })\n *\n * // 'd d' to delete line\n * useHotkeySequence(['D', 'D'], () => {\n * deleteLine()\n * })\n *\n * // 'd i w' to delete inner word\n * useHotkeySequence(['D', 'I', 'W'], () => {\n * deleteInnerWord()\n * }, { timeout: 500 })\n * </script>\n *\n * <template>\n * <div>...</div>\n * </template>\n * ```\n */\nexport function useHotkeySequence(\n sequence: MaybeRefOrGetter<HotkeySequence>,\n callback: HotkeyCallback,\n options: MaybeRefOrGetter<UseHotkeySequenceOptions> = {},\n): void {\n const defaultOptions = useDefaultHotkeysOptions()\n const manager = getSequenceManager()\n\n let registration: SequenceRegistrationHandle | null = null\n\n // Watch for changes to reactive dependencies\n const stopWatcher = watch(\n () => {\n const resolvedSequence = resolveMaybeRefOrGetter(sequence)\n const resolvedOptions = resolveMaybeRefOrGetter(options)\n const mergedOptions = {\n ...defaultOptions.hotkeySequence,\n ...resolvedOptions,\n } as UseHotkeySequenceOptions\n const resolvedEnabled =\n mergedOptions.enabled === undefined\n ? undefined\n : resolveMaybeRefOrGetter(mergedOptions.enabled)\n const resolvedTarget =\n mergedOptions.target === undefined\n ? undefined\n : resolveMaybeRefOrGetter(mergedOptions.target)\n\n return {\n resolvedSequence,\n mergedOptions,\n resolvedEnabled,\n resolvedTarget,\n }\n },\n ({ resolvedSequence, mergedOptions, resolvedEnabled, resolvedTarget }) => {\n if (resolvedEnabled === false || resolvedSequence.length === 0) {\n return\n }\n\n // Resolve target\n const finalTarget =\n resolvedTarget ?? (typeof document !== 'undefined' ? document : null)\n\n if (!finalTarget) {\n return\n }\n\n // Unregister previous registration if it exists\n if (registration?.isActive) {\n registration.unregister()\n registration = null\n }\n\n // Extract options without target (target is handled separately)\n const {\n target: _target,\n enabled: _enabled,\n ...restOptions\n } = mergedOptions\n const optionsWithoutTarget = {\n ...restOptions,\n ...(resolvedEnabled === undefined ? {} : { enabled: resolvedEnabled }),\n }\n\n // Register the sequence\n registration = manager.register(resolvedSequence, callback, {\n ...optionsWithoutTarget,\n target: finalTarget,\n })\n\n // Update callback and options\n if (registration.isActive) {\n registration.callback = callback\n registration.setOptions(optionsWithoutTarget)\n }\n },\n { immediate: true },\n )\n\n // Cleanup on unmount\n onUnmounted(() => {\n stopWatcher()\n if (registration?.isActive) {\n registration.unregister()\n registration = null\n }\n })\n}\n\nfunction resolveMaybeRefOrGetter<T>(value: MaybeRefOrGetter<T>): T {\n return typeof value === 'function' ? (value as () => T)() : unref(value)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,SAAgB,kBACd,UACA,UACA,UAAsD,EAAE,EAClD;CACN,MAAM,iBAAiBA,yDAA0B;CACjD,MAAM,qDAA8B;CAEpC,IAAI,eAAkD;CAGtD,MAAM,mCACE;EACJ,MAAM,mBAAmB,wBAAwB,SAAS;EAC1D,MAAM,kBAAkB,wBAAwB,QAAQ;EACxD,MAAM,gBAAgB;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ;AAUD,SAAO;GACL;GACA;GACA,iBAXA,cAAc,YAAY,SACtB,SACA,wBAAwB,cAAc,QAAQ;GAUlD,gBARA,cAAc,WAAW,SACrB,SACA,wBAAwB,cAAc,OAAO;GAOlD;KAEF,EAAE,kBAAkB,eAAe,iBAAiB,qBAAqB;AACxE,MAAI,oBAAoB,SAAS,iBAAiB,WAAW,EAC3D;EAIF,MAAM,cACJ,mBAAmB,OAAO,aAAa,cAAc,WAAW;AAElE,MAAI,CAAC,YACH;AAIF,MAAI,cAAc,UAAU;AAC1B,gBAAa,YAAY;AACzB,kBAAe;;EAIjB,MAAM,EACJ,QAAQ,SACR,SAAS,UACT,GAAG,gBACD;EACJ,MAAM,uBAAuB;GAC3B,GAAG;GACH,GAAI,oBAAoB,SAAY,EAAE,GAAG,EAAE,SAAS,iBAAiB;GACtE;AAGD,iBAAe,QAAQ,SAAS,kBAAkB,UAAU;GAC1D,GAAG;GACH,QAAQ;GACT,CAAC;AAGF,MAAI,aAAa,UAAU;AACzB,gBAAa,WAAW;AACxB,gBAAa,WAAW,qBAAqB;;IAGjD,EAAE,WAAW,MAAM,CACpB;AAGD,4BAAkB;AAChB,eAAa;AACb,MAAI,cAAc,UAAU;AAC1B,gBAAa,YAAY;AACzB,kBAAe;;GAEjB;;AAGJ,SAAS,wBAA2B,OAA+B;AACjE,QAAO,OAAO,UAAU,aAAc,OAAmB,kBAAS,MAAM"}
@@ -0,0 +1,58 @@
1
+ import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
+ import { MaybeRefOrGetter } from "vue";
3
+
4
+ //#region src/useHotkeySequence.d.ts
5
+ interface UseHotkeySequenceOptions extends Omit<SequenceOptions, 'enabled' | 'target'> {
6
+ /**
7
+ * Whether the sequence is active.
8
+ * Can be a Ref, a getter function, or a boolean value.
9
+ * Defaults to true.
10
+ */
11
+ enabled?: MaybeRefOrGetter<boolean>;
12
+ /**
13
+ * The DOM element to attach the event listener to.
14
+ * Can be a Ref, a getter function, direct DOM element, or null.
15
+ * Defaults to document.
16
+ */
17
+ target?: MaybeRefOrGetter<HTMLElement | Document | Window | null>;
18
+ }
19
+ /**
20
+ * Vue composable for registering a keyboard shortcut sequence (Vim-style).
21
+ *
22
+ * This composable allows you to register multi-key sequences like 'g g' or 'd d'
23
+ * that trigger when the full sequence is pressed within a timeout.
24
+ *
25
+ * @param sequence - Array of hotkey strings that form the sequence
26
+ * @param callback - Function to call when the sequence is completed
27
+ * @param options - Options for the sequence behavior
28
+ *
29
+ * @example
30
+ * ```vue
31
+ * <script setup>
32
+ * import { useHotkeySequence } from '@tanstack/vue-hotkeys'
33
+ *
34
+ * // 'g g' to go to top
35
+ * useHotkeySequence(['G', 'G'], () => {
36
+ * scrollToTop()
37
+ * })
38
+ *
39
+ * // 'd d' to delete line
40
+ * useHotkeySequence(['D', 'D'], () => {
41
+ * deleteLine()
42
+ * })
43
+ *
44
+ * // 'd i w' to delete inner word
45
+ * useHotkeySequence(['D', 'I', 'W'], () => {
46
+ * deleteInnerWord()
47
+ * }, { timeout: 500 })
48
+ * </script>
49
+ *
50
+ * <template>
51
+ * <div>...</div>
52
+ * </template>
53
+ * ```
54
+ */
55
+ declare function useHotkeySequence(sequence: MaybeRefOrGetter<HotkeySequence>, callback: HotkeyCallback, options?: MaybeRefOrGetter<UseHotkeySequenceOptions>): void;
56
+ //#endregion
57
+ export { UseHotkeySequenceOptions, useHotkeySequence };
58
+ //# sourceMappingURL=useHotkeySequence.d.cts.map
@@ -0,0 +1,58 @@
1
+ import { HotkeyCallback, HotkeySequence, SequenceOptions } from "@tanstack/hotkeys";
2
+ import { MaybeRefOrGetter } from "vue";
3
+
4
+ //#region src/useHotkeySequence.d.ts
5
+ interface UseHotkeySequenceOptions extends Omit<SequenceOptions, 'enabled' | 'target'> {
6
+ /**
7
+ * Whether the sequence is active.
8
+ * Can be a Ref, a getter function, or a boolean value.
9
+ * Defaults to true.
10
+ */
11
+ enabled?: MaybeRefOrGetter<boolean>;
12
+ /**
13
+ * The DOM element to attach the event listener to.
14
+ * Can be a Ref, a getter function, direct DOM element, or null.
15
+ * Defaults to document.
16
+ */
17
+ target?: MaybeRefOrGetter<HTMLElement | Document | Window | null>;
18
+ }
19
+ /**
20
+ * Vue composable for registering a keyboard shortcut sequence (Vim-style).
21
+ *
22
+ * This composable allows you to register multi-key sequences like 'g g' or 'd d'
23
+ * that trigger when the full sequence is pressed within a timeout.
24
+ *
25
+ * @param sequence - Array of hotkey strings that form the sequence
26
+ * @param callback - Function to call when the sequence is completed
27
+ * @param options - Options for the sequence behavior
28
+ *
29
+ * @example
30
+ * ```vue
31
+ * <script setup>
32
+ * import { useHotkeySequence } from '@tanstack/vue-hotkeys'
33
+ *
34
+ * // 'g g' to go to top
35
+ * useHotkeySequence(['G', 'G'], () => {
36
+ * scrollToTop()
37
+ * })
38
+ *
39
+ * // 'd d' to delete line
40
+ * useHotkeySequence(['D', 'D'], () => {
41
+ * deleteLine()
42
+ * })
43
+ *
44
+ * // 'd i w' to delete inner word
45
+ * useHotkeySequence(['D', 'I', 'W'], () => {
46
+ * deleteInnerWord()
47
+ * }, { timeout: 500 })
48
+ * </script>
49
+ *
50
+ * <template>
51
+ * <div>...</div>
52
+ * </template>
53
+ * ```
54
+ */
55
+ declare function useHotkeySequence(sequence: MaybeRefOrGetter<HotkeySequence>, callback: HotkeyCallback, options?: MaybeRefOrGetter<UseHotkeySequenceOptions>): void;
56
+ //#endregion
57
+ export { UseHotkeySequenceOptions, useHotkeySequence };
58
+ //# sourceMappingURL=useHotkeySequence.d.ts.map
@@ -0,0 +1,95 @@
1
+ import { useDefaultHotkeysOptions } from "./HotkeysProviderContext.js";
2
+ import { getSequenceManager } from "@tanstack/hotkeys";
3
+ import { onUnmounted, unref, watch } from "vue";
4
+
5
+ //#region src/useHotkeySequence.ts
6
+ /**
7
+ * Vue composable for registering a keyboard shortcut sequence (Vim-style).
8
+ *
9
+ * This composable allows you to register multi-key sequences like 'g g' or 'd d'
10
+ * that trigger when the full sequence is pressed within a timeout.
11
+ *
12
+ * @param sequence - Array of hotkey strings that form the sequence
13
+ * @param callback - Function to call when the sequence is completed
14
+ * @param options - Options for the sequence behavior
15
+ *
16
+ * @example
17
+ * ```vue
18
+ * <script setup>
19
+ * import { useHotkeySequence } from '@tanstack/vue-hotkeys'
20
+ *
21
+ * // 'g g' to go to top
22
+ * useHotkeySequence(['G', 'G'], () => {
23
+ * scrollToTop()
24
+ * })
25
+ *
26
+ * // 'd d' to delete line
27
+ * useHotkeySequence(['D', 'D'], () => {
28
+ * deleteLine()
29
+ * })
30
+ *
31
+ * // 'd i w' to delete inner word
32
+ * useHotkeySequence(['D', 'I', 'W'], () => {
33
+ * deleteInnerWord()
34
+ * }, { timeout: 500 })
35
+ * <\/script>
36
+ *
37
+ * <template>
38
+ * <div>...</div>
39
+ * </template>
40
+ * ```
41
+ */
42
+ function useHotkeySequence(sequence, callback, options = {}) {
43
+ const defaultOptions = useDefaultHotkeysOptions();
44
+ const manager = getSequenceManager();
45
+ let registration = null;
46
+ const stopWatcher = watch(() => {
47
+ const resolvedSequence = resolveMaybeRefOrGetter(sequence);
48
+ const resolvedOptions = resolveMaybeRefOrGetter(options);
49
+ const mergedOptions = {
50
+ ...defaultOptions.hotkeySequence,
51
+ ...resolvedOptions
52
+ };
53
+ return {
54
+ resolvedSequence,
55
+ mergedOptions,
56
+ resolvedEnabled: mergedOptions.enabled === void 0 ? void 0 : resolveMaybeRefOrGetter(mergedOptions.enabled),
57
+ resolvedTarget: mergedOptions.target === void 0 ? void 0 : resolveMaybeRefOrGetter(mergedOptions.target)
58
+ };
59
+ }, ({ resolvedSequence, mergedOptions, resolvedEnabled, resolvedTarget }) => {
60
+ if (resolvedEnabled === false || resolvedSequence.length === 0) return;
61
+ const finalTarget = resolvedTarget ?? (typeof document !== "undefined" ? document : null);
62
+ if (!finalTarget) return;
63
+ if (registration?.isActive) {
64
+ registration.unregister();
65
+ registration = null;
66
+ }
67
+ const { target: _target, enabled: _enabled, ...restOptions } = mergedOptions;
68
+ const optionsWithoutTarget = {
69
+ ...restOptions,
70
+ ...resolvedEnabled === void 0 ? {} : { enabled: resolvedEnabled }
71
+ };
72
+ registration = manager.register(resolvedSequence, callback, {
73
+ ...optionsWithoutTarget,
74
+ target: finalTarget
75
+ });
76
+ if (registration.isActive) {
77
+ registration.callback = callback;
78
+ registration.setOptions(optionsWithoutTarget);
79
+ }
80
+ }, { immediate: true });
81
+ onUnmounted(() => {
82
+ stopWatcher();
83
+ if (registration?.isActive) {
84
+ registration.unregister();
85
+ registration = null;
86
+ }
87
+ });
88
+ }
89
+ function resolveMaybeRefOrGetter(value) {
90
+ return typeof value === "function" ? value() : unref(value);
91
+ }
92
+
93
+ //#endregion
94
+ export { useHotkeySequence };
95
+ //# sourceMappingURL=useHotkeySequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHotkeySequence.js","names":[],"sources":["../src/useHotkeySequence.ts"],"sourcesContent":["import { onUnmounted, unref, watch } from 'vue'\nimport { getSequenceManager } from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProviderContext'\nimport type { MaybeRefOrGetter } from 'vue'\nimport type {\n HotkeyCallback,\n HotkeySequence,\n SequenceOptions,\n SequenceRegistrationHandle,\n} from '@tanstack/hotkeys'\n\nexport interface UseHotkeySequenceOptions extends Omit<\n SequenceOptions,\n 'enabled' | 'target'\n> {\n /**\n * Whether the sequence is active.\n * Can be a Ref, a getter function, or a boolean value.\n * Defaults to true.\n */\n enabled?: MaybeRefOrGetter<boolean>\n /**\n * The DOM element to attach the event listener to.\n * Can be a Ref, a getter function, direct DOM element, or null.\n * Defaults to document.\n */\n target?: MaybeRefOrGetter<HTMLElement | Document | Window | null>\n}\n\n/**\n * Vue composable for registering a keyboard shortcut sequence (Vim-style).\n *\n * This composable allows you to register multi-key sequences like 'g g' or 'd d'\n * that trigger when the full sequence is pressed within a timeout.\n *\n * @param sequence - Array of hotkey strings that form the sequence\n * @param callback - Function to call when the sequence is completed\n * @param options - Options for the sequence behavior\n *\n * @example\n * ```vue\n * <script setup>\n * import { useHotkeySequence } from '@tanstack/vue-hotkeys'\n *\n * // 'g g' to go to top\n * useHotkeySequence(['G', 'G'], () => {\n * scrollToTop()\n * })\n *\n * // 'd d' to delete line\n * useHotkeySequence(['D', 'D'], () => {\n * deleteLine()\n * })\n *\n * // 'd i w' to delete inner word\n * useHotkeySequence(['D', 'I', 'W'], () => {\n * deleteInnerWord()\n * }, { timeout: 500 })\n * </script>\n *\n * <template>\n * <div>...</div>\n * </template>\n * ```\n */\nexport function useHotkeySequence(\n sequence: MaybeRefOrGetter<HotkeySequence>,\n callback: HotkeyCallback,\n options: MaybeRefOrGetter<UseHotkeySequenceOptions> = {},\n): void {\n const defaultOptions = useDefaultHotkeysOptions()\n const manager = getSequenceManager()\n\n let registration: SequenceRegistrationHandle | null = null\n\n // Watch for changes to reactive dependencies\n const stopWatcher = watch(\n () => {\n const resolvedSequence = resolveMaybeRefOrGetter(sequence)\n const resolvedOptions = resolveMaybeRefOrGetter(options)\n const mergedOptions = {\n ...defaultOptions.hotkeySequence,\n ...resolvedOptions,\n } as UseHotkeySequenceOptions\n const resolvedEnabled =\n mergedOptions.enabled === undefined\n ? undefined\n : resolveMaybeRefOrGetter(mergedOptions.enabled)\n const resolvedTarget =\n mergedOptions.target === undefined\n ? undefined\n : resolveMaybeRefOrGetter(mergedOptions.target)\n\n return {\n resolvedSequence,\n mergedOptions,\n resolvedEnabled,\n resolvedTarget,\n }\n },\n ({ resolvedSequence, mergedOptions, resolvedEnabled, resolvedTarget }) => {\n if (resolvedEnabled === false || resolvedSequence.length === 0) {\n return\n }\n\n // Resolve target\n const finalTarget =\n resolvedTarget ?? (typeof document !== 'undefined' ? document : null)\n\n if (!finalTarget) {\n return\n }\n\n // Unregister previous registration if it exists\n if (registration?.isActive) {\n registration.unregister()\n registration = null\n }\n\n // Extract options without target (target is handled separately)\n const {\n target: _target,\n enabled: _enabled,\n ...restOptions\n } = mergedOptions\n const optionsWithoutTarget = {\n ...restOptions,\n ...(resolvedEnabled === undefined ? {} : { enabled: resolvedEnabled }),\n }\n\n // Register the sequence\n registration = manager.register(resolvedSequence, callback, {\n ...optionsWithoutTarget,\n target: finalTarget,\n })\n\n // Update callback and options\n if (registration.isActive) {\n registration.callback = callback\n registration.setOptions(optionsWithoutTarget)\n }\n },\n { immediate: true },\n )\n\n // Cleanup on unmount\n onUnmounted(() => {\n stopWatcher()\n if (registration?.isActive) {\n registration.unregister()\n registration = null\n }\n })\n}\n\nfunction resolveMaybeRefOrGetter<T>(value: MaybeRefOrGetter<T>): T {\n return typeof value === 'function' ? (value as () => T)() : unref(value)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,SAAgB,kBACd,UACA,UACA,UAAsD,EAAE,EAClD;CACN,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,UAAU,oBAAoB;CAEpC,IAAI,eAAkD;CAGtD,MAAM,cAAc,YACZ;EACJ,MAAM,mBAAmB,wBAAwB,SAAS;EAC1D,MAAM,kBAAkB,wBAAwB,QAAQ;EACxD,MAAM,gBAAgB;GACpB,GAAG,eAAe;GAClB,GAAG;GACJ;AAUD,SAAO;GACL;GACA;GACA,iBAXA,cAAc,YAAY,SACtB,SACA,wBAAwB,cAAc,QAAQ;GAUlD,gBARA,cAAc,WAAW,SACrB,SACA,wBAAwB,cAAc,OAAO;GAOlD;KAEF,EAAE,kBAAkB,eAAe,iBAAiB,qBAAqB;AACxE,MAAI,oBAAoB,SAAS,iBAAiB,WAAW,EAC3D;EAIF,MAAM,cACJ,mBAAmB,OAAO,aAAa,cAAc,WAAW;AAElE,MAAI,CAAC,YACH;AAIF,MAAI,cAAc,UAAU;AAC1B,gBAAa,YAAY;AACzB,kBAAe;;EAIjB,MAAM,EACJ,QAAQ,SACR,SAAS,UACT,GAAG,gBACD;EACJ,MAAM,uBAAuB;GAC3B,GAAG;GACH,GAAI,oBAAoB,SAAY,EAAE,GAAG,EAAE,SAAS,iBAAiB;GACtE;AAGD,iBAAe,QAAQ,SAAS,kBAAkB,UAAU;GAC1D,GAAG;GACH,QAAQ;GACT,CAAC;AAGF,MAAI,aAAa,UAAU;AACzB,gBAAa,WAAW;AACxB,gBAAa,WAAW,qBAAqB;;IAGjD,EAAE,WAAW,MAAM,CACpB;AAGD,mBAAkB;AAChB,eAAa;AACb,MAAI,cAAc,UAAU;AAC1B,gBAAa,YAAY;AACzB,kBAAe;;GAEjB;;AAGJ,SAAS,wBAA2B,OAA+B;AACjE,QAAO,OAAO,UAAU,aAAc,OAAmB,GAAG,MAAM,MAAM"}
@@ -0,0 +1,60 @@
1
+ let _tanstack_hotkeys = require("@tanstack/hotkeys");
2
+ let vue = require("vue");
3
+ let _tanstack_vue_store = require("@tanstack/vue-store");
4
+
5
+ //#region src/useKeyHold.ts
6
+ /**
7
+ * Vue composable that returns a reactive ref indicating whether a specific key is currently being held.
8
+ *
9
+ * This composable uses `useStore` from `@tanstack/vue-store` to subscribe
10
+ * to the global KeyStateTracker and uses a selector to determine if
11
+ * the specified key is held.
12
+ *
13
+ * @param key - The key to check (e.g., 'Shift', 'Control', 'A')
14
+ * @returns Reactive ref that is true if the key is currently held down
15
+ *
16
+ * @example
17
+ * ```vue
18
+ * <script setup>
19
+ * import { useKeyHold } from '@tanstack/vue-hotkeys'
20
+ *
21
+ * const isShiftHeld = useKeyHold('Shift')
22
+ * <\/script>
23
+ *
24
+ * <template>
25
+ * <div :style="{ opacity: isShiftHeld ? 1 : 0.5 }">
26
+ * {{ isShiftHeld ? 'Shift is pressed!' : 'Press Shift' }}
27
+ * </div>
28
+ * </template>
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```vue
33
+ * <script setup>
34
+ * import { useKeyHold } from '@tanstack/vue-hotkeys'
35
+ *
36
+ * const ctrl = useKeyHold('Control')
37
+ * const shift = useKeyHold('Shift')
38
+ * const alt = useKeyHold('Alt')
39
+ * <\/script>
40
+ *
41
+ * <template>
42
+ * <div>
43
+ * <span :style="{ opacity: ctrl ? 1 : 0.3 }">Ctrl</span>
44
+ * <span :style="{ opacity: shift ? 1 : 0.3 }">Shift</span>
45
+ * <span :style="{ opacity: alt ? 1 : 0.3 }">Alt</span>
46
+ * </div>
47
+ * </template>
48
+ * ```
49
+ */
50
+ function useKeyHold(key) {
51
+ return (0, _tanstack_vue_store.useStore)((0, _tanstack_hotkeys.getKeyStateTracker)().store, (state) => {
52
+ const keyValue = (0, vue.unref)(key);
53
+ const normalizedKey = (typeof keyValue === "string" ? keyValue : String(keyValue)).toLowerCase();
54
+ return state.heldKeys.some((heldKey) => heldKey.toLowerCase() === normalizedKey);
55
+ });
56
+ }
57
+
58
+ //#endregion
59
+ exports.useKeyHold = useKeyHold;
60
+ //# sourceMappingURL=useKeyHold.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyHold.cjs","names":[],"sources":["../src/useKeyHold.ts"],"sourcesContent":["import { useStore } from '@tanstack/vue-store'\nimport { getKeyStateTracker } from '@tanstack/hotkeys'\nimport { unref } from 'vue'\nimport type { MaybeRefOrGetter, Ref } from 'vue'\nimport type { HeldKey } from '@tanstack/hotkeys'\n\n/**\n * Vue composable that returns a reactive ref indicating whether a specific key is currently being held.\n *\n * This composable uses `useStore` from `@tanstack/vue-store` to subscribe\n * to the global KeyStateTracker and uses a selector to determine if\n * the specified key is held.\n *\n * @param key - The key to check (e.g., 'Shift', 'Control', 'A')\n * @returns Reactive ref that is true if the key is currently held down\n *\n * @example\n * ```vue\n * <script setup>\n * import { useKeyHold } from '@tanstack/vue-hotkeys'\n *\n * const isShiftHeld = useKeyHold('Shift')\n * </script>\n *\n * <template>\n * <div :style=\"{ opacity: isShiftHeld ? 1 : 0.5 }\">\n * {{ isShiftHeld ? 'Shift is pressed!' : 'Press Shift' }}\n * </div>\n * </template>\n * ```\n *\n * @example\n * ```vue\n * <script setup>\n * import { useKeyHold } from '@tanstack/vue-hotkeys'\n *\n * const ctrl = useKeyHold('Control')\n * const shift = useKeyHold('Shift')\n * const alt = useKeyHold('Alt')\n * </script>\n *\n * <template>\n * <div>\n * <span :style=\"{ opacity: ctrl ? 1 : 0.3 }\">Ctrl</span>\n * <span :style=\"{ opacity: shift ? 1 : 0.3 }\">Shift</span>\n * <span :style=\"{ opacity: alt ? 1 : 0.3 }\">Alt</span>\n * </div>\n * </template>\n * ```\n */\nexport function useKeyHold(key: MaybeRefOrGetter<HeldKey>): Ref<boolean> {\n const tracker = getKeyStateTracker()\n\n const isHeld = useStore(tracker.store, (state) => {\n const keyValue = unref(key)\n const normalizedKey = (\n typeof keyValue === 'string' ? keyValue : String(keyValue)\n ).toLowerCase()\n return state.heldKeys.some(\n (heldKey) => heldKey.toLowerCase() === normalizedKey,\n )\n })\n\n return isHeld as Ref<boolean>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,WAAW,KAA8C;AAavE,qFAZoC,CAEJ,QAAQ,UAAU;EAChD,MAAM,0BAAiB,IAAI;EAC3B,MAAM,iBACJ,OAAO,aAAa,WAAW,WAAW,OAAO,SAAS,EAC1D,aAAa;AACf,SAAO,MAAM,SAAS,MACnB,YAAY,QAAQ,aAAa,KAAK,cACxC;GACD"}
@@ -0,0 +1,52 @@
1
+ import { HeldKey } from "@tanstack/hotkeys";
2
+ import { MaybeRefOrGetter, Ref } from "vue";
3
+
4
+ //#region src/useKeyHold.d.ts
5
+ /**
6
+ * Vue composable that returns a reactive ref indicating whether a specific key is currently being held.
7
+ *
8
+ * This composable uses `useStore` from `@tanstack/vue-store` to subscribe
9
+ * to the global KeyStateTracker and uses a selector to determine if
10
+ * the specified key is held.
11
+ *
12
+ * @param key - The key to check (e.g., 'Shift', 'Control', 'A')
13
+ * @returns Reactive ref that is true if the key is currently held down
14
+ *
15
+ * @example
16
+ * ```vue
17
+ * <script setup>
18
+ * import { useKeyHold } from '@tanstack/vue-hotkeys'
19
+ *
20
+ * const isShiftHeld = useKeyHold('Shift')
21
+ * </script>
22
+ *
23
+ * <template>
24
+ * <div :style="{ opacity: isShiftHeld ? 1 : 0.5 }">
25
+ * {{ isShiftHeld ? 'Shift is pressed!' : 'Press Shift' }}
26
+ * </div>
27
+ * </template>
28
+ * ```
29
+ *
30
+ * @example
31
+ * ```vue
32
+ * <script setup>
33
+ * import { useKeyHold } from '@tanstack/vue-hotkeys'
34
+ *
35
+ * const ctrl = useKeyHold('Control')
36
+ * const shift = useKeyHold('Shift')
37
+ * const alt = useKeyHold('Alt')
38
+ * </script>
39
+ *
40
+ * <template>
41
+ * <div>
42
+ * <span :style="{ opacity: ctrl ? 1 : 0.3 }">Ctrl</span>
43
+ * <span :style="{ opacity: shift ? 1 : 0.3 }">Shift</span>
44
+ * <span :style="{ opacity: alt ? 1 : 0.3 }">Alt</span>
45
+ * </div>
46
+ * </template>
47
+ * ```
48
+ */
49
+ declare function useKeyHold(key: MaybeRefOrGetter<HeldKey>): Ref<boolean>;
50
+ //#endregion
51
+ export { useKeyHold };
52
+ //# sourceMappingURL=useKeyHold.d.cts.map