@tanstack/preact-hotkeys 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/HotkeysProvider.d.ts +6 -13
  2. package/dist/HotkeysProvider.js +1 -2
  3. package/dist/useHeldKeyCodes.d.ts +2 -4
  4. package/dist/useHeldKeyCodes.js +3 -3
  5. package/dist/useHeldKeys.d.ts +2 -4
  6. package/dist/useHeldKeys.js +3 -3
  7. package/dist/useHotkey.d.ts +3 -6
  8. package/dist/useHotkey.js +3 -3
  9. package/dist/useHotkeyHint.d.ts +2 -5
  10. package/dist/useHotkeyHint.js +1 -2
  11. package/dist/useHotkeyRecorder.d.ts +3 -6
  12. package/dist/useHotkeyRecorder.js +1 -2
  13. package/dist/useHotkeyRegistrations.d.ts +3 -6
  14. package/dist/useHotkeyRegistrations.js +1 -2
  15. package/dist/useHotkeySequence.d.ts +3 -6
  16. package/dist/useHotkeySequence.js +1 -2
  17. package/dist/useHotkeySequenceRecorder.d.ts +3 -6
  18. package/dist/useHotkeySequenceRecorder.js +1 -2
  19. package/dist/useHotkeySequences.d.ts +3 -6
  20. package/dist/useHotkeySequences.js +1 -2
  21. package/dist/useHotkeys.d.ts +3 -6
  22. package/dist/useHotkeys.js +1 -2
  23. package/dist/useKeyHold.d.ts +2 -5
  24. package/dist/useKeyHold.js +1 -2
  25. package/dist/utils.js +1 -2
  26. package/package.json +11 -16
  27. package/dist/HotkeysProvider.cjs +0 -26
  28. package/dist/HotkeysProvider.cjs.map +0 -1
  29. package/dist/HotkeysProvider.d.cts +0 -29
  30. package/dist/HotkeysProvider.js.map +0 -1
  31. package/dist/index.cjs +0 -35
  32. package/dist/index.d.cts +0 -14
  33. package/dist/useHeldKeyCodes.cjs +0 -37
  34. package/dist/useHeldKeyCodes.cjs.map +0 -1
  35. package/dist/useHeldKeyCodes.d.cts +0 -31
  36. package/dist/useHeldKeyCodes.js.map +0 -1
  37. package/dist/useHeldKeys.cjs +0 -33
  38. package/dist/useHeldKeys.cjs.map +0 -1
  39. package/dist/useHeldKeys.d.cts +0 -27
  40. package/dist/useHeldKeys.js.map +0 -1
  41. package/dist/useHotkey.cjs +0 -125
  42. package/dist/useHotkey.cjs.map +0 -1
  43. package/dist/useHotkey.d.cts +0 -75
  44. package/dist/useHotkey.js.map +0 -1
  45. package/dist/useHotkeyHint.cjs +0 -18
  46. package/dist/useHotkeyHint.cjs.map +0 -1
  47. package/dist/useHotkeyHint.d.cts +0 -14
  48. package/dist/useHotkeyHint.js.map +0 -1
  49. package/dist/useHotkeyRecorder.cjs +0 -71
  50. package/dist/useHotkeyRecorder.cjs.map +0 -1
  51. package/dist/useHotkeyRecorder.d.cts +0 -57
  52. package/dist/useHotkeyRecorder.js.map +0 -1
  53. package/dist/useHotkeyRegistrations.cjs +0 -29
  54. package/dist/useHotkeyRegistrations.cjs.map +0 -1
  55. package/dist/useHotkeyRegistrations.d.cts +0 -26
  56. package/dist/useHotkeyRegistrations.js.map +0 -1
  57. package/dist/useHotkeySequence.cjs +0 -120
  58. package/dist/useHotkeySequence.cjs.map +0 -1
  59. package/dist/useHotkeySequence.d.cts +0 -59
  60. package/dist/useHotkeySequence.js.map +0 -1
  61. package/dist/useHotkeySequenceRecorder.cjs +0 -39
  62. package/dist/useHotkeySequenceRecorder.cjs.map +0 -1
  63. package/dist/useHotkeySequenceRecorder.d.cts +0 -19
  64. package/dist/useHotkeySequenceRecorder.js.map +0 -1
  65. package/dist/useHotkeySequences.cjs +0 -126
  66. package/dist/useHotkeySequences.cjs.map +0 -1
  67. package/dist/useHotkeySequences.d.cts +0 -63
  68. package/dist/useHotkeySequences.js.map +0 -1
  69. package/dist/useHotkeys.cjs +0 -124
  70. package/dist/useHotkeys.cjs.map +0 -1
  71. package/dist/useHotkeys.d.cts +0 -63
  72. package/dist/useHotkeys.js.map +0 -1
  73. package/dist/useKeyHold.cjs +0 -53
  74. package/dist/useKeyHold.cjs.map +0 -1
  75. package/dist/useKeyHold.d.cts +0 -47
  76. package/dist/useKeyHold.js.map +0 -1
  77. package/dist/utils.cjs +0 -12
  78. package/dist/utils.cjs.map +0 -1
  79. package/dist/utils.js.map +0 -1
  80. package/src/HotkeysProvider.tsx +0 -56
  81. package/src/index.ts +0 -18
  82. package/src/useHeldKeyCodes.ts +0 -33
  83. package/src/useHeldKeys.ts +0 -29
  84. package/src/useHotkey.ts +0 -191
  85. package/src/useHotkeyHint.ts +0 -19
  86. package/src/useHotkeyRecorder.ts +0 -101
  87. package/src/useHotkeyRegistrations.ts +0 -51
  88. package/src/useHotkeySequence.ts +0 -192
  89. package/src/useHotkeySequenceRecorder.ts +0 -64
  90. package/src/useHotkeySequences.ts +0 -192
  91. package/src/useHotkeys.ts +0 -193
  92. package/src/useKeyHold.ts +0 -52
  93. package/src/utils.ts +0 -8
