@tanstack/vue-hotkeys 0.17.0 → 0.18.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/dist/HotkeysProviderContext.d.ts +5 -0
- package/dist/HotkeysProviderContext.js +11 -6
- package/dist/defaultOptions.js +3 -3
- package/dist/useHeldKeyCodes.js +2 -2
- package/dist/useHeldKeys.d.ts +1 -2
- package/dist/useHeldKeys.js +3 -4
- package/dist/useHotkeyHint.js +3 -3
- package/dist/useHotkeyRecorder.js +4 -4
- package/dist/useHotkeyRegistrations.js +2 -2
- package/dist/useHotkeyScopesState.js +2 -2
- package/dist/useKeyHold.d.ts +2 -3
- package/dist/useKeyHold.js +8 -11
- package/dist/useStoreSelector.js +23 -0
- package/package.json +3 -4
|
@@ -63,6 +63,11 @@ export interface ProvideHotkeysContextOptions {
|
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
65
|
export declare function provideHotkeysContext(options?: ProvideHotkeysContextOptions): void;
|
|
66
|
+
/**
|
|
67
|
+
* The nearest context, or `null`. Outside a component, such as in a bare
|
|
68
|
+
* `effectScope`, there is no context to read, so this skips `inject` and its
|
|
69
|
+
* warning.
|
|
70
|
+
*/
|
|
66
71
|
export declare function useHotkeysContext(): HotkeysContextValue | null;
|
|
67
72
|
export declare function useDefaultHotkeysOptions(): HotkeysProviderOptions;
|
|
68
73
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { computed, inject, onMounted, onScopeDispose, provide, toValue, watch } from "vue";
|
|
3
|
-
import { activateHotkeysProviderScope, getHotkeysProviderScopeKey, mergeHotkeysProviderDefaults } from "@tanstack/hotkeys/adapter";
|
|
1
|
+
import { publishAppHotkeysStore } from "@tanstack/hotkeys";
|
|
2
|
+
import { computed, hasInjectionContext, inject, onMounted, onScopeDispose, provide, toValue, watch } from "vue";
|
|
3
|
+
import { activateHotkeysProviderScope, createAppHotkeysStore, getHotkeysProviderScopeKey, mergeHotkeysProviderDefaults } from "@tanstack/hotkeys/adapter";
|
|
4
4
|
|
|
5
5
|
//#region src/HotkeysProviderContext.ts
|
|
6
6
|
const HotkeysContext = Symbol("HotkeysContext");
|
|
@@ -28,7 +28,7 @@ const DEFAULT_OPTIONS = {};
|
|
|
28
28
|
function provideHotkeysContext(options = {}) {
|
|
29
29
|
const parent = inject(HotkeysContext, null);
|
|
30
30
|
const appHotkeys = toValue(options.appHotkeys);
|
|
31
|
-
const store = appHotkeys ?
|
|
31
|
+
const store = appHotkeys ? createAppHotkeysStore(appHotkeys, {
|
|
32
32
|
customHotkeys: options.customHotkeys,
|
|
33
33
|
onCustomHotkeysChange: (custom) => options.onCustomHotkeysChange?.(custom)
|
|
34
34
|
}) : null;
|
|
@@ -62,11 +62,16 @@ function provideHotkeysContext(options = {}) {
|
|
|
62
62
|
};
|
|
63
63
|
provide(HotkeysContext, contextValue);
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* The nearest context, or `null`. Outside a component, such as in a bare
|
|
67
|
+
* `effectScope`, there is no context to read, so this skips `inject` and its
|
|
68
|
+
* warning.
|
|
69
|
+
*/
|
|
65
70
|
function useHotkeysContext() {
|
|
66
|
-
return inject(HotkeysContext, null);
|
|
71
|
+
return hasInjectionContext() ? inject(HotkeysContext, null) : null;
|
|
67
72
|
}
|
|
68
73
|
function useDefaultHotkeysOptions() {
|
|
69
|
-
return
|
|
74
|
+
return useHotkeysContext()?.defaultOptions ?? DEFAULT_OPTIONS;
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
//#endregion
|
package/dist/defaultOptions.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useHotkeysContext } from "./HotkeysProviderContext.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
3
|
+
import { shallowRef } from "vue";
|
|
3
4
|
|
|
4
5
|
//#region src/defaultOptions.ts
|
|
5
6
|
/** Captures the context once and reads current defaults inside reactive computations. */
|
|
@@ -7,7 +8,6 @@ function useDefaultHotkeysOptionsSource() {
|
|
|
7
8
|
const context = useHotkeysContext();
|
|
8
9
|
return () => context?.defaultOptions ?? {};
|
|
9
10
|
}
|
|
10
|
-
const NO_APP_HOTKEYS = new Store(null);
|
|
11
11
|
/**
|
|
12
12
|
* The provider's app hotkeys store and a ref that tracks its state, so
|
|
13
13
|
* watchers re-run when app hotkeys or custom hotkeys change.
|
|
@@ -16,7 +16,7 @@ function useAppHotkeysStoreSource() {
|
|
|
16
16
|
const store = useHotkeysContext()?.appHotkeysStore ?? null;
|
|
17
17
|
return {
|
|
18
18
|
store,
|
|
19
|
-
state:
|
|
19
|
+
state: store ? useStoreSelector(store.store, (value) => value) : shallowRef(null)
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
package/dist/useHeldKeyCodes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { getKeyStateTracker } from "@tanstack/hotkeys";
|
|
2
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
3
3
|
|
|
4
4
|
//#region src/useHeldKeyCodes.ts
|
|
5
5
|
/**
|
|
@@ -30,7 +30,7 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
30
30
|
*/
|
|
31
31
|
function useHeldKeyCodes() {
|
|
32
32
|
const tracker = getKeyStateTracker();
|
|
33
|
-
return
|
|
33
|
+
return useStoreSelector(tracker.store, (state) => state.heldCodes);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
//#endregion
|
package/dist/useHeldKeys.d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { Ref } from "vue";
|
|
|
3
3
|
/**
|
|
4
4
|
* Vue composable that returns a reactive ref of currently held keyboard keys.
|
|
5
5
|
*
|
|
6
|
-
* This composable
|
|
7
|
-
* to the global KeyStateTracker and updates whenever keys are pressed
|
|
6
|
+
* This composable subscribes to the global KeyStateTracker and updates whenever keys are pressed
|
|
8
7
|
* or released.
|
|
9
8
|
*
|
|
10
9
|
* @returns Reactive ref containing array of currently held key names
|
package/dist/useHeldKeys.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { getKeyStateTracker } from "@tanstack/hotkeys";
|
|
2
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
3
3
|
|
|
4
4
|
//#region src/useHeldKeys.ts
|
|
5
5
|
/**
|
|
6
6
|
* Vue composable that returns a reactive ref of currently held keyboard keys.
|
|
7
7
|
*
|
|
8
|
-
* This composable
|
|
9
|
-
* to the global KeyStateTracker and updates whenever keys are pressed
|
|
8
|
+
* This composable subscribes to the global KeyStateTracker and updates whenever keys are pressed
|
|
10
9
|
* or released.
|
|
11
10
|
*
|
|
12
11
|
* @returns Reactive ref containing array of currently held key names
|
|
@@ -28,7 +27,7 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
28
27
|
*/
|
|
29
28
|
function useHeldKeys() {
|
|
30
29
|
const tracker = getKeyStateTracker();
|
|
31
|
-
return
|
|
30
|
+
return useStoreSelector(tracker.store, (state) => state.heldKeys);
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
//#endregion
|
package/dist/useHotkeyHint.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { useAppHotkeysStoreSource } from "./defaultOptions.js";
|
|
2
3
|
import { getHotkeyManager, getKeyStateTracker, isAppHotkey, matchesHeldModifiers, resolveAppHotkey } from "@tanstack/hotkeys";
|
|
3
4
|
import { computed, toValue } from "vue";
|
|
4
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
5
5
|
|
|
6
6
|
//#region src/useHotkeyHint.ts
|
|
7
7
|
/**
|
|
@@ -15,8 +15,8 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
15
15
|
function useHotkeyHint(hotkey, options = {}) {
|
|
16
16
|
const appHotkeys = useAppHotkeysStoreSource();
|
|
17
17
|
const manager = getHotkeyManager();
|
|
18
|
-
const registrations =
|
|
19
|
-
const held =
|
|
18
|
+
const registrations = useStoreSelector(manager.registrations, (state) => state);
|
|
19
|
+
const held = useStoreSelector(getKeyStateTracker().store, (state) => state.heldKeys);
|
|
20
20
|
return computed(() => {
|
|
21
21
|
appHotkeys.state.value;
|
|
22
22
|
const value = toValue(hotkey);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { useDefaultHotkeysOptionsSource } from "./defaultOptions.js";
|
|
2
3
|
import { HotkeyRecorder } from "@tanstack/hotkeys";
|
|
3
4
|
import { onScopeDispose, toValue, watch } from "vue";
|
|
4
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
5
5
|
|
|
6
6
|
//#region src/useHotkeyRecorder.ts
|
|
7
7
|
function useHotkeyRecorder(options) {
|
|
@@ -11,9 +11,9 @@ function useHotkeyRecorder(options) {
|
|
|
11
11
|
...toValue(options)
|
|
12
12
|
});
|
|
13
13
|
const recorder = new HotkeyRecorder(resolve());
|
|
14
|
-
const isRecording =
|
|
15
|
-
const steps =
|
|
16
|
-
const recordedHotkey =
|
|
14
|
+
const isRecording = useStoreSelector(recorder.store, (state) => state.isRecording);
|
|
15
|
+
const steps = useStoreSelector(recorder.store, (state) => state.steps);
|
|
16
|
+
const recordedHotkey = useStoreSelector(recorder.store, (state) => state.recordedHotkey);
|
|
17
17
|
const stopWatcher = watch(resolve, (resolved) => recorder.setOptions(resolved));
|
|
18
18
|
onScopeDispose(() => {
|
|
19
19
|
stopWatcher();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { getHotkeyManager, toHotkeyRegistrationView } from "@tanstack/hotkeys";
|
|
2
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
3
3
|
|
|
4
4
|
//#region src/useHotkeyRegistrations.ts
|
|
5
5
|
/**
|
|
@@ -23,7 +23,7 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
function useHotkeyRegistrations() {
|
|
26
|
-
return
|
|
26
|
+
return useStoreSelector(getHotkeyManager().registrations, (state) => Array.from(state.values()).map(toHotkeyRegistrationView));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { useStoreSelector } from "./useStoreSelector.js";
|
|
1
2
|
import { getHotkeyManager } from "@tanstack/hotkeys";
|
|
2
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
3
3
|
|
|
4
4
|
//#region src/useHotkeyScopesState.ts
|
|
5
5
|
/**
|
|
@@ -23,7 +23,7 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
function useHotkeyScopesState() {
|
|
26
|
-
return
|
|
26
|
+
return useStoreSelector(getHotkeyManager().scopes, (state) => state);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
//#endregion
|
package/dist/useKeyHold.d.ts
CHANGED
|
@@ -4,9 +4,8 @@ import { MaybeRefOrGetter, Ref } from "vue";
|
|
|
4
4
|
/**
|
|
5
5
|
* Vue composable that returns a reactive ref indicating whether a specific key is currently being held.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* the specified key is held.
|
|
7
|
+
* Reads the held keys from the global KeyStateTracker. The key may be a ref
|
|
8
|
+
* or getter; the result follows it without waiting for a key event.
|
|
10
9
|
*
|
|
11
10
|
* @param key - The key to check (e.g., 'Shift', 'Control', 'A')
|
|
12
11
|
* @returns Reactive ref that is true if the key is currently held down
|
package/dist/useKeyHold.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useSelector } from "@tanstack/vue-store";
|
|
1
|
+
import { useHeldKeys } from "./useHeldKeys.js";
|
|
2
|
+
import { computed, toValue } from "vue";
|
|
4
3
|
|
|
5
4
|
//#region src/useKeyHold.ts
|
|
6
5
|
/**
|
|
7
6
|
* Vue composable that returns a reactive ref indicating whether a specific key is currently being held.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* the specified key is held.
|
|
8
|
+
* Reads the held keys from the global KeyStateTracker. The key may be a ref
|
|
9
|
+
* or getter; the result follows it without waiting for a key event.
|
|
12
10
|
*
|
|
13
11
|
* @param key - The key to check (e.g., 'Shift', 'Control', 'A')
|
|
14
12
|
* @returns Reactive ref that is true if the key is currently held down
|
|
@@ -48,11 +46,10 @@ import { useSelector } from "@tanstack/vue-store";
|
|
|
48
46
|
* ```
|
|
49
47
|
*/
|
|
50
48
|
function useKeyHold(key) {
|
|
51
|
-
const
|
|
52
|
-
return
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
return state.heldKeys.some((heldKey) => heldKey.toLowerCase() === normalizedKey);
|
|
49
|
+
const heldKeys = useHeldKeys();
|
|
50
|
+
return computed(() => {
|
|
51
|
+
const target = toValue(key).toLowerCase();
|
|
52
|
+
return heldKeys.value.some((heldKey) => heldKey.toLowerCase() === target);
|
|
56
53
|
});
|
|
57
54
|
}
|
|
58
55
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { onScopeDispose, shallowReadonly, shallowRef } from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/useStoreSelector.ts
|
|
4
|
+
/**
|
|
5
|
+
* Subscribes to a store until the effect scope is disposed and returns a ref
|
|
6
|
+
* to the selected value, which updates when it changes (by `===`).
|
|
7
|
+
*
|
|
8
|
+
* Does not subscribe during server rendering. Vue never disposes component
|
|
9
|
+
* scopes on the server, so a subscription to a shared store would never be
|
|
10
|
+
* released. The server gets the current value instead.
|
|
11
|
+
*/
|
|
12
|
+
function useStoreSelector(store, selector) {
|
|
13
|
+
const selected = shallowRef(selector(store.get()));
|
|
14
|
+
if (typeof document === "undefined") return selected;
|
|
15
|
+
const { unsubscribe } = store.subscribe((state) => {
|
|
16
|
+
selected.value = selector(state);
|
|
17
|
+
});
|
|
18
|
+
onScopeDispose(unsubscribe);
|
|
19
|
+
return shallowReadonly(selected);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { useStoreSelector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Vue adapter for TanStack Hotkeys",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,8 +38,7 @@
|
|
|
38
38
|
"skills"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@tanstack/hotkeys": "0.
|
|
42
|
-
"@tanstack/vue-store": "^0.11.2"
|
|
41
|
+
"@tanstack/hotkeys": "0.20.0"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
45
44
|
"@vitejs/plugin-vue": "^6.0.9",
|
|
@@ -47,7 +46,7 @@
|
|
|
47
46
|
"vue": "^3.5.43"
|
|
48
47
|
},
|
|
49
48
|
"peerDependencies": {
|
|
50
|
-
"vue": ">=3.
|
|
49
|
+
"vue": ">=3.3.0"
|
|
51
50
|
},
|
|
52
51
|
"scripts": {
|
|
53
52
|
"clean": "premove ./build ./dist",
|