@tanstack/vue-hotkeys 0.14.5 → 0.15.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 +1 -1
- package/dist/HotkeysProvider.d.ts +47 -0
- package/dist/HotkeysProvider.js +29 -0
- package/dist/HotkeysProviderContext.d.ts +18 -2
- package/dist/HotkeysProviderContext.js +31 -7
- package/dist/useAppHotkeys.d.ts +2 -2
- package/dist/useAppHotkeys.js +2 -2
- package/dist/useHotkey.d.ts +2 -2
- package/dist/useHotkeyRecorder.d.ts +1 -1
- package/dist/useHotkeys.d.ts +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
# TanStack Hotkeys
|
|
52
52
|
|
|
53
53
|
> [!NOTE]
|
|
54
|
-
> TanStack Hotkeys is
|
|
54
|
+
> TanStack Hotkeys is in beta. We are actively developing the library and are open to feedback and contributions.
|
|
55
55
|
|
|
56
56
|
Type-safe keyboard shortcuts for the web. Template-string bindings, parsed objects, a cross-platform `Mod` key, a singleton Hotkey Manager, and utilities for cheatsheet UIs—built to stay SSR-friendly.
|
|
57
57
|
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { HotkeysProviderOptions } from "./HotkeysProviderContext.js";
|
|
2
2
|
import { AppHotkeys, CustomHotkeys } from "@tanstack/hotkeys";
|
|
3
3
|
import { PropType } from "vue";
|
|
4
|
+
import { HotkeysProviderScopeProps } from "@tanstack/hotkeys/adapter";
|
|
4
5
|
//#region src/HotkeysProvider.d.ts
|
|
5
6
|
/**
|
|
6
7
|
* Vue component that provides default options, app hotkeys, and the user's
|
|
7
8
|
* custom hotkeys. `customHotkeys` is read once; listen to
|
|
8
9
|
* `custom-hotkeys-change` to save changes.
|
|
9
10
|
*
|
|
11
|
+
* Nest providers to create hotkey scopes. A nested provider inherits app
|
|
12
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
13
|
+
* while it is mounted and enabled; with `exclusive`, only its hotkeys fire.
|
|
14
|
+
*
|
|
10
15
|
* @example
|
|
11
16
|
* ```vue
|
|
12
17
|
* <template>
|
|
@@ -19,6 +24,13 @@ import { PropType } from "vue";
|
|
|
19
24
|
* </HotkeysProvider>
|
|
20
25
|
* </template>
|
|
21
26
|
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```vue
|
|
30
|
+
* <HotkeysProvider scope="edit-dialog" :exclusive="{ allow: ['global'] }">
|
|
31
|
+
* <DialogBody />
|
|
32
|
+
* </HotkeysProvider>
|
|
33
|
+
* ```
|
|
22
34
|
*/
|
|
23
35
|
export declare const HotkeysProvider: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
24
36
|
defaultOptions: {
|
|
@@ -33,6 +45,21 @@ export declare const HotkeysProvider: import("vue").DefineComponent<import("vue"
|
|
|
33
45
|
type: PropType<CustomHotkeys | null>;
|
|
34
46
|
default: undefined;
|
|
35
47
|
};
|
|
48
|
+
/** See `HotkeysProviderScopeProps['scope']`. */
|
|
49
|
+
scope: {
|
|
50
|
+
type: StringConstructor;
|
|
51
|
+
default: undefined;
|
|
52
|
+
};
|
|
53
|
+
/** See `HotkeysProviderScopeProps['exclusive']`. */
|
|
54
|
+
exclusive: {
|
|
55
|
+
type: PropType<HotkeysProviderScopeProps["exclusive"]>;
|
|
56
|
+
default: boolean;
|
|
57
|
+
};
|
|
58
|
+
/** See `HotkeysProviderScopeProps['enabled']`. */
|
|
59
|
+
enabled: {
|
|
60
|
+
type: BooleanConstructor;
|
|
61
|
+
default: boolean;
|
|
62
|
+
};
|
|
36
63
|
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
37
64
|
[key: string]: any;
|
|
38
65
|
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -50,11 +77,31 @@ export declare const HotkeysProvider: import("vue").DefineComponent<import("vue"
|
|
|
50
77
|
type: PropType<CustomHotkeys | null>;
|
|
51
78
|
default: undefined;
|
|
52
79
|
};
|
|
80
|
+
/** See `HotkeysProviderScopeProps['scope']`. */
|
|
81
|
+
scope: {
|
|
82
|
+
type: StringConstructor;
|
|
83
|
+
default: undefined;
|
|
84
|
+
};
|
|
85
|
+
/** See `HotkeysProviderScopeProps['exclusive']`. */
|
|
86
|
+
exclusive: {
|
|
87
|
+
type: PropType<HotkeysProviderScopeProps["exclusive"]>;
|
|
88
|
+
default: boolean;
|
|
89
|
+
};
|
|
90
|
+
/** See `HotkeysProviderScopeProps['enabled']`. */
|
|
91
|
+
enabled: {
|
|
92
|
+
type: BooleanConstructor;
|
|
93
|
+
default: boolean;
|
|
94
|
+
};
|
|
53
95
|
}>> & Readonly<{
|
|
54
96
|
onCustomHotkeysChange?: ((_customHotkeys: CustomHotkeys<Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>>) => any) | undefined;
|
|
55
97
|
}>, {
|
|
98
|
+
exclusive: boolean | {
|
|
99
|
+
allow: ReadonlyArray<string>;
|
|
100
|
+
} | undefined;
|
|
56
101
|
defaultOptions: HotkeysProviderOptions;
|
|
57
102
|
appHotkeys: Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>;
|
|
58
103
|
customHotkeys: CustomHotkeys<Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>> | null;
|
|
104
|
+
scope: string;
|
|
105
|
+
enabled: boolean;
|
|
59
106
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
60
107
|
//#endregion
|
package/dist/HotkeysProvider.js
CHANGED
|
@@ -7,6 +7,10 @@ import { defineComponent } from "vue";
|
|
|
7
7
|
* custom hotkeys. `customHotkeys` is read once; listen to
|
|
8
8
|
* `custom-hotkeys-change` to save changes.
|
|
9
9
|
*
|
|
10
|
+
* Nest providers to create hotkey scopes. A nested provider inherits app
|
|
11
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
12
|
+
* while it is mounted and enabled; with `exclusive`, only its hotkeys fire.
|
|
13
|
+
*
|
|
10
14
|
* @example
|
|
11
15
|
* ```vue
|
|
12
16
|
* <template>
|
|
@@ -19,6 +23,13 @@ import { defineComponent } from "vue";
|
|
|
19
23
|
* </HotkeysProvider>
|
|
20
24
|
* </template>
|
|
21
25
|
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```vue
|
|
29
|
+
* <HotkeysProvider scope="edit-dialog" :exclusive="{ allow: ['global'] }">
|
|
30
|
+
* <DialogBody />
|
|
31
|
+
* </HotkeysProvider>
|
|
32
|
+
* ```
|
|
22
33
|
*/
|
|
23
34
|
const HotkeysProvider = defineComponent({
|
|
24
35
|
name: "HotkeysProvider",
|
|
@@ -34,6 +45,21 @@ const HotkeysProvider = defineComponent({
|
|
|
34
45
|
customHotkeys: {
|
|
35
46
|
type: Object,
|
|
36
47
|
default: void 0
|
|
48
|
+
},
|
|
49
|
+
/** See `HotkeysProviderScopeProps['scope']`. */
|
|
50
|
+
scope: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: void 0
|
|
53
|
+
},
|
|
54
|
+
/** See `HotkeysProviderScopeProps['exclusive']`. */
|
|
55
|
+
exclusive: {
|
|
56
|
+
type: [Boolean, Object],
|
|
57
|
+
default: false
|
|
58
|
+
},
|
|
59
|
+
/** See `HotkeysProviderScopeProps['enabled']`. */
|
|
60
|
+
enabled: {
|
|
61
|
+
type: Boolean,
|
|
62
|
+
default: true
|
|
37
63
|
}
|
|
38
64
|
},
|
|
39
65
|
emits: { customHotkeysChange: (_customHotkeys) => true },
|
|
@@ -42,6 +68,9 @@ const HotkeysProvider = defineComponent({
|
|
|
42
68
|
defaultOptions: () => props.defaultOptions,
|
|
43
69
|
appHotkeys: () => props.appHotkeys,
|
|
44
70
|
customHotkeys: props.customHotkeys,
|
|
71
|
+
scope: () => props.scope,
|
|
72
|
+
exclusive: () => props.exclusive,
|
|
73
|
+
enabled: () => props.enabled,
|
|
45
74
|
onCustomHotkeysChange: (custom) => emit("customHotkeysChange", custom)
|
|
46
75
|
});
|
|
47
76
|
return () => slots.default?.();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { UseHotkeyCommonOptions } from "./useHotkey.js";
|
|
2
2
|
import { AppHotkeys, AppHotkeysStore, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
|
|
3
3
|
import { MaybeRefOrGetter } from "vue";
|
|
4
|
+
import { HotkeysProviderScopeProps } from "@tanstack/hotkeys/adapter";
|
|
4
5
|
//#region src/HotkeysProviderContext.d.ts
|
|
5
6
|
export interface HotkeysProviderOptions {
|
|
6
7
|
/**
|
|
@@ -13,11 +14,21 @@ export interface HotkeysProviderOptions {
|
|
|
13
14
|
}
|
|
14
15
|
interface HotkeysContextValue {
|
|
15
16
|
readonly appHotkeysStore: AppHotkeysStore | null;
|
|
17
|
+
/** Merged with every ancestor's defaults, including `hotkey.scope`. */
|
|
16
18
|
readonly defaultOptions: HotkeysProviderOptions;
|
|
19
|
+
/** Whether this context and every ancestor are enabled. */
|
|
20
|
+
readonly enabled: boolean;
|
|
17
21
|
}
|
|
18
22
|
/** Options for `provideHotkeysContext`. */
|
|
19
23
|
export interface ProvideHotkeysContextOptions {
|
|
24
|
+
/** Merged with the parent context's defaults. */
|
|
20
25
|
defaultOptions?: MaybeRefOrGetter<HotkeysProviderOptions | undefined>;
|
|
26
|
+
/** See `HotkeysProviderScopeProps['scope']`. */
|
|
27
|
+
scope?: MaybeRefOrGetter<HotkeysProviderScopeProps['scope']>;
|
|
28
|
+
/** See `HotkeysProviderScopeProps['exclusive']`. */
|
|
29
|
+
exclusive?: MaybeRefOrGetter<HotkeysProviderScopeProps['exclusive']>;
|
|
30
|
+
/** See `HotkeysProviderScopeProps['enabled']`. */
|
|
31
|
+
enabled?: MaybeRefOrGetter<HotkeysProviderScopeProps['enabled']>;
|
|
21
32
|
/**
|
|
22
33
|
* Every app hotkey, from `defineAppHotkeys`. Read when the context is
|
|
23
34
|
* provided; later changes update the declarations.
|
|
@@ -33,8 +44,13 @@ export interface ProvideHotkeysContextOptions {
|
|
|
33
44
|
}
|
|
34
45
|
/**
|
|
35
46
|
* Provides default options, app hotkeys, and the user's custom hotkeys to
|
|
36
|
-
* descendants. `HotkeysProvider` calls this; call it directly in a
|
|
37
|
-
*
|
|
47
|
+
* descendants. `HotkeysProvider` calls this; call it directly in a component's
|
|
48
|
+
* setup instead of rendering the provider.
|
|
49
|
+
*
|
|
50
|
+
* Nest contexts to create hotkey scopes. A nested context inherits app
|
|
51
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
52
|
+
* while the component is mounted and enabled; with `exclusive`, only its
|
|
53
|
+
* hotkeys fire.
|
|
38
54
|
*
|
|
39
55
|
* @example
|
|
40
56
|
* ```ts
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { AppHotkeysStore, publishAppHotkeysStore } from "@tanstack/hotkeys";
|
|
2
|
-
import { inject, onScopeDispose, provide, toValue, watch } from "vue";
|
|
2
|
+
import { computed, inject, onMounted, onScopeDispose, provide, toValue, watch } from "vue";
|
|
3
|
+
import { activateHotkeysProviderScope, getHotkeysProviderScopeKey, mergeHotkeysProviderDefaults } from "@tanstack/hotkeys/adapter";
|
|
3
4
|
|
|
4
5
|
//#region src/HotkeysProviderContext.ts
|
|
5
6
|
const HotkeysContext = Symbol("HotkeysContext");
|
|
6
7
|
const DEFAULT_OPTIONS = {};
|
|
7
8
|
/**
|
|
8
9
|
* Provides default options, app hotkeys, and the user's custom hotkeys to
|
|
9
|
-
* descendants. `HotkeysProvider` calls this; call it directly in a
|
|
10
|
-
*
|
|
10
|
+
* descendants. `HotkeysProvider` calls this; call it directly in a component's
|
|
11
|
+
* setup instead of rendering the provider.
|
|
12
|
+
*
|
|
13
|
+
* Nest contexts to create hotkey scopes. A nested context inherits app
|
|
14
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
15
|
+
* while the component is mounted and enabled; with `exclusive`, only its
|
|
16
|
+
* hotkeys fire.
|
|
11
17
|
*
|
|
12
18
|
* @example
|
|
13
19
|
* ```ts
|
|
@@ -20,6 +26,7 @@ const DEFAULT_OPTIONS = {};
|
|
|
20
26
|
* ```
|
|
21
27
|
*/
|
|
22
28
|
function provideHotkeysContext(options = {}) {
|
|
29
|
+
const parent = inject(HotkeysContext, null);
|
|
23
30
|
const appHotkeys = toValue(options.appHotkeys);
|
|
24
31
|
const store = appHotkeys ? new AppHotkeysStore(appHotkeys, {
|
|
25
32
|
customHotkeys: options.customHotkeys,
|
|
@@ -31,12 +38,29 @@ function provideHotkeysContext(options = {}) {
|
|
|
31
38
|
});
|
|
32
39
|
if (typeof document !== "undefined") onScopeDispose(publishAppHotkeysStore(store));
|
|
33
40
|
}
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
const active = computed(() => (parent?.enabled ?? true) && toValue(options.enabled) !== false);
|
|
42
|
+
const defaultOptions = computed(() => mergeHotkeysProviderDefaults(parent?.defaultOptions, toValue(options.defaultOptions), toValue(options.scope)));
|
|
43
|
+
const scopeKey = computed(() => getHotkeysProviderScopeKey({
|
|
44
|
+
scope: toValue(options.scope),
|
|
45
|
+
exclusive: toValue(options.exclusive),
|
|
46
|
+
active: active.value,
|
|
47
|
+
parent: parent?.defaultOptions.hotkey?.scope
|
|
48
|
+
}));
|
|
49
|
+
onMounted(() => {
|
|
50
|
+
watch(scopeKey, (key, _, onCleanup) => {
|
|
51
|
+
if (key) onCleanup(activateHotkeysProviderScope(key));
|
|
52
|
+
}, { immediate: true });
|
|
53
|
+
});
|
|
54
|
+
const contextValue = {
|
|
55
|
+
appHotkeysStore: store ?? parent?.appHotkeysStore ?? null,
|
|
36
56
|
get defaultOptions() {
|
|
37
|
-
return
|
|
57
|
+
return defaultOptions.value;
|
|
58
|
+
},
|
|
59
|
+
get enabled() {
|
|
60
|
+
return active.value;
|
|
38
61
|
}
|
|
39
|
-
}
|
|
62
|
+
};
|
|
63
|
+
provide(HotkeysContext, contextValue);
|
|
40
64
|
}
|
|
41
65
|
function useHotkeysContext() {
|
|
42
66
|
return inject(HotkeysContext, null);
|
package/dist/useAppHotkeys.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ import { ComputedRef } from "vue";
|
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
|
-
* const
|
|
11
|
-
* useHotkey(() =>
|
|
10
|
+
* const appHotkeys = useAppHotkeys()
|
|
11
|
+
* useHotkey(() => appHotkeys.value['doc.save'], () => save())
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
export declare function useAppHotkeys(): ComputedRef<RegisteredAppHotkeys>;
|
package/dist/useAppHotkeys.js
CHANGED
|
@@ -17,8 +17,8 @@ function useRequiredStore(name) {
|
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* ```ts
|
|
20
|
-
* const
|
|
21
|
-
* useHotkey(() =>
|
|
20
|
+
* const appHotkeys = useAppHotkeys()
|
|
21
|
+
* useHotkey(() => appHotkeys.value['doc.save'], () => save())
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
function useAppHotkeys() {
|
package/dist/useHotkey.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppHotkey, HotkeyCallback, RegisterableHotkey, Target } from "@tanstack/hotkeys";
|
|
1
|
+
import { AppHotkey, HotkeyCallback, HotkeyCallbackContextFor, RegisterableHotkey, Target } from "@tanstack/hotkeys";
|
|
2
2
|
import { MaybeRefOrGetter } from "vue";
|
|
3
3
|
import { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from "@tanstack/hotkeys/adapter";
|
|
4
4
|
//#region src/useHotkey.d.ts
|
|
@@ -42,5 +42,5 @@ export type UseAppHotkeyOptions<T extends AppHotkey = AppHotkey> = WithReactiveE
|
|
|
42
42
|
* ```
|
|
43
43
|
*/
|
|
44
44
|
export declare function useHotkey<T extends AppHotkey>(hotkey: MaybeRefOrGetter<T>, callback: HotkeyCallback, options?: MaybeRefOrGetter<UseAppHotkeyOptions<T>>): void;
|
|
45
|
-
export declare function useHotkey<T extends RegisterableHotkey>(hotkey: MaybeRefOrGetter<T>, callback: HotkeyCallback
|
|
45
|
+
export declare function useHotkey<const T extends RegisterableHotkey>(hotkey: MaybeRefOrGetter<T>, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: MaybeRefOrGetter<UseHotkeyOptionsFor<T>>): void;
|
|
46
46
|
//#endregion
|
|
@@ -28,7 +28,7 @@ export interface VueHotkeyRecorder<THotkey extends Hotkey = Hotkey> {
|
|
|
28
28
|
* @example
|
|
29
29
|
* ```ts
|
|
30
30
|
* const recorder = useHotkeyRecorder({ onRecord: (hotkey) => (shortcut.value = hotkey) })
|
|
31
|
-
* const sequenceRecorder = useHotkeyRecorder({ maxSteps:
|
|
31
|
+
* const sequenceRecorder = useHotkeyRecorder({ maxSteps: Infinity, onRecord: save })
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
34
|
export declare function useHotkeyRecorder(options: HotkeyChordRecorderOptions): VueHotkeyRecorder<HotkeyChord>;
|
package/dist/useHotkeys.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UseAppHotkeyOptions, UseHotkeyChordOptions, UseHotkeyCommonOptions, UseHotkeyOptions, UseHotkeySequenceOptions } from "./useHotkey.js";
|
|
2
|
-
import { AppHotkey, HotkeyCallback,
|
|
2
|
+
import { AppHotkey, HotkeyCallback, RegisterableHotkey, RegisterableHotkeyChord, RegisterableHotkeySequence } from "@tanstack/hotkeys";
|
|
3
3
|
import { MaybeRefOrGetter } from "vue";
|
|
4
4
|
//#region src/useHotkeys.d.ts
|
|
5
5
|
/**
|
|
@@ -8,15 +8,15 @@ import { MaybeRefOrGetter } from "vue";
|
|
|
8
8
|
* kind accept only shared options.
|
|
9
9
|
*/
|
|
10
10
|
export type UseHotkeyDefinition = {
|
|
11
|
-
/** A chord string such as `'Mod+S'`, or a
|
|
11
|
+
/** A chord string such as `'Mod+S'`, or a chord object */
|
|
12
12
|
hotkey: MaybeRefOrGetter<RegisterableHotkeyChord>;
|
|
13
13
|
/** The function to call when the hotkey is pressed */
|
|
14
14
|
callback: HotkeyCallback;
|
|
15
15
|
/** Per-hotkey options (merged on top of commonOptions) */
|
|
16
16
|
options?: MaybeRefOrGetter<UseHotkeyChordOptions>;
|
|
17
17
|
} | {
|
|
18
|
-
/** A sequence such as `['G', 'G']
|
|
19
|
-
hotkey: MaybeRefOrGetter<
|
|
18
|
+
/** A sequence such as `['G', 'G']`, with each step a string or an object */
|
|
19
|
+
hotkey: MaybeRefOrGetter<RegisterableHotkeySequence>;
|
|
20
20
|
callback: HotkeyCallback;
|
|
21
21
|
options?: MaybeRefOrGetter<UseHotkeySequenceOptions>;
|
|
22
22
|
} | {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Vue adapter for TanStack Hotkeys",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@tanstack/hotkeys": "0.
|
|
39
|
+
"@tanstack/hotkeys": "0.16.0",
|
|
40
40
|
"@tanstack/vue-store": "^0.11.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|