@@ -1,33 +0,0 @@
1
- let _tanstack_hotkeys = require("@tanstack/hotkeys");
2
- let _tanstack_preact_store = require("@tanstack/preact-store");
3
-
4
- //#region src/useHeldKeys.ts
5
- /**
6
- * Preact hook that returns an array of currently held keyboard keys.
7
- *
8
- * This hook uses `useSelector` from `@tanstack/preact-store` to subscribe
9
- * to the global KeyStateTracker and updates whenever keys are pressed
10
- * or released.
11
- *
12
- * @returns Array of currently held key names
13
- *
14
- * @example
15
- * ```tsx
16
- * function KeyDisplay() {
17
- * const heldKeys = useHeldKeys()
18
- *
19
- * return (
20
- * <div>
21
- * Currently pressed: {heldKeys.join(' + ') || 'None'}
22
- * </div>
23
- * )
24
- * }
25
- * ```
26
- */
27
- function useHeldKeys() {
28
- return (0, _tanstack_preact_store.useSelector)((0, _tanstack_hotkeys.getKeyStateTracker)().store, (state) => state.heldKeys);
29
- }
30
-
31
- //#endregion
32
- exports.useHeldKeys = useHeldKeys;
33
- //# sourceMappingURL=useHeldKeys.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHeldKeys.cjs","names":[],"sources":["../src/useHeldKeys.ts"],"sourcesContent":["import { useSelector } from '@tanstack/preact-store'\nimport { getKeyStateTracker } from '@tanstack/hotkeys'\n\n/**\n * Preact hook that returns an array of currently held keyboard keys.\n *\n * This hook uses `useSelector` from `@tanstack/preact-store` to subscribe\n * to the global KeyStateTracker and updates whenever keys are pressed\n * or released.\n *\n * @returns Array of currently held key names\n *\n * @example\n * ```tsx\n * function KeyDisplay() {\n * const heldKeys = useHeldKeys()\n *\n * return (\n * <div>\n * Currently pressed: {heldKeys.join(' + ') || 'None'}\n * </div>\n * )\n * }\n * ```\n */\nexport function useHeldKeys(): Array<string> {\n const tracker = getKeyStateTracker()\n return useSelector(tracker.store, (state) => state.heldKeys)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,cAA6B;AAE3C,2FADoC,CACT,QAAQ,UAAU,MAAM,SAAS"}
@@ -1,27 +0,0 @@
1
- //#region src/useHeldKeys.d.ts
2
- /**
3
- * Preact hook that returns an array of currently held keyboard keys.
4
- *
5
- * This hook uses `useSelector` from `@tanstack/preact-store` to subscribe
6
- * to the global KeyStateTracker and updates whenever keys are pressed
7
- * or released.
8
- *
9
- * @returns Array of currently held key names
10
- *
11
- * @example
12
- * ```tsx
13
- * function KeyDisplay() {
14
- * const heldKeys = useHeldKeys()
15
- *
16
- * return (
17
- * <div>
18
- * Currently pressed: {heldKeys.join(' + ') || 'None'}
19
- * </div>
20
- * )
21
- * }
22
- * ```
23
- */
24
- declare function useHeldKeys(): Array<string>;
25
- //#endregion
26
- export { useHeldKeys };
27
- //# sourceMappingURL=useHeldKeys.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHeldKeys.js","names":[],"sources":["../src/useHeldKeys.ts"],"sourcesContent":["import { useSelector } from '@tanstack/preact-store'\nimport { getKeyStateTracker } from '@tanstack/hotkeys'\n\n/**\n * Preact hook that returns an array of currently held keyboard keys.\n *\n * This hook uses `useSelector` from `@tanstack/preact-store` to subscribe\n * to the global KeyStateTracker and updates whenever keys are pressed\n * or released.\n *\n * @returns Array of currently held key names\n *\n * @example\n * ```tsx\n * function KeyDisplay() {\n * const heldKeys = useHeldKeys()\n *\n * return (\n * <div>\n * Currently pressed: {heldKeys.join(' + ') || 'None'}\n * </div>\n * )\n * }\n * ```\n */\nexport function useHeldKeys(): Array<string> {\n const tracker = getKeyStateTracker()\n return useSelector(tracker.store, (state) => state.heldKeys)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,cAA6B;AAE3C,QAAO,YADS,oBAAoB,CACT,QAAQ,UAAU,MAAM,SAAS"}
@@ -1,125 +0,0 @@
1
- const require_HotkeysProvider = require('./HotkeysProvider.cjs');
2
- const require_utils = require('./utils.cjs');
3
- let _tanstack_hotkeys = require("@tanstack/hotkeys");
4
- let preact_hooks = require("preact/hooks");
5
-
6
- //#region src/useHotkey.ts
7
- /**
8
- * Preact hook for registering a keyboard hotkey.
9
- *
10
- * Uses the singleton HotkeyManager for efficient event handling.
11
- * The callback receives both the keyboard event and a context object
12
- * containing the hotkey string and parsed hotkey.
13
- *
14
- * This hook syncs the callback and options on every render to avoid
15
- * stale closures. This means
16
- * callbacks that reference Preact state will always have access to
17
- * the latest values.
18
- *
19
- * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)
20
- * @param callback - The function to call when the hotkey is pressed
21
- * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)
22
- * and only suppresses firing; the hook updates the existing handle instead of unregistering.
23
- *
24
- * @example
25
- * ```tsx
26
- * function SaveButton() {
27
- * const [count, setCount] = useState(0)
28
- *
29
- * // Callback always has access to latest count value
30
- * useHotkey('Mod+S', (event, { hotkey }) => {
31
- * console.log(`Save triggered, count is ${count}`)
32
- * handleSave()
33
- * })
34
- *
35
- * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
36
- * }
37
- * ```
38
- *
39
- * @example
40
- * ```tsx
41
- * function Modal({ isOpen, onClose }) {
42
- * // enabled option is synced on every render
43
- * useHotkey('Escape', () => {
44
- * onClose()
45
- * }, { enabled: isOpen })
46
- *
47
- * if (!isOpen) return null
48
- * return <div className="modal">...</div>
49
- * }
50
- * ```
51
- *
52
- * @example
53
- * ```tsx
54
- * function Editor() {
55
- * const editorRef = useRef<HTMLDivElement>(null)
56
- *
57
- * // Scoped to a specific element
58
- * useHotkey('Mod+S', () => {
59
- * save()
60
- * }, { target: editorRef })
61
- *
62
- * return <div ref={editorRef}>...</div>
63
- * }
64
- * ```
65
- */
66
- function useHotkey(hotkey, callback, options = {}) {
67
- const mergedOptions = {
68
- ...require_HotkeysProvider.useDefaultHotkeysOptions().hotkey,
69
- ...options
70
- };
71
- const manager = (0, _tanstack_hotkeys.getHotkeyManager)();
72
- const registrationRef = (0, preact_hooks.useRef)(null);
73
- const callbackRef = (0, preact_hooks.useRef)(callback);
74
- const optionsRef = (0, preact_hooks.useRef)(mergedOptions);
75
- const managerRef = (0, preact_hooks.useRef)(manager);
76
- callbackRef.current = callback;
77
- optionsRef.current = mergedOptions;
78
- managerRef.current = manager;
79
- const prevTargetRef = (0, preact_hooks.useRef)(null);
80
- const prevHotkeyRef = (0, preact_hooks.useRef)(null);
81
- const hotkeyString = (0, _tanstack_hotkeys.normalizeRegisterableHotkey)(hotkey, mergedOptions.platform ?? (0, _tanstack_hotkeys.detectPlatform)());
82
- const { target: _target, ...optionsWithoutTarget } = mergedOptions;
83
- (0, preact_hooks.useEffect)(() => {
84
- const resolvedTarget = require_utils.isRef(optionsRef.current.target) ? optionsRef.current.target.current : optionsRef.current.target ?? (typeof document !== "undefined" ? document : null);
85
- if (!resolvedTarget) {
86
- if (registrationRef.current?.isActive) {
87
- registrationRef.current.unregister();
88
- registrationRef.current = null;
89
- }
90
- prevTargetRef.current = null;
91
- prevHotkeyRef.current = null;
92
- return;
93
- }
94
- const targetChanged = prevTargetRef.current !== null && prevTargetRef.current !== resolvedTarget;
95
- const hotkeyChanged = prevHotkeyRef.current !== null && prevHotkeyRef.current !== hotkeyString;
96
- if (registrationRef.current?.isActive && (targetChanged || hotkeyChanged)) {
97
- registrationRef.current.unregister();
98
- registrationRef.current = null;
99
- }
100
- if (!registrationRef.current || !registrationRef.current.isActive) registrationRef.current = managerRef.current.register(hotkeyString, callbackRef.current, {
101
- ...optionsRef.current,
102
- target: resolvedTarget
103
- });
104
- prevTargetRef.current = resolvedTarget;
105
- prevHotkeyRef.current = hotkeyString;
106
- });
107
- (0, preact_hooks.useEffect)(() => {
108
- return () => {
109
- if (registrationRef.current?.isActive) {
110
- registrationRef.current.unregister();
111
- registrationRef.current = null;
112
- }
113
- };
114
- }, []);
115
- (0, preact_hooks.useEffect)(() => {
116
- if (registrationRef.current?.isActive) {
117
- registrationRef.current.callback = callback;
118
- registrationRef.current.setOptions(optionsWithoutTarget);
119
- }
120
- });
121
- }
122
-
123
- //#endregion
124
- exports.useHotkey = useHotkey;
125
- //# sourceMappingURL=useHotkey.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkey.cjs","names":["useDefaultHotkeysOptions","isRef"],"sources":["../src/useHotkey.ts"],"sourcesContent":["import { useEffect, useRef } from 'preact/hooks'\nimport {\n detectPlatform,\n getHotkeyManager,\n normalizeRegisterableHotkey,\n} from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProvider'\nimport { isRef } from './utils'\nimport type { RefObject } from 'preact'\nimport type {\n HotkeyCallback,\n HotkeyOptions,\n HotkeyRegistrationHandle,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\nexport interface UseHotkeyOptions extends Omit<HotkeyOptions, 'target'> {\n /**\n * The DOM element to attach the event listener to.\n * Can be a Preact ref, direct DOM element, or null.\n * Defaults to document.\n */\n target?:\n | RefObject<HTMLElement | null>\n | HTMLElement\n | Document\n | Window\n | null\n}\n\n/**\n * Preact hook for registering a keyboard hotkey.\n *\n * Uses the singleton HotkeyManager for efficient event handling.\n * The callback receives both the keyboard event and a context object\n * containing the hotkey string and parsed hotkey.\n *\n * This hook syncs the callback and options on every render to avoid\n * stale closures. This means\n * callbacks that reference Preact state will always have access to\n * the latest values.\n *\n * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)\n * @param callback - The function to call when the hotkey is pressed\n * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)\n * and only suppresses firing; the hook updates the existing handle instead of unregistering.\n *\n * @example\n * ```tsx\n * function SaveButton() {\n * const [count, setCount] = useState(0)\n *\n * // Callback always has access to latest count value\n * useHotkey('Mod+S', (event, { hotkey }) => {\n * console.log(`Save triggered, count is ${count}`)\n * handleSave()\n * })\n *\n * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>\n * }\n * ```\n *\n * @example\n * ```tsx\n * function Modal({ isOpen, onClose }) {\n * // enabled option is synced on every render\n * useHotkey('Escape', () => {\n * onClose()\n * }, { enabled: isOpen })\n *\n * if (!isOpen) return null\n * return <div className=\"modal\">...</div>\n * }\n * ```\n *\n * @example\n * ```tsx\n * function Editor() {\n * const editorRef = useRef<HTMLDivElement>(null)\n *\n * // Scoped to a specific element\n * useHotkey('Mod+S', () => {\n * save()\n * }, { target: editorRef })\n *\n * return <div ref={editorRef}>...</div>\n * }\n * ```\n */\nexport function useHotkey(\n hotkey: RegisterableHotkey,\n callback: HotkeyCallback,\n options: UseHotkeyOptions = {},\n): void {\n const mergedOptions = {\n ...useDefaultHotkeysOptions().hotkey,\n ...options,\n } as UseHotkeyOptions\n\n const manager = getHotkeyManager()\n\n // Stable ref for registration handle\n const registrationRef = useRef<HotkeyRegistrationHandle | null>(null)\n\n // Refs to capture current values for use in effect without adding dependencies\n const callbackRef = useRef(callback)\n const optionsRef = useRef(mergedOptions)\n const managerRef = useRef(manager)\n\n // Update refs on every render\n callbackRef.current = callback\n optionsRef.current = mergedOptions\n managerRef.current = manager\n\n // Track previous target and hotkey to detect changes requiring re-registration\n const prevTargetRef = useRef<HTMLElement | Document | Window | null>(null)\n const prevHotkeyRef = useRef<string | null>(null)\n\n // Normalize to hotkey string\n const platform = mergedOptions.platform ?? detectPlatform()\n const hotkeyString = normalizeRegisterableHotkey(hotkey, platform)\n\n // Extract options without target (target is handled separately)\n const { target: _target, ...optionsWithoutTarget } = mergedOptions\n\n useEffect(() => {\n // Resolve target inside the effect so refs are already attached after mount\n const resolvedTarget = isRef(optionsRef.current.target)\n ? optionsRef.current.target.current\n : (optionsRef.current.target ??\n (typeof document !== 'undefined' ? document : null))\n\n // Skip if no valid target (SSR or ref still null)\n if (!resolvedTarget) {\n if (registrationRef.current?.isActive) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n prevTargetRef.current = null\n prevHotkeyRef.current = null\n return\n }\n\n // Check if we need to re-register (target or hotkey changed)\n const targetChanged =\n prevTargetRef.current !== null && prevTargetRef.current !== resolvedTarget\n const hotkeyChanged =\n prevHotkeyRef.current !== null && prevHotkeyRef.current !== hotkeyString\n\n // If we have an active registration and target/hotkey changed, unregister first\n if (registrationRef.current?.isActive && (targetChanged || hotkeyChanged)) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n\n // Register if needed (no active registration)\n // Use refs to access current values without adding them to dependencies\n if (!registrationRef.current || !registrationRef.current.isActive) {\n registrationRef.current = managerRef.current.register(\n hotkeyString,\n callbackRef.current,\n {\n ...optionsRef.current,\n target: resolvedTarget,\n },\n )\n }\n\n // Update tracking refs\n prevTargetRef.current = resolvedTarget\n prevHotkeyRef.current = hotkeyString\n })\n\n useEffect(() => {\n // Cleanup on unmount\n return () => {\n if (registrationRef.current?.isActive) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n }\n }, [])\n\n // Publish option changes after commit, never during render.\n useEffect(() => {\n if (registrationRef.current?.isActive) {\n registrationRef.current.callback = callback\n registrationRef.current.setOptions(optionsWithoutTarget)\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFA,SAAgB,UACd,QACA,UACA,UAA4B,EAAE,EACxB;CACN,MAAM,gBAAgB;EACpB,GAAGA,kDAA0B,CAAC;EAC9B,GAAG;EACJ;CAED,MAAM,mDAA4B;CAGlC,MAAM,2CAA0D,KAAK;CAGrE,MAAM,uCAAqB,SAAS;CACpC,MAAM,sCAAoB,cAAc;CACxC,MAAM,sCAAoB,QAAQ;AAGlC,aAAY,UAAU;AACtB,YAAW,UAAU;AACrB,YAAW,UAAU;CAGrB,MAAM,yCAA+D,KAAK;CAC1E,MAAM,yCAAsC,KAAK;CAIjD,MAAM,kEAA2C,QADhC,cAAc,mDAA4B,CACO;CAGlE,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB;AAErD,mCAAgB;EAEd,MAAM,iBAAiBC,oBAAM,WAAW,QAAQ,OAAO,GACnD,WAAW,QAAQ,OAAO,UACzB,WAAW,QAAQ,WACnB,OAAO,aAAa,cAAc,WAAW;AAGlD,MAAI,CAAC,gBAAgB;AACnB,OAAI,gBAAgB,SAAS,UAAU;AACrC,oBAAgB,QAAQ,YAAY;AACpC,oBAAgB,UAAU;;AAE5B,iBAAc,UAAU;AACxB,iBAAc,UAAU;AACxB;;EAIF,MAAM,gBACJ,cAAc,YAAY,QAAQ,cAAc,YAAY;EAC9D,MAAM,gBACJ,cAAc,YAAY,QAAQ,cAAc,YAAY;AAG9D,MAAI,gBAAgB,SAAS,aAAa,iBAAiB,gBAAgB;AACzE,mBAAgB,QAAQ,YAAY;AACpC,mBAAgB,UAAU;;AAK5B,MAAI,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,QAAQ,SACvD,iBAAgB,UAAU,WAAW,QAAQ,SAC3C,cACA,YAAY,SACZ;GACE,GAAG,WAAW;GACd,QAAQ;GACT,CACF;AAIH,gBAAc,UAAU;AACxB,gBAAc,UAAU;GACxB;AAEF,mCAAgB;AAEd,eAAa;AACX,OAAI,gBAAgB,SAAS,UAAU;AACrC,oBAAgB,QAAQ,YAAY;AACpC,oBAAgB,UAAU;;;IAG7B,EAAE,CAAC;AAGN,mCAAgB;AACd,MAAI,gBAAgB,SAAS,UAAU;AACrC,mBAAgB,QAAQ,WAAW;AACnC,mBAAgB,QAAQ,WAAW,qBAAqB;;GAE1D"}
@@ -1,75 +0,0 @@
1
- import { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from "@tanstack/hotkeys";
2
- import { RefObject } from "preact";
3
-
4
- //#region src/useHotkey.d.ts
5
- interface UseHotkeyOptions extends Omit<HotkeyOptions, 'target'> {
6
- /**
7
- * The DOM element to attach the event listener to.
8
- * Can be a Preact ref, direct DOM element, or null.
9
- * Defaults to document.
10
- */
11
- target?: RefObject<HTMLElement | null> | HTMLElement | Document | Window | null;
12
- }
13
- /**
14
- * Preact hook for registering a keyboard hotkey.
15
- *
16
- * Uses the singleton HotkeyManager for efficient event handling.
17
- * The callback receives both the keyboard event and a context object
18
- * containing the hotkey string and parsed hotkey.
19
- *
20
- * This hook syncs the callback and options on every render to avoid
21
- * stale closures. This means
22
- * callbacks that reference Preact state will always have access to
23
- * the latest values.
24
- *
25
- * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)
26
- * @param callback - The function to call when the hotkey is pressed
27
- * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)
28
- * and only suppresses firing; the hook updates the existing handle instead of unregistering.
29
- *
30
- * @example
31
- * ```tsx
32
- * function SaveButton() {
33
- * const [count, setCount] = useState(0)
34
- *
35
- * // Callback always has access to latest count value
36
- * useHotkey('Mod+S', (event, { hotkey }) => {
37
- * console.log(`Save triggered, count is ${count}`)
38
- * handleSave()
39
- * })
40
- *
41
- * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
42
- * }
43
- * ```
44
- *
45
- * @example
46
- * ```tsx
47
- * function Modal({ isOpen, onClose }) {
48
- * // enabled option is synced on every render
49
- * useHotkey('Escape', () => {
50
- * onClose()
51
- * }, { enabled: isOpen })
52
- *
53
- * if (!isOpen) return null
54
- * return <div className="modal">...</div>
55
- * }
56
- * ```
57
- *
58
- * @example
59
- * ```tsx
60
- * function Editor() {
61
- * const editorRef = useRef<HTMLDivElement>(null)
62
- *
63
- * // Scoped to a specific element
64
- * useHotkey('Mod+S', () => {
65
- * save()
66
- * }, { target: editorRef })
67
- *
68
- * return <div ref={editorRef}>...</div>
69
- * }
70
- * ```
71
- */
72
- declare function useHotkey(hotkey: RegisterableHotkey, callback: HotkeyCallback, options?: UseHotkeyOptions): void;
73
- //#endregion
74
- export { UseHotkeyOptions, useHotkey };
75
- //# sourceMappingURL=useHotkey.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkey.js","names":[],"sources":["../src/useHotkey.ts"],"sourcesContent":["import { useEffect, useRef } from 'preact/hooks'\nimport {\n detectPlatform,\n getHotkeyManager,\n normalizeRegisterableHotkey,\n} from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProvider'\nimport { isRef } from './utils'\nimport type { RefObject } from 'preact'\nimport type {\n HotkeyCallback,\n HotkeyOptions,\n HotkeyRegistrationHandle,\n RegisterableHotkey,\n} from '@tanstack/hotkeys'\n\nexport interface UseHotkeyOptions extends Omit<HotkeyOptions, 'target'> {\n /**\n * The DOM element to attach the event listener to.\n * Can be a Preact ref, direct DOM element, or null.\n * Defaults to document.\n */\n target?:\n | RefObject<HTMLElement | null>\n | HTMLElement\n | Document\n | Window\n | null\n}\n\n/**\n * Preact hook for registering a keyboard hotkey.\n *\n * Uses the singleton HotkeyManager for efficient event handling.\n * The callback receives both the keyboard event and a context object\n * containing the hotkey string and parsed hotkey.\n *\n * This hook syncs the callback and options on every render to avoid\n * stale closures. This means\n * callbacks that reference Preact state will always have access to\n * the latest values.\n *\n * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)\n * @param callback - The function to call when the hotkey is pressed\n * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)\n * and only suppresses firing; the hook updates the existing handle instead of unregistering.\n *\n * @example\n * ```tsx\n * function SaveButton() {\n * const [count, setCount] = useState(0)\n *\n * // Callback always has access to latest count value\n * useHotkey('Mod+S', (event, { hotkey }) => {\n * console.log(`Save triggered, count is ${count}`)\n * handleSave()\n * })\n *\n * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>\n * }\n * ```\n *\n * @example\n * ```tsx\n * function Modal({ isOpen, onClose }) {\n * // enabled option is synced on every render\n * useHotkey('Escape', () => {\n * onClose()\n * }, { enabled: isOpen })\n *\n * if (!isOpen) return null\n * return <div className=\"modal\">...</div>\n * }\n * ```\n *\n * @example\n * ```tsx\n * function Editor() {\n * const editorRef = useRef<HTMLDivElement>(null)\n *\n * // Scoped to a specific element\n * useHotkey('Mod+S', () => {\n * save()\n * }, { target: editorRef })\n *\n * return <div ref={editorRef}>...</div>\n * }\n * ```\n */\nexport function useHotkey(\n hotkey: RegisterableHotkey,\n callback: HotkeyCallback,\n options: UseHotkeyOptions = {},\n): void {\n const mergedOptions = {\n ...useDefaultHotkeysOptions().hotkey,\n ...options,\n } as UseHotkeyOptions\n\n const manager = getHotkeyManager()\n\n // Stable ref for registration handle\n const registrationRef = useRef<HotkeyRegistrationHandle | null>(null)\n\n // Refs to capture current values for use in effect without adding dependencies\n const callbackRef = useRef(callback)\n const optionsRef = useRef(mergedOptions)\n const managerRef = useRef(manager)\n\n // Update refs on every render\n callbackRef.current = callback\n optionsRef.current = mergedOptions\n managerRef.current = manager\n\n // Track previous target and hotkey to detect changes requiring re-registration\n const prevTargetRef = useRef<HTMLElement | Document | Window | null>(null)\n const prevHotkeyRef = useRef<string | null>(null)\n\n // Normalize to hotkey string\n const platform = mergedOptions.platform ?? detectPlatform()\n const hotkeyString = normalizeRegisterableHotkey(hotkey, platform)\n\n // Extract options without target (target is handled separately)\n const { target: _target, ...optionsWithoutTarget } = mergedOptions\n\n useEffect(() => {\n // Resolve target inside the effect so refs are already attached after mount\n const resolvedTarget = isRef(optionsRef.current.target)\n ? optionsRef.current.target.current\n : (optionsRef.current.target ??\n (typeof document !== 'undefined' ? document : null))\n\n // Skip if no valid target (SSR or ref still null)\n if (!resolvedTarget) {\n if (registrationRef.current?.isActive) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n prevTargetRef.current = null\n prevHotkeyRef.current = null\n return\n }\n\n // Check if we need to re-register (target or hotkey changed)\n const targetChanged =\n prevTargetRef.current !== null && prevTargetRef.current !== resolvedTarget\n const hotkeyChanged =\n prevHotkeyRef.current !== null && prevHotkeyRef.current !== hotkeyString\n\n // If we have an active registration and target/hotkey changed, unregister first\n if (registrationRef.current?.isActive && (targetChanged || hotkeyChanged)) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n\n // Register if needed (no active registration)\n // Use refs to access current values without adding them to dependencies\n if (!registrationRef.current || !registrationRef.current.isActive) {\n registrationRef.current = managerRef.current.register(\n hotkeyString,\n callbackRef.current,\n {\n ...optionsRef.current,\n target: resolvedTarget,\n },\n )\n }\n\n // Update tracking refs\n prevTargetRef.current = resolvedTarget\n prevHotkeyRef.current = hotkeyString\n })\n\n useEffect(() => {\n // Cleanup on unmount\n return () => {\n if (registrationRef.current?.isActive) {\n registrationRef.current.unregister()\n registrationRef.current = null\n }\n }\n }, [])\n\n // Publish option changes after commit, never during render.\n useEffect(() => {\n if (registrationRef.current?.isActive) {\n registrationRef.current.callback = callback\n registrationRef.current.setOptions(optionsWithoutTarget)\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFA,SAAgB,UACd,QACA,UACA,UAA4B,EAAE,EACxB;CACN,MAAM,gBAAgB;EACpB,GAAG,0BAA0B,CAAC;EAC9B,GAAG;EACJ;CAED,MAAM,UAAU,kBAAkB;CAGlC,MAAM,kBAAkB,OAAwC,KAAK;CAGrE,MAAM,cAAc,OAAO,SAAS;CACpC,MAAM,aAAa,OAAO,cAAc;CACxC,MAAM,aAAa,OAAO,QAAQ;AAGlC,aAAY,UAAU;AACtB,YAAW,UAAU;AACrB,YAAW,UAAU;CAGrB,MAAM,gBAAgB,OAA+C,KAAK;CAC1E,MAAM,gBAAgB,OAAsB,KAAK;CAIjD,MAAM,eAAe,4BAA4B,QADhC,cAAc,YAAY,gBAAgB,CACO;CAGlE,MAAM,EAAE,QAAQ,SAAS,GAAG,yBAAyB;AAErD,iBAAgB;EAEd,MAAM,iBAAiB,MAAM,WAAW,QAAQ,OAAO,GACnD,WAAW,QAAQ,OAAO,UACzB,WAAW,QAAQ,WACnB,OAAO,aAAa,cAAc,WAAW;AAGlD,MAAI,CAAC,gBAAgB;AACnB,OAAI,gBAAgB,SAAS,UAAU;AACrC,oBAAgB,QAAQ,YAAY;AACpC,oBAAgB,UAAU;;AAE5B,iBAAc,UAAU;AACxB,iBAAc,UAAU;AACxB;;EAIF,MAAM,gBACJ,cAAc,YAAY,QAAQ,cAAc,YAAY;EAC9D,MAAM,gBACJ,cAAc,YAAY,QAAQ,cAAc,YAAY;AAG9D,MAAI,gBAAgB,SAAS,aAAa,iBAAiB,gBAAgB;AACzE,mBAAgB,QAAQ,YAAY;AACpC,mBAAgB,UAAU;;AAK5B,MAAI,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,QAAQ,SACvD,iBAAgB,UAAU,WAAW,QAAQ,SAC3C,cACA,YAAY,SACZ;GACE,GAAG,WAAW;GACd,QAAQ;GACT,CACF;AAIH,gBAAc,UAAU;AACxB,gBAAc,UAAU;GACxB;AAEF,iBAAgB;AAEd,eAAa;AACX,OAAI,gBAAgB,SAAS,UAAU;AACrC,oBAAgB,QAAQ,YAAY;AACpC,oBAAgB,UAAU;;;IAG7B,EAAE,CAAC;AAGN,iBAAgB;AACd,MAAI,gBAAgB,SAAS,UAAU;AACrC,mBAAgB,QAAQ,WAAW;AACnC,mBAAgB,QAAQ,WAAW,qBAAqB;;GAE1D"}
@@ -1,18 +0,0 @@
1
- let _tanstack_hotkeys = require("@tanstack/hotkeys");
2
- let _tanstack_preact_store = require("@tanstack/preact-store");
3
-
4
- //#region src/useHotkeyHint.ts
5
- /**
6
- * Returns a boolean indicating whether held modifiers reveal this shortcut.
7
- * Only visibility changes from held-key updates cause a rerender.
8
- * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires
9
- * every modifier. Combine with the action's enabled state before showing a badge.
10
- * This helper does not register a shortcut or check whether its target is focused.
11
- */
12
- function useHotkeyHint(hotkey, options = {}) {
13
- return (0, _tanstack_preact_store.useSelector)((0, _tanstack_hotkeys.getKeyStateTracker)().store, (state) => (0, _tanstack_hotkeys.matchesHeldModifiers)(hotkey, state.heldKeys, options));
14
- }
15
-
16
- //#endregion
17
- exports.useHotkeyHint = useHotkeyHint;
18
- //# sourceMappingURL=useHotkeyHint.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyHint.cjs","names":[],"sources":["../src/useHotkeyHint.ts"],"sourcesContent":["import { useSelector } from '@tanstack/preact-store'\nimport { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/hotkeys'\nimport type { HeldModifierOptions, RegisterableHotkey } from '@tanstack/hotkeys'\n\n/**\n * Returns a boolean indicating whether held modifiers reveal this shortcut.\n * Only visibility changes from held-key updates cause a rerender.\n * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires\n * every modifier. Combine with the action's enabled state before showing a badge.\n * This helper does not register a shortcut or check whether its target is focused.\n */\nexport function useHotkeyHint(\n hotkey: RegisterableHotkey,\n options: HeldModifierOptions = {},\n): boolean {\n return useSelector(getKeyStateTracker().store, (state) =>\n matchesHeldModifiers(hotkey, state.heldKeys, options),\n )\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,cACd,QACA,UAA+B,EAAE,EACxB;AACT,2FAAuC,CAAC,QAAQ,sDACzB,QAAQ,MAAM,UAAU,QAAQ,CACtD"}
@@ -1,14 +0,0 @@
1
- import { HeldModifierOptions, RegisterableHotkey } from "@tanstack/hotkeys";
2
-
3
- //#region src/useHotkeyHint.d.ts
4
- /**
5
- * Returns a boolean indicating whether held modifiers reveal this shortcut.
6
- * Only visibility changes from held-key updates cause a rerender.
7
- * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires
8
- * every modifier. Combine with the action's enabled state before showing a badge.
9
- * This helper does not register a shortcut or check whether its target is focused.
10
- */
11
- declare function useHotkeyHint(hotkey: RegisterableHotkey, options?: HeldModifierOptions): boolean;
12
- //#endregion
13
- export { useHotkeyHint };
14
- //# sourceMappingURL=useHotkeyHint.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyHint.js","names":[],"sources":["../src/useHotkeyHint.ts"],"sourcesContent":["import { useSelector } from '@tanstack/preact-store'\nimport { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/hotkeys'\nimport type { HeldModifierOptions, RegisterableHotkey } from '@tanstack/hotkeys'\n\n/**\n * Returns a boolean indicating whether held modifiers reveal this shortcut.\n * Only visibility changes from held-key updates cause a rerender.\n * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires\n * every modifier. Combine with the action's enabled state before showing a badge.\n * This helper does not register a shortcut or check whether its target is focused.\n */\nexport function useHotkeyHint(\n hotkey: RegisterableHotkey,\n options: HeldModifierOptions = {},\n): boolean {\n return useSelector(getKeyStateTracker().store, (state) =>\n matchesHeldModifiers(hotkey, state.heldKeys, options),\n )\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,cACd,QACA,UAA+B,EAAE,EACxB;AACT,QAAO,YAAY,oBAAoB,CAAC,QAAQ,UAC9C,qBAAqB,QAAQ,MAAM,UAAU,QAAQ,CACtD"}
@@ -1,71 +0,0 @@
1
- const require_HotkeysProvider = require('./HotkeysProvider.cjs');
2
- let _tanstack_hotkeys = require("@tanstack/hotkeys");
3
- let preact_hooks = require("preact/hooks");
4
- let _tanstack_preact_store = require("@tanstack/preact-store");
5
-
6
- //#region src/useHotkeyRecorder.ts
7
- /**
8
- * Preact hook for recording keyboard shortcuts.
9
- *
10
- * This hook 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
- * ```tsx
20
- * function ShortcutSettings() {
21
- * const [shortcut, setShortcut] = useState<Hotkey>('Mod+S')
22
- *
23
- * const recorder = useHotkeyRecorder({
24
- * onRecord: (hotkey) => {
25
- * setShortcut(hotkey)
26
- * },
27
- * onCancel: () => {
28
- * console.log('Recording cancelled')
29
- * },
30
- * })
31
- *
32
- * return (
33
- * <div>
34
- * <button onClick={recorder.startRecording}>
35
- * {recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}
36
- * </button>
37
- * {recorder.recordedHotkey && (
38
- * <div>Recording: {recorder.recordedHotkey}</div>
39
- * )}
40
- * </div>
41
- * )
42
- * }
43
- * ```
44
- */
45
- function useHotkeyRecorder(options) {
46
- const mergedOptions = {
47
- ...require_HotkeysProvider.useDefaultHotkeysOptions().hotkeyRecorder,
48
- ...options
49
- };
50
- const recorderRef = (0, preact_hooks.useRef)(null);
51
- if (!recorderRef.current) recorderRef.current = new _tanstack_hotkeys.HotkeyRecorder(mergedOptions);
52
- recorderRef.current.setOptions(mergedOptions);
53
- const isRecording = (0, _tanstack_preact_store.useSelector)(recorderRef.current.store, (state) => state.isRecording);
54
- const recordedHotkey = (0, _tanstack_preact_store.useSelector)(recorderRef.current.store, (state) => state.recordedHotkey);
55
- (0, preact_hooks.useEffect)(() => {
56
- return () => {
57
- recorderRef.current?.destroy();
58
- };
59
- }, []);
60
- return {
61
- isRecording,
62
- recordedHotkey,
63
- startRecording: () => recorderRef.current?.start(),
64
- stopRecording: () => recorderRef.current?.stop(),
65
- cancelRecording: () => recorderRef.current?.cancel()
66
- };
67
- }
68
-
69
- //#endregion
70
- exports.useHotkeyRecorder = useHotkeyRecorder;
71
- //# sourceMappingURL=useHotkeyRecorder.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyRecorder.cjs","names":["useDefaultHotkeysOptions","HotkeyRecorder"],"sources":["../src/useHotkeyRecorder.ts"],"sourcesContent":["import { useEffect, useRef } from 'preact/hooks'\nimport { useSelector } from '@tanstack/preact-store'\nimport { HotkeyRecorder } from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProvider'\nimport type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'\n\nexport interface PreactHotkeyRecorder {\n /** Whether recording is currently active */\n isRecording: boolean\n /** The currently recorded hotkey (for live preview) */\n recordedHotkey: 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 * Preact hook for recording keyboard shortcuts.\n *\n * This hook 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 * ```tsx\n * function ShortcutSettings() {\n * const [shortcut, setShortcut] = useState<Hotkey>('Mod+S')\n *\n * const recorder = useHotkeyRecorder({\n * onRecord: (hotkey) => {\n * setShortcut(hotkey)\n * },\n * onCancel: () => {\n * console.log('Recording cancelled')\n * },\n * })\n *\n * return (\n * <div>\n * <button onClick={recorder.startRecording}>\n * {recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}\n * </button>\n * {recorder.recordedHotkey && (\n * <div>Recording: {recorder.recordedHotkey}</div>\n * )}\n * </div>\n * )\n * }\n * ```\n */\nexport function useHotkeyRecorder(\n options: HotkeyRecorderOptions,\n): PreactHotkeyRecorder {\n const mergedOptions = {\n ...useDefaultHotkeysOptions().hotkeyRecorder,\n ...options,\n } as HotkeyRecorderOptions\n\n const recorderRef = useRef<HotkeyRecorder | null>(null)\n\n // Create recorder instance once\n if (!recorderRef.current) {\n recorderRef.current = new HotkeyRecorder(mergedOptions)\n }\n\n // Sync options on every render (same pattern as useHotkey)\n // This ensures callbacks always have access to latest values\n recorderRef.current.setOptions(mergedOptions)\n\n // Subscribe to recorder state using useSelector (same pattern as useHeldKeys)\n const isRecording = useSelector(\n recorderRef.current.store,\n (state) => state.isRecording,\n )\n const recordedHotkey = useSelector(\n recorderRef.current.store,\n (state) => state.recordedHotkey,\n )\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n recorderRef.current?.destroy()\n }\n }, [])\n\n return {\n isRecording,\n recordedHotkey,\n startRecording: () => recorderRef.current?.start(),\n stopRecording: () => recorderRef.current?.stop(),\n cancelRecording: () => recorderRef.current?.cancel(),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,kBACd,SACsB;CACtB,MAAM,gBAAgB;EACpB,GAAGA,kDAA0B,CAAC;EAC9B,GAAG;EACJ;CAED,MAAM,uCAA4C,KAAK;AAGvD,KAAI,CAAC,YAAY,QACf,aAAY,UAAU,IAAIC,iCAAe,cAAc;AAKzD,aAAY,QAAQ,WAAW,cAAc;CAG7C,MAAM,sDACJ,YAAY,QAAQ,QACnB,UAAU,MAAM,YAClB;CACD,MAAM,yDACJ,YAAY,QAAQ,QACnB,UAAU,MAAM,eAClB;AAGD,mCAAgB;AACd,eAAa;AACX,eAAY,SAAS,SAAS;;IAE/B,EAAE,CAAC;AAEN,QAAO;EACL;EACA;EACA,sBAAsB,YAAY,SAAS,OAAO;EAClD,qBAAqB,YAAY,SAAS,MAAM;EAChD,uBAAuB,YAAY,SAAS,QAAQ;EACrD"}
@@ -1,57 +0,0 @@
1
- import { Hotkey, HotkeyRecorderOptions } from "@tanstack/hotkeys";
2
-
3
- //#region src/useHotkeyRecorder.d.ts
4
- interface PreactHotkeyRecorder {
5
- /** Whether recording is currently active */
6
- isRecording: boolean;
7
- /** The currently recorded hotkey (for live preview) */
8
- recordedHotkey: Hotkey | null;
9
- /** Start recording a new hotkey */
10
- startRecording: () => void;
11
- /** Stop recording (same as cancel) */
12
- stopRecording: () => void;
13
- /** Cancel recording without saving */
14
- cancelRecording: () => void;
15
- }
16
- /**
17
- * Preact hook for recording keyboard shortcuts.
18
- *
19
- * This hook provides a thin wrapper around the framework-agnostic `HotkeyRecorder`
20
- * class, managing all the complexity of capturing keyboard events, converting them
21
- * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete
22
- * to clear.
23
- *
24
- * @param options - Configuration options for the recorder
25
- * @returns An object with recording state and control functions
26
- *
27
- * @example
28
- * ```tsx
29
- * function ShortcutSettings() {
30
- * const [shortcut, setShortcut] = useState<Hotkey>('Mod+S')
31
- *
32
- * const recorder = useHotkeyRecorder({
33
- * onRecord: (hotkey) => {
34
- * setShortcut(hotkey)
35
- * },
36
- * onCancel: () => {
37
- * console.log('Recording cancelled')
38
- * },
39
- * })
40
- *
41
- * return (
42
- * <div>
43
- * <button onClick={recorder.startRecording}>
44
- * {recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}
45
- * </button>
46
- * {recorder.recordedHotkey && (
47
- * <div>Recording: {recorder.recordedHotkey}</div>
48
- * )}
49
- * </div>
50
- * )
51
- * }
52
- * ```
53
- */
54
- declare function useHotkeyRecorder(options: HotkeyRecorderOptions): PreactHotkeyRecorder;
55
- //#endregion
56
- export { PreactHotkeyRecorder, useHotkeyRecorder };
57
- //# sourceMappingURL=useHotkeyRecorder.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyRecorder.js","names":[],"sources":["../src/useHotkeyRecorder.ts"],"sourcesContent":["import { useEffect, useRef } from 'preact/hooks'\nimport { useSelector } from '@tanstack/preact-store'\nimport { HotkeyRecorder } from '@tanstack/hotkeys'\nimport { useDefaultHotkeysOptions } from './HotkeysProvider'\nimport type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys'\n\nexport interface PreactHotkeyRecorder {\n /** Whether recording is currently active */\n isRecording: boolean\n /** The currently recorded hotkey (for live preview) */\n recordedHotkey: 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 * Preact hook for recording keyboard shortcuts.\n *\n * This hook 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 * ```tsx\n * function ShortcutSettings() {\n * const [shortcut, setShortcut] = useState<Hotkey>('Mod+S')\n *\n * const recorder = useHotkeyRecorder({\n * onRecord: (hotkey) => {\n * setShortcut(hotkey)\n * },\n * onCancel: () => {\n * console.log('Recording cancelled')\n * },\n * })\n *\n * return (\n * <div>\n * <button onClick={recorder.startRecording}>\n * {recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}\n * </button>\n * {recorder.recordedHotkey && (\n * <div>Recording: {recorder.recordedHotkey}</div>\n * )}\n * </div>\n * )\n * }\n * ```\n */\nexport function useHotkeyRecorder(\n options: HotkeyRecorderOptions,\n): PreactHotkeyRecorder {\n const mergedOptions = {\n ...useDefaultHotkeysOptions().hotkeyRecorder,\n ...options,\n } as HotkeyRecorderOptions\n\n const recorderRef = useRef<HotkeyRecorder | null>(null)\n\n // Create recorder instance once\n if (!recorderRef.current) {\n recorderRef.current = new HotkeyRecorder(mergedOptions)\n }\n\n // Sync options on every render (same pattern as useHotkey)\n // This ensures callbacks always have access to latest values\n recorderRef.current.setOptions(mergedOptions)\n\n // Subscribe to recorder state using useSelector (same pattern as useHeldKeys)\n const isRecording = useSelector(\n recorderRef.current.store,\n (state) => state.isRecording,\n )\n const recordedHotkey = useSelector(\n recorderRef.current.store,\n (state) => state.recordedHotkey,\n )\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n recorderRef.current?.destroy()\n }\n }, [])\n\n return {\n isRecording,\n recordedHotkey,\n startRecording: () => recorderRef.current?.start(),\n stopRecording: () => recorderRef.current?.stop(),\n cancelRecording: () => recorderRef.current?.cancel(),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,kBACd,SACsB;CACtB,MAAM,gBAAgB;EACpB,GAAG,0BAA0B,CAAC;EAC9B,GAAG;EACJ;CAED,MAAM,cAAc,OAA8B,KAAK;AAGvD,KAAI,CAAC,YAAY,QACf,aAAY,UAAU,IAAI,eAAe,cAAc;AAKzD,aAAY,QAAQ,WAAW,cAAc;CAG7C,MAAM,cAAc,YAClB,YAAY,QAAQ,QACnB,UAAU,MAAM,YAClB;CACD,MAAM,iBAAiB,YACrB,YAAY,QAAQ,QACnB,UAAU,MAAM,eAClB;AAGD,iBAAgB;AACd,eAAa;AACX,eAAY,SAAS,SAAS;;IAE/B,EAAE,CAAC;AAEN,QAAO;EACL;EACA;EACA,sBAAsB,YAAY,SAAS,OAAO;EAClD,qBAAqB,YAAY,SAAS,MAAM;EAChD,uBAAuB,YAAY,SAAS,QAAQ;EACrD"}
@@ -1,29 +0,0 @@
1
- let _tanstack_hotkeys = require("@tanstack/hotkeys");
2
- let preact_hooks = require("preact/hooks");
3
- let _tanstack_preact_store = require("@tanstack/preact-store");
4
-
5
- //#region src/useHotkeyRegistrations.ts
6
- /**
7
- * Preact hook that reactively reads all hotkey and sequence registrations
8
- * from the singleton managers.
9
- *
10
- * This is a standalone hook that does NOT require the HotkeysProvider.
11
- * It subscribes to both HotkeyManager and SequenceManager stores and
12
- * re-renders when registrations change.
13
- *
14
- * @returns Object with `hotkeys` and `sequences` arrays
15
- */
16
- function useHotkeyRegistrations() {
17
- const hotkeyManager = (0, _tanstack_hotkeys.getHotkeyManager)();
18
- const sequenceManager = (0, _tanstack_hotkeys.getSequenceManager)();
19
- const hotkeyState = (0, _tanstack_preact_store.useSelector)(hotkeyManager.registrations);
20
- const sequenceState = (0, _tanstack_preact_store.useSelector)(sequenceManager.registrations);
21
- return {
22
- hotkeys: (0, preact_hooks.useMemo)(() => Array.from(hotkeyState.values()).map(_tanstack_hotkeys.toHotkeyRegistrationView), [hotkeyState]),
23
- sequences: (0, preact_hooks.useMemo)(() => Array.from(sequenceState.values()), [sequenceState])
24
- };
25
- }
26
-
27
- //#endregion
28
- exports.useHotkeyRegistrations = useHotkeyRegistrations;
29
- //# sourceMappingURL=useHotkeyRegistrations.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyRegistrations.cjs","names":["toHotkeyRegistrationView"],"sources":["../src/useHotkeyRegistrations.ts"],"sourcesContent":["import { useMemo } from 'preact/hooks'\nimport { useSelector } from '@tanstack/preact-store'\nimport {\n getHotkeyManager,\n getSequenceManager,\n toHotkeyRegistrationView,\n} from '@tanstack/hotkeys'\nimport type {\n HotkeyRegistrationView,\n SequenceRegistrationView,\n} from '@tanstack/hotkeys'\n\n/**\n * Return type for useHotkeyRegistrations.\n */\nexport interface HotkeyRegistrationsResult {\n /** All registered hotkeys (public view, no callbacks) */\n hotkeys: Array<HotkeyRegistrationView>\n /** All registered sequences */\n sequences: Array<SequenceRegistrationView>\n}\n\n/**\n * Preact hook that reactively reads all hotkey and sequence registrations\n * from the singleton managers.\n *\n * This is a standalone hook that does NOT require the HotkeysProvider.\n * It subscribes to both HotkeyManager and SequenceManager stores and\n * re-renders when registrations change.\n *\n * @returns Object with `hotkeys` and `sequences` arrays\n */\nexport function useHotkeyRegistrations(): HotkeyRegistrationsResult {\n const hotkeyManager = getHotkeyManager()\n const sequenceManager = getSequenceManager()\n\n // Select stable store snapshots before deriving arrays; fresh selector arrays\n // make Preact's external-store subscription render continuously.\n const hotkeyState = useSelector(hotkeyManager.registrations)\n const sequenceState = useSelector(sequenceManager.registrations)\n const hotkeys = useMemo(\n () => Array.from(hotkeyState.values()).map(toHotkeyRegistrationView),\n [hotkeyState],\n )\n const sequences = useMemo(\n () => Array.from(sequenceState.values()),\n [sequenceState],\n )\n\n return { hotkeys, sequences }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,SAAgB,yBAAoD;CAClE,MAAM,yDAAkC;CACxC,MAAM,6DAAsC;CAI5C,MAAM,sDAA0B,cAAc,cAAc;CAC5D,MAAM,wDAA4B,gBAAgB,cAAc;AAUhE,QAAO;EAAE,yCARD,MAAM,KAAK,YAAY,QAAQ,CAAC,CAAC,IAAIA,2CAAyB,EACpE,CAAC,YAAY,CACd;EAMiB,2CAJV,MAAM,KAAK,cAAc,QAAQ,CAAC,EACxC,CAAC,cAAc,CAChB;EAE4B"}
@@ -1,26 +0,0 @@
1
- import { HotkeyRegistrationView, SequenceRegistrationView } from "@tanstack/hotkeys";
2
-
3
- //#region src/useHotkeyRegistrations.d.ts
4
- /**
5
- * Return type for useHotkeyRegistrations.
6
- */
7
- interface HotkeyRegistrationsResult {
8
- /** All registered hotkeys (public view, no callbacks) */
9
- hotkeys: Array<HotkeyRegistrationView>;
10
- /** All registered sequences */
11
- sequences: Array<SequenceRegistrationView>;
12
- }
13
- /**
14
- * Preact hook that reactively reads all hotkey and sequence registrations
15
- * from the singleton managers.
16
- *
17
- * This is a standalone hook that does NOT require the HotkeysProvider.
18
- * It subscribes to both HotkeyManager and SequenceManager stores and
19
- * re-renders when registrations change.
20
- *
21
- * @returns Object with `hotkeys` and `sequences` arrays
22
- */
23
- declare function useHotkeyRegistrations(): HotkeyRegistrationsResult;
24
- //#endregion
25
- export { HotkeyRegistrationsResult, useHotkeyRegistrations };
26
- //# sourceMappingURL=useHotkeyRegistrations.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHotkeyRegistrations.js","names":[],"sources":["../src/useHotkeyRegistrations.ts"],"sourcesContent":["import { useMemo } from 'preact/hooks'\nimport { useSelector } from '@tanstack/preact-store'\nimport {\n getHotkeyManager,\n getSequenceManager,\n toHotkeyRegistrationView,\n} from '@tanstack/hotkeys'\nimport type {\n HotkeyRegistrationView,\n SequenceRegistrationView,\n} from '@tanstack/hotkeys'\n\n/**\n * Return type for useHotkeyRegistrations.\n */\nexport interface HotkeyRegistrationsResult {\n /** All registered hotkeys (public view, no callbacks) */\n hotkeys: Array<HotkeyRegistrationView>\n /** All registered sequences */\n sequences: Array<SequenceRegistrationView>\n}\n\n/**\n * Preact hook that reactively reads all hotkey and sequence registrations\n * from the singleton managers.\n *\n * This is a standalone hook that does NOT require the HotkeysProvider.\n * It subscribes to both HotkeyManager and SequenceManager stores and\n * re-renders when registrations change.\n *\n * @returns Object with `hotkeys` and `sequences` arrays\n */\nexport function useHotkeyRegistrations(): HotkeyRegistrationsResult {\n const hotkeyManager = getHotkeyManager()\n const sequenceManager = getSequenceManager()\n\n // Select stable store snapshots before deriving arrays; fresh selector arrays\n // make Preact's external-store subscription render continuously.\n const hotkeyState = useSelector(hotkeyManager.registrations)\n const sequenceState = useSelector(sequenceManager.registrations)\n const hotkeys = useMemo(\n () => Array.from(hotkeyState.values()).map(toHotkeyRegistrationView),\n [hotkeyState],\n )\n const sequences = useMemo(\n () => Array.from(sequenceState.values()),\n [sequenceState],\n )\n\n return { hotkeys, sequences }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgCA,SAAgB,yBAAoD;CAClE,MAAM,gBAAgB,kBAAkB;CACxC,MAAM,kBAAkB,oBAAoB;CAI5C,MAAM,cAAc,YAAY,cAAc,cAAc;CAC5D,MAAM,gBAAgB,YAAY,gBAAgB,cAAc;AAUhE,QAAO;EAAE,SATO,cACR,MAAM,KAAK,YAAY,QAAQ,CAAC,CAAC,IAAI,yBAAyB,EACpE,CAAC,YAAY,CACd;EAMiB,WALA,cACV,MAAM,KAAK,cAAc,QAAQ,CAAC,EACxC,CAAC,cAAc,CAChB;EAE4B"}