@tanstack/svelte-hotkeys 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,19 @@
1
1
  <div align="center">
2
- <img src="./media/header_hotkeys.png" alt="TanStack Hotkeys" />
2
+ <picture>
3
+ <source
4
+ media="(prefers-color-scheme: dark)"
5
+ srcset="https://tanstack.com/api/readme/hotkeys.png?theme=dark"
6
+ />
7
+ <source
8
+ media="(prefers-color-scheme: light)"
9
+ srcset="https://tanstack.com/api/readme/hotkeys.png"
10
+ />
11
+ <img
12
+ src="https://tanstack.com/api/readme/hotkeys.png"
13
+ alt="TanStack Hotkeys"
14
+ width="900"
15
+ />
16
+ </picture>
3
17
  </div>
4
18
 
5
19
  <br />
@@ -54,6 +54,18 @@ class SvelteHotkeyRecorderState {
54
54
  constructor(options) {
55
55
  _SvelteHotkeyRecorderState_recorder.set(this, void 0);
56
56
  _SvelteHotkeyRecorderState_subscribe.set(this, void 0);
57
+ // Keep the recorder receiver when used directly as an event handler.
58
+ this.startRecording = () => {
59
+ __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").start();
60
+ };
61
+ // Keep the recorder receiver when used directly as an event handler.
62
+ this.stopRecording = () => {
63
+ __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").stop();
64
+ };
65
+ // Keep the recorder receiver when used directly as an event handler.
66
+ this.cancelRecording = () => {
67
+ __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").cancel();
68
+ };
57
69
  __classPrivateFieldSet(this, _SvelteHotkeyRecorderState_recorder, new HotkeyRecorder(options), "f");
58
70
  __classPrivateFieldSet(this, _SvelteHotkeyRecorderState_subscribe, createStoreSubscriber(__classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").store), "f");
59
71
  }
@@ -68,15 +80,6 @@ class SvelteHotkeyRecorderState {
68
80
  setOptions(options) {
69
81
  __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").setOptions(options);
70
82
  }
71
- startRecording() {
72
- __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").start();
73
- }
74
- stopRecording() {
75
- __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").stop();
76
- }
77
- cancelRecording() {
78
- __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").cancel();
79
- }
80
83
  destroy() {
81
84
  __classPrivateFieldGet(this, _SvelteHotkeyRecorderState_recorder, "f").destroy();
82
85
  }
@@ -18,6 +18,22 @@ class SvelteHotkeySequenceRecorderState {
18
18
  constructor(options) {
19
19
  _SvelteHotkeySequenceRecorderState_recorder.set(this, void 0);
20
20
  _SvelteHotkeySequenceRecorderState_subscribe.set(this, void 0);
21
+ // Keep the recorder receiver when used directly as an event handler.
22
+ this.startRecording = () => {
23
+ __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").start();
24
+ };
25
+ // Keep the recorder receiver when used directly as an event handler.
26
+ this.stopRecording = () => {
27
+ __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").stop();
28
+ };
29
+ // Keep the recorder receiver when used directly as an event handler.
30
+ this.cancelRecording = () => {
31
+ __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").cancel();
32
+ };
33
+ // Keep the recorder receiver when used directly as an event handler.
34
+ this.commitRecording = () => {
35
+ __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").commit();
36
+ };
21
37
  __classPrivateFieldSet(this, _SvelteHotkeySequenceRecorderState_recorder, new HotkeySequenceRecorder(options), "f");
22
38
  __classPrivateFieldSet(this, _SvelteHotkeySequenceRecorderState_subscribe, createStoreSubscriber(__classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").store), "f");
23
39
  }
@@ -36,18 +52,6 @@ class SvelteHotkeySequenceRecorderState {
36
52
  setOptions(options) {
37
53
  __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").setOptions(options);
38
54
  }
39
- startRecording() {
40
- __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").start();
41
- }
42
- stopRecording() {
43
- __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").stop();
44
- }
45
- cancelRecording() {
46
- __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").cancel();
47
- }
48
- commitRecording() {
49
- __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").commit();
50
- }
51
55
  destroy() {
52
56
  __classPrivateFieldGet(this, _SvelteHotkeySequenceRecorderState_recorder, "f").destroy();
53
57
  }
@@ -0,0 +1,13 @@
1
+ import type { HeldModifierOptions, RegisterableHotkey } from '@tanstack/hotkeys';
2
+ import type { MaybeGetter } from './internal.svelte';
3
+ export interface SvelteHotkeyHint {
4
+ readonly visible: boolean;
5
+ }
6
+ /**
7
+ * Returns an object with a reactive `visible` getter indicating whether held modifiers reveal this shortcut.
8
+ * Pass getters to track changing bindings and options.
9
+ * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires
10
+ * every modifier. Combine with the action's enabled state before showing a badge.
11
+ * This helper does not register a shortcut or check whether its target is focused.
12
+ */
13
+ export declare function getHotkeyHint(hotkey: MaybeGetter<RegisterableHotkey>, options?: MaybeGetter<HeldModifierOptions>): SvelteHotkeyHint;
@@ -0,0 +1,36 @@
1
+ import { createSubscriber } from 'svelte/reactivity';
2
+ import { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/hotkeys';
3
+ import { resolveMaybeGetter } from './internal.svelte';
4
+ /**
5
+ * Returns an object with a reactive `visible` getter indicating whether held modifiers reveal this shortcut.
6
+ * Pass getters to track changing bindings and options.
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
+ export function getHotkeyHint(hotkey, options = {}) {
12
+ const tracker = getKeyStateTracker();
13
+ // Resolve current reactive arguments without caching a stale binding.
14
+ const read = () => matchesHeldModifiers(resolveMaybeGetter(hotkey), tracker.store.state.heldKeys, resolveMaybeGetter(options));
15
+ let previous = false;
16
+ // Notify Svelte only when visibility changes, not for every unrelated held key.
17
+ const subscribe = createSubscriber((update) => {
18
+ previous = read();
19
+ const subscription = tracker.store.subscribe(() => {
20
+ const next = read();
21
+ if (next !== previous) {
22
+ previous = next;
23
+ update();
24
+ }
25
+ });
26
+ return () => subscription.unsubscribe();
27
+ });
28
+ return {
29
+ /** Reads visibility and subscribes the current reactive consumer when needed. */
30
+ get visible() {
31
+ subscribe();
32
+ previous = read();
33
+ return previous;
34
+ },
35
+ };
36
+ }
package/dist/index.d.ts CHANGED
@@ -12,3 +12,4 @@ export * from './getIsKeyHeld.svelte';
12
12
  export { default as HotkeysProvider } from './HotkeysProvider.svelte';
13
13
  export { DEFAULT_OPTIONS, getDefaultHotkeysOptions, getHotkeysContext, setHotkeysContext, } from './HotkeysCtx';
14
14
  export type { HotkeysProviderOptions, HotkeysProviderProps } from './HotkeysCtx';
15
+ export * from './getHotkeyHint.svelte';
package/dist/index.js CHANGED
@@ -12,3 +12,4 @@ export * from './getHeldKeyCodesMap.svelte';
12
12
  export * from './getIsKeyHeld.svelte';
13
13
  export { default as HotkeysProvider } from './HotkeysProvider.svelte';
14
14
  export { DEFAULT_OPTIONS, getDefaultHotkeysOptions, getHotkeysContext, setHotkeysContext, } from './HotkeysCtx';
15
+ export * from './getHotkeyHint.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/svelte-hotkeys",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "Svelte adapter for TanStack Hotkeys",
5
5
  "author": "Kunal Rao",
6
6
  "license": "MIT",
@@ -40,14 +40,14 @@
40
40
  "src"
41
41
  ],
42
42
  "dependencies": {
43
- "@tanstack/hotkeys": "0.7.1"
43
+ "@tanstack/hotkeys": "0.9.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@sveltejs/package": "^2.5.7",
47
47
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
48
- "@typescript-eslint/parser": "^8.57.2",
49
- "eslint-plugin-svelte": "^3.16.0",
50
- "svelte": "^5.55.0"
48
+ "@typescript-eslint/parser": "^8.59.0",
49
+ "eslint-plugin-svelte": "^3.17.1",
50
+ "svelte": "^5.55.5"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "svelte": "^5.25.0"
@@ -78,15 +78,18 @@ class SvelteHotkeyRecorderState implements SvelteHotkeyRecorder {
78
78
  this.#recorder.setOptions(options)
79
79
  }
80
80
 
81
- startRecording(): void {
81
+ // Keep the recorder receiver when used directly as an event handler.
82
+ startRecording = (): void => {
82
83
  this.#recorder.start()
83
84
  }
84
85
 
85
- stopRecording(): void {
86
+ // Keep the recorder receiver when used directly as an event handler.
87
+ stopRecording = (): void => {
86
88
  this.#recorder.stop()
87
89
  }
88
90
 
89
- cancelRecording(): void {
91
+ // Keep the recorder receiver when used directly as an event handler.
92
+ cancelRecording = (): void => {
90
93
  this.#recorder.cancel()
91
94
  }
92
95
 
@@ -46,19 +46,23 @@ class SvelteHotkeySequenceRecorderState implements SvelteHotkeySequenceRecorder
46
46
  this.#recorder.setOptions(options)
47
47
  }
48
48
 
49
- startRecording(): void {
49
+ // Keep the recorder receiver when used directly as an event handler.
50
+ startRecording = (): void => {
50
51
  this.#recorder.start()
51
52
  }
52
53
 
53
- stopRecording(): void {
54
+ // Keep the recorder receiver when used directly as an event handler.
55
+ stopRecording = (): void => {
54
56
  this.#recorder.stop()
55
57
  }
56
58
 
57
- cancelRecording(): void {
59
+ // Keep the recorder receiver when used directly as an event handler.
60
+ cancelRecording = (): void => {
58
61
  this.#recorder.cancel()
59
62
  }
60
63
 
61
- commitRecording(): void {
64
+ // Keep the recorder receiver when used directly as an event handler.
65
+ commitRecording = (): void => {
62
66
  this.#recorder.commit()
63
67
  }
64
68
 
@@ -0,0 +1,51 @@
1
+ import { createSubscriber } from 'svelte/reactivity'
2
+ import { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/hotkeys'
3
+ import { resolveMaybeGetter } from './internal.svelte'
4
+ import type { HeldModifierOptions, RegisterableHotkey } from '@tanstack/hotkeys'
5
+ import type { MaybeGetter } from './internal.svelte'
6
+
7
+ export interface SvelteHotkeyHint {
8
+ readonly visible: boolean
9
+ }
10
+
11
+ /**
12
+ * Returns an object with a reactive `visible` getter indicating whether held modifiers reveal this shortcut.
13
+ * Pass getters to track changing bindings and options.
14
+ * Uses the nonempty-subset/AltGr rules of `matchesHeldModifiers`; `exact` requires
15
+ * every modifier. Combine with the action's enabled state before showing a badge.
16
+ * This helper does not register a shortcut or check whether its target is focused.
17
+ */
18
+ export function getHotkeyHint(
19
+ hotkey: MaybeGetter<RegisterableHotkey>,
20
+ options: MaybeGetter<HeldModifierOptions> = {},
21
+ ): SvelteHotkeyHint {
22
+ const tracker = getKeyStateTracker()
23
+ // Resolve current reactive arguments without caching a stale binding.
24
+ const read = () =>
25
+ matchesHeldModifiers(
26
+ resolveMaybeGetter(hotkey),
27
+ tracker.store.state.heldKeys,
28
+ resolveMaybeGetter(options),
29
+ )
30
+ let previous = false
31
+ // Notify Svelte only when visibility changes, not for every unrelated held key.
32
+ const subscribe = createSubscriber((update) => {
33
+ previous = read()
34
+ const subscription = tracker.store.subscribe(() => {
35
+ const next = read()
36
+ if (next !== previous) {
37
+ previous = next
38
+ update()
39
+ }
40
+ })
41
+ return () => subscription.unsubscribe()
42
+ })
43
+ return {
44
+ /** Reads visibility and subscribes the current reactive consumer when needed. */
45
+ get visible() {
46
+ subscribe()
47
+ previous = read()
48
+ return previous
49
+ },
50
+ }
51
+ }
package/src/index.ts CHANGED
@@ -19,3 +19,4 @@ export {
19
19
  setHotkeysContext,
20
20
  } from './HotkeysCtx'
21
21
  export type { HotkeysProviderOptions, HotkeysProviderProps } from './HotkeysCtx'
22
+ export * from './getHotkeyHint.svelte'