@tanstack/vue-hotkeys 0.12.1 → 0.14.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 +3 -0
- package/dist/HotkeysProvider.d.ts +36 -6
- package/dist/HotkeysProvider.js +30 -8
- package/dist/HotkeysProviderContext.d.ts +44 -9
- package/dist/HotkeysProviderContext.js +36 -4
- package/dist/defaultOptions.js +24 -0
- package/dist/index.d.ts +5 -7
- package/dist/index.js +3 -5
- package/dist/useAppHotkeys.d.ts +43 -0
- package/dist/useAppHotkeys.js +64 -0
- package/dist/useHotkey.d.ts +36 -73
- package/dist/useHotkey.js +6 -133
- package/dist/useHotkeyHint.d.ts +6 -6
- package/dist/useHotkeyHint.js +13 -6
- package/dist/useHotkeyRecorder.d.ts +25 -44
- package/dist/useHotkeyRecorder.js +14 -59
- package/dist/useHotkeyRegistrations.d.ts +18 -17
- package/dist/useHotkeyRegistrations.js +18 -13
- package/dist/useHotkeys.d.ts +33 -44
- package/dist/useHotkeys.js +37 -119
- package/package.json +3 -3
- package/dist/useHotkeySequence.d.ts +0 -65
- package/dist/useHotkeySequence.js +0 -121
- package/dist/useHotkeySequenceRecorder.d.ts +0 -17
- package/dist/useHotkeySequenceRecorder.js +0 -44
- package/dist/useHotkeySequences.d.ts +0 -61
- package/dist/useHotkeySequences.js +0 -139
package/README.md
CHANGED
|
@@ -67,6 +67,9 @@ Type-safe keyboard shortcuts for the web. Template-string bindings, parsed objec
|
|
|
67
67
|
> [!NOTE]
|
|
68
68
|
> You may know **TanStack Hotkeys** by our adapter names, too!
|
|
69
69
|
>
|
|
70
|
+
> - [**Alpine Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/alpine/quick-start)
|
|
71
|
+
> - [**Ember Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/ember/quick-start)
|
|
72
|
+
> - [**Octane Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/octane/quick-start)
|
|
70
73
|
> - [**React Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/react/react-hotkeys)
|
|
71
74
|
> - [**Preact Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/preact/preact-hotkeys)
|
|
72
75
|
> - [**Solid Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/solid/reference)
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { HotkeysProviderOptions } from "./HotkeysProviderContext.js";
|
|
2
|
+
import { AppHotkeys, CustomHotkeys } from "@tanstack/hotkeys";
|
|
3
|
+
import { PropType } from "vue";
|
|
2
4
|
//#region src/HotkeysProvider.d.ts
|
|
3
5
|
/**
|
|
4
|
-
* Vue component that provides default options
|
|
6
|
+
* Vue component that provides default options, app hotkeys, and the user's
|
|
7
|
+
* custom hotkeys. `customHotkeys` is read once; listen to
|
|
8
|
+
* `custom-hotkeys-change` to save changes.
|
|
5
9
|
*
|
|
6
10
|
* @example
|
|
7
11
|
* ```vue
|
|
8
12
|
* <template>
|
|
9
|
-
* <HotkeysProvider
|
|
13
|
+
* <HotkeysProvider
|
|
14
|
+
* :app-hotkeys="appHotkeys"
|
|
15
|
+
* :custom-hotkeys="saved"
|
|
16
|
+
* @custom-hotkeys-change="save"
|
|
17
|
+
* >
|
|
10
18
|
* <App />
|
|
11
19
|
* </HotkeysProvider>
|
|
12
20
|
* </template>
|
|
@@ -14,17 +22,39 @@ import { HotkeysProviderOptions } from "./HotkeysProviderContext.js";
|
|
|
14
22
|
*/
|
|
15
23
|
export declare const HotkeysProvider: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
16
24
|
defaultOptions: {
|
|
17
|
-
type:
|
|
25
|
+
type: PropType<HotkeysProviderOptions>;
|
|
26
|
+
default: undefined;
|
|
27
|
+
};
|
|
28
|
+
appHotkeys: {
|
|
29
|
+
type: PropType<AppHotkeys>;
|
|
30
|
+
default: undefined;
|
|
31
|
+
};
|
|
32
|
+
customHotkeys: {
|
|
33
|
+
type: PropType<CustomHotkeys | null>;
|
|
18
34
|
default: undefined;
|
|
19
35
|
};
|
|
20
36
|
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
21
37
|
[key: string]: any;
|
|
22
|
-
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
38
|
+
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
39
|
+
customHotkeysChange: (_customHotkeys: CustomHotkeys) => true;
|
|
40
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
23
41
|
defaultOptions: {
|
|
24
|
-
type:
|
|
42
|
+
type: PropType<HotkeysProviderOptions>;
|
|
43
|
+
default: undefined;
|
|
44
|
+
};
|
|
45
|
+
appHotkeys: {
|
|
46
|
+
type: PropType<AppHotkeys>;
|
|
47
|
+
default: undefined;
|
|
48
|
+
};
|
|
49
|
+
customHotkeys: {
|
|
50
|
+
type: PropType<CustomHotkeys | null>;
|
|
25
51
|
default: undefined;
|
|
26
52
|
};
|
|
27
|
-
}>> & Readonly<{
|
|
53
|
+
}>> & Readonly<{
|
|
54
|
+
onCustomHotkeysChange?: ((_customHotkeys: CustomHotkeys<Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>>) => any) | undefined;
|
|
55
|
+
}>, {
|
|
28
56
|
defaultOptions: HotkeysProviderOptions;
|
|
57
|
+
appHotkeys: Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>;
|
|
58
|
+
customHotkeys: CustomHotkeys<Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>> | null;
|
|
29
59
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
30
60
|
//#endregion
|
package/dist/HotkeysProvider.js
CHANGED
|
@@ -3,12 +3,18 @@ import { defineComponent } from "vue";
|
|
|
3
3
|
|
|
4
4
|
//#region src/HotkeysProvider.tsx
|
|
5
5
|
/**
|
|
6
|
-
* Vue component that provides default options
|
|
6
|
+
* Vue component that provides default options, app hotkeys, and the user's
|
|
7
|
+
* custom hotkeys. `customHotkeys` is read once; listen to
|
|
8
|
+
* `custom-hotkeys-change` to save changes.
|
|
7
9
|
*
|
|
8
10
|
* @example
|
|
9
11
|
* ```vue
|
|
10
12
|
* <template>
|
|
11
|
-
* <HotkeysProvider
|
|
13
|
+
* <HotkeysProvider
|
|
14
|
+
* :app-hotkeys="appHotkeys"
|
|
15
|
+
* :custom-hotkeys="saved"
|
|
16
|
+
* @custom-hotkeys-change="save"
|
|
17
|
+
* >
|
|
12
18
|
* <App />
|
|
13
19
|
* </HotkeysProvider>
|
|
14
20
|
* </template>
|
|
@@ -16,12 +22,28 @@ import { defineComponent } from "vue";
|
|
|
16
22
|
*/
|
|
17
23
|
const HotkeysProvider = defineComponent({
|
|
18
24
|
name: "HotkeysProvider",
|
|
19
|
-
props: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
props: {
|
|
26
|
+
defaultOptions: {
|
|
27
|
+
type: Object,
|
|
28
|
+
default: void 0
|
|
29
|
+
},
|
|
30
|
+
appHotkeys: {
|
|
31
|
+
type: Object,
|
|
32
|
+
default: void 0
|
|
33
|
+
},
|
|
34
|
+
customHotkeys: {
|
|
35
|
+
type: Object,
|
|
36
|
+
default: void 0
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
emits: { customHotkeysChange: (_customHotkeys) => true },
|
|
40
|
+
setup(props, { slots, emit }) {
|
|
41
|
+
provideHotkeysContext({
|
|
42
|
+
defaultOptions: () => props.defaultOptions,
|
|
43
|
+
appHotkeys: () => props.appHotkeys,
|
|
44
|
+
customHotkeys: props.customHotkeys,
|
|
45
|
+
onCustomHotkeysChange: (custom) => emit("customHotkeysChange", custom)
|
|
46
|
+
});
|
|
25
47
|
return () => slots.default?.();
|
|
26
48
|
}
|
|
27
49
|
});
|
|
@@ -1,17 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { UseHotkeyCommonOptions } from "./useHotkey.js";
|
|
2
|
+
import { AppHotkeys, AppHotkeysStore, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
|
|
3
|
+
import { MaybeRefOrGetter } from "vue";
|
|
4
4
|
//#region src/HotkeysProviderContext.d.ts
|
|
5
5
|
export interface HotkeysProviderOptions {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Defaults for every hotkey registered by `useHotkey` and `useHotkeys`.
|
|
8
|
+
* `requireReset` applies to chords and `timeout` applies to sequences.
|
|
9
|
+
*/
|
|
10
|
+
hotkey?: UseHotkeyCommonOptions;
|
|
11
|
+
/** Defaults for every `useHotkeyRecorder`. */
|
|
12
|
+
hotkeyRecorder?: Partial<Omit<HotkeyChordRecorderOptions & HotkeySequenceRecorderOptions, 'maxSteps' | 'onRecord' | 'validate'>>;
|
|
10
13
|
}
|
|
11
14
|
interface HotkeysContextValue {
|
|
12
|
-
|
|
15
|
+
readonly appHotkeysStore: AppHotkeysStore | null;
|
|
16
|
+
readonly defaultOptions: HotkeysProviderOptions;
|
|
13
17
|
}
|
|
14
|
-
|
|
18
|
+
/** Options for `provideHotkeysContext`. */
|
|
19
|
+
export interface ProvideHotkeysContextOptions {
|
|
20
|
+
defaultOptions?: MaybeRefOrGetter<HotkeysProviderOptions | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Every app hotkey, from `defineAppHotkeys`. Read when the context is
|
|
23
|
+
* provided; later changes update the declarations.
|
|
24
|
+
*/
|
|
25
|
+
appHotkeys?: MaybeRefOrGetter<AppHotkeys | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Starting custom hotkeys, such as saved data. Read once; the context owns
|
|
28
|
+
* the state afterwards. Invalid entries are ignored with a warning.
|
|
29
|
+
*/
|
|
30
|
+
customHotkeys?: CustomHotkeys | null;
|
|
31
|
+
/** Called with the custom hotkeys after every change, ready to save. */
|
|
32
|
+
onCustomHotkeysChange?: (customHotkeys: CustomHotkeys) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Provides default options, app hotkeys, and the user's custom hotkeys to
|
|
36
|
+
* descendants. `HotkeysProvider` calls this; call it directly in a root
|
|
37
|
+
* component's setup instead of rendering the provider.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* provideHotkeysContext({
|
|
42
|
+
* appHotkeys,
|
|
43
|
+
* customHotkeys: JSON.parse(localStorage.getItem('hotkeys') ?? '{}'),
|
|
44
|
+
* onCustomHotkeysChange: (custom) =>
|
|
45
|
+
* localStorage.setItem('hotkeys', JSON.stringify(custom)),
|
|
46
|
+
* })
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function provideHotkeysContext(options?: ProvideHotkeysContextOptions): void;
|
|
15
50
|
export declare function useHotkeysContext(): HotkeysContextValue | null;
|
|
16
51
|
export declare function useDefaultHotkeysOptions(): HotkeysProviderOptions;
|
|
17
52
|
//#endregion
|
|
@@ -1,16 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppHotkeysStore, publishAppHotkeysStore } from "@tanstack/hotkeys";
|
|
2
|
+
import { inject, onScopeDispose, provide, toValue, watch } from "vue";
|
|
2
3
|
|
|
3
4
|
//#region src/HotkeysProviderContext.ts
|
|
4
5
|
const HotkeysContext = Symbol("HotkeysContext");
|
|
5
6
|
const DEFAULT_OPTIONS = {};
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Provides default options, app hotkeys, and the user's custom hotkeys to
|
|
9
|
+
* descendants. `HotkeysProvider` calls this; call it directly in a root
|
|
10
|
+
* component's setup instead of rendering the provider.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* provideHotkeysContext({
|
|
15
|
+
* appHotkeys,
|
|
16
|
+
* customHotkeys: JSON.parse(localStorage.getItem('hotkeys') ?? '{}'),
|
|
17
|
+
* onCustomHotkeysChange: (custom) =>
|
|
18
|
+
* localStorage.setItem('hotkeys', JSON.stringify(custom)),
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function provideHotkeysContext(options = {}) {
|
|
23
|
+
const appHotkeys = toValue(options.appHotkeys);
|
|
24
|
+
const store = appHotkeys ? new AppHotkeysStore(appHotkeys, {
|
|
25
|
+
customHotkeys: options.customHotkeys,
|
|
26
|
+
onCustomHotkeysChange: (custom) => options.onCustomHotkeysChange?.(custom)
|
|
27
|
+
}) : null;
|
|
28
|
+
if (store) {
|
|
29
|
+
watch(() => toValue(options.appHotkeys), (next) => {
|
|
30
|
+
if (next) store.setAppHotkeys(next);
|
|
31
|
+
});
|
|
32
|
+
if (typeof document !== "undefined") onScopeDispose(publishAppHotkeysStore(store));
|
|
33
|
+
}
|
|
34
|
+
provide(HotkeysContext, {
|
|
35
|
+
appHotkeysStore: store,
|
|
36
|
+
get defaultOptions() {
|
|
37
|
+
return toValue(options.defaultOptions) ?? DEFAULT_OPTIONS;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
8
40
|
}
|
|
9
41
|
function useHotkeysContext() {
|
|
10
42
|
return inject(HotkeysContext, null);
|
|
11
43
|
}
|
|
12
44
|
function useDefaultHotkeysOptions() {
|
|
13
|
-
return inject(HotkeysContext, null)?.defaultOptions ??
|
|
45
|
+
return inject(HotkeysContext, null)?.defaultOptions ?? DEFAULT_OPTIONS;
|
|
14
46
|
}
|
|
15
47
|
|
|
16
48
|
//#endregion
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useHotkeysContext } from "./HotkeysProviderContext.js";
|
|
2
|
+
import { Store, useSelector } from "@tanstack/vue-store";
|
|
3
|
+
|
|
4
|
+
//#region src/defaultOptions.ts
|
|
5
|
+
/** Captures the context once and reads current defaults inside reactive computations. */
|
|
6
|
+
function useDefaultHotkeysOptionsSource() {
|
|
7
|
+
const context = useHotkeysContext();
|
|
8
|
+
return () => context?.defaultOptions ?? {};
|
|
9
|
+
}
|
|
10
|
+
const NO_APP_HOTKEYS = new Store(null);
|
|
11
|
+
/**
|
|
12
|
+
* The provider's app hotkeys store and a ref that tracks its state, so
|
|
13
|
+
* watchers re-run when app hotkeys or custom hotkeys change.
|
|
14
|
+
*/
|
|
15
|
+
function useAppHotkeysStoreSource() {
|
|
16
|
+
const store = useHotkeysContext()?.appHotkeysStore ?? null;
|
|
17
|
+
return {
|
|
18
|
+
store,
|
|
19
|
+
state: useSelector(store?.store ?? NO_APP_HOTKEYS, (value) => value)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useAppHotkeysStoreSource, useDefaultHotkeysOptionsSource };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { UseHotkeyOptions, useHotkey } from "./useHotkey.js";
|
|
2
|
-
import {
|
|
3
|
-
import { HotkeysProviderOptions, provideHotkeysContext, useDefaultHotkeysOptions, useHotkeysContext } from "./HotkeysProviderContext.js";
|
|
1
|
+
import { UseAppHotkeyOptions, UseHotkeyChordOptions, UseHotkeyCommonOptions, UseHotkeyOptions, UseHotkeyOptionsFor, UseHotkeySequenceOptions, UseHotkeyTarget, useHotkey } from "./useHotkey.js";
|
|
2
|
+
import { HotkeysProviderOptions, ProvideHotkeysContextOptions, provideHotkeysContext, useDefaultHotkeysOptions, useHotkeysContext } from "./HotkeysProviderContext.js";
|
|
4
3
|
import { HotkeysProvider } from "./HotkeysProvider.js";
|
|
5
4
|
import { UseHotkeyDefinition, useHotkeys } from "./useHotkeys.js";
|
|
6
5
|
import { useHeldKeys } from "./useHeldKeys.js";
|
|
7
6
|
import { useHeldKeyCodes } from "./useHeldKeyCodes.js";
|
|
8
7
|
import { useKeyHold } from "./useKeyHold.js";
|
|
9
|
-
import { UseHotkeySequenceDefinition, useHotkeySequences } from "./useHotkeySequences.js";
|
|
10
8
|
import { VueHotkeyRecorder, useHotkeyRecorder } from "./useHotkeyRecorder.js";
|
|
11
|
-
import {
|
|
12
|
-
import { VueHotkeySequenceRecorder, useHotkeySequenceRecorder } from "./useHotkeySequenceRecorder.js";
|
|
9
|
+
import { useHotkeyRegistrations } from "./useHotkeyRegistrations.js";
|
|
13
10
|
import { useHotkeyHint } from "./useHotkeyHint.js";
|
|
11
|
+
import { UseCustomHotkeysResult, useAppHotkeyList, useAppHotkeys, useCustomHotkeys } from "./useAppHotkeys.js";
|
|
14
12
|
export * from "@tanstack/hotkeys";
|
|
15
|
-
export {
|
|
13
|
+
export { HotkeysProvider, HotkeysProviderOptions, ProvideHotkeysContextOptions, UseAppHotkeyOptions, UseCustomHotkeysResult, UseHotkeyChordOptions, UseHotkeyCommonOptions, UseHotkeyDefinition, UseHotkeyOptions, UseHotkeyOptionsFor, UseHotkeySequenceOptions, UseHotkeyTarget, VueHotkeyRecorder, provideHotkeysContext, useAppHotkeyList, useAppHotkeys, useCustomHotkeys, useDefaultHotkeysOptions, useHeldKeyCodes, useHeldKeys, useHotkey, useHotkeyHint, useHotkeyRecorder, useHotkeyRegistrations, useHotkeys, useHotkeysContext, useKeyHold };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { provideHotkeysContext, useDefaultHotkeysOptions, useHotkeysContext } from "./HotkeysProviderContext.js";
|
|
2
2
|
import { HotkeysProvider } from "./HotkeysProvider.js";
|
|
3
|
-
import { useHotkey } from "./useHotkey.js";
|
|
4
3
|
import { useHotkeys } from "./useHotkeys.js";
|
|
4
|
+
import { useHotkey } from "./useHotkey.js";
|
|
5
5
|
import { useHeldKeys } from "./useHeldKeys.js";
|
|
6
6
|
import { useHeldKeyCodes } from "./useHeldKeyCodes.js";
|
|
7
7
|
import { useKeyHold } from "./useKeyHold.js";
|
|
8
|
-
import { useHotkeySequence } from "./useHotkeySequence.js";
|
|
9
|
-
import { useHotkeySequences } from "./useHotkeySequences.js";
|
|
10
8
|
import { useHotkeyRecorder } from "./useHotkeyRecorder.js";
|
|
11
9
|
import { useHotkeyRegistrations } from "./useHotkeyRegistrations.js";
|
|
12
|
-
import { useHotkeySequenceRecorder } from "./useHotkeySequenceRecorder.js";
|
|
13
10
|
import { useHotkeyHint } from "./useHotkeyHint.js";
|
|
11
|
+
import { useAppHotkeyList, useAppHotkeys, useCustomHotkeys } from "./useAppHotkeys.js";
|
|
14
12
|
|
|
15
13
|
export * from "@tanstack/hotkeys"
|
|
16
14
|
|
|
17
|
-
export { HotkeysProvider, provideHotkeysContext, useDefaultHotkeysOptions, useHeldKeyCodes, useHeldKeys, useHotkey, useHotkeyHint, useHotkeyRecorder, useHotkeyRegistrations,
|
|
15
|
+
export { HotkeysProvider, provideHotkeysContext, useAppHotkeyList, useAppHotkeys, useCustomHotkeys, useDefaultHotkeysOptions, useHeldKeyCodes, useHeldKeys, useHotkey, useHotkeyHint, useHotkeyRecorder, useHotkeyRegistrations, useHotkeys, useHotkeysContext, useKeyHold };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AppHotkey, AppHotkeyListItem, CustomHotkeys, Hotkey, RegisteredAppHotkeys } from "@tanstack/hotkeys";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
//#region src/useAppHotkeys.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns a computed ref of the effective app hotkeys from `HotkeysProvider`,
|
|
6
|
+
* typed by `Register`: each declaration with the user's custom hotkey applied.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const hotkeys = useAppHotkeys()
|
|
11
|
+
* useHotkey(() => hotkeys.value['doc.save'], () => save())
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function useAppHotkeys(): ComputedRef<RegisteredAppHotkeys>;
|
|
15
|
+
/**
|
|
16
|
+
* Lists every app hotkey with its live status, in declaration order, for
|
|
17
|
+
* cheat sheets and settings screens. App hotkeys whose components have not
|
|
18
|
+
* mounted are `'inactive'`; those without a hotkey are `'unbound'`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function useAppHotkeyList(): ComputedRef<Array<AppHotkeyListItem<RegisteredAppHotkeys[keyof RegisteredAppHotkeys]>>>;
|
|
21
|
+
/** Custom hotkey state and actions returned by `useCustomHotkeys`. */
|
|
22
|
+
export interface UseCustomHotkeysResult {
|
|
23
|
+
/** The user's hotkeys that differ from the defaults. */
|
|
24
|
+
customHotkeys: ComputedRef<CustomHotkeys>;
|
|
25
|
+
/**
|
|
26
|
+
* Sets the user's hotkey for an app hotkey. `null` unbinds it.
|
|
27
|
+
* Returns conflicting app hotkeys; when any exist, nothing changes.
|
|
28
|
+
*/
|
|
29
|
+
setCustomHotkey: (id: keyof RegisteredAppHotkeys & string, hotkey: Hotkey | null) => Array<AppHotkey>;
|
|
30
|
+
/** Restores the default hotkey for an app hotkey. */
|
|
31
|
+
resetCustomHotkey: (id: keyof RegisteredAppHotkeys & string) => void;
|
|
32
|
+
/** Restores every default hotkey. */
|
|
33
|
+
resetCustomHotkeys: () => void;
|
|
34
|
+
/** Other app hotkeys that would collide if `id` used `hotkey`. */
|
|
35
|
+
findConflicts: (id: keyof RegisteredAppHotkeys & string, hotkey: Hotkey) => Array<AppHotkey>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reads and changes the user's custom hotkeys. Changes apply to every
|
|
39
|
+
* registered app hotkey immediately and are emitted by the provider as
|
|
40
|
+
* `custom-hotkeys-change`, ready to save.
|
|
41
|
+
*/
|
|
42
|
+
export declare function useCustomHotkeys(): UseCustomHotkeysResult;
|
|
43
|
+
//#endregion
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useAppHotkeysStoreSource } from "./defaultOptions.js";
|
|
2
|
+
import { useHotkeyRegistrations } from "./useHotkeyRegistrations.js";
|
|
3
|
+
import { computed } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/useAppHotkeys.ts
|
|
6
|
+
function useRequiredStore(name) {
|
|
7
|
+
const source = useAppHotkeysStoreSource();
|
|
8
|
+
if (!source.store) throw new Error(`${name} requires a HotkeysProvider with app hotkeys`);
|
|
9
|
+
return {
|
|
10
|
+
store: source.store,
|
|
11
|
+
state: source.state
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns a computed ref of the effective app hotkeys from `HotkeysProvider`,
|
|
16
|
+
* typed by `Register`: each declaration with the user's custom hotkey applied.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const hotkeys = useAppHotkeys()
|
|
21
|
+
* useHotkey(() => hotkeys.value['doc.save'], () => save())
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
function useAppHotkeys() {
|
|
25
|
+
const { store, state } = useRequiredStore("useAppHotkeys");
|
|
26
|
+
return computed(() => {
|
|
27
|
+
state.value;
|
|
28
|
+
return store.appHotkeys;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lists every app hotkey with its live status, in declaration order, for
|
|
33
|
+
* cheat sheets and settings screens. App hotkeys whose components have not
|
|
34
|
+
* mounted are `'inactive'`; those without a hotkey are `'unbound'`.
|
|
35
|
+
*/
|
|
36
|
+
function useAppHotkeyList() {
|
|
37
|
+
const { store, state } = useRequiredStore("useAppHotkeyList");
|
|
38
|
+
const registrations = useHotkeyRegistrations();
|
|
39
|
+
return computed(() => {
|
|
40
|
+
state.value;
|
|
41
|
+
return store.getList(registrations.value);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reads and changes the user's custom hotkeys. Changes apply to every
|
|
46
|
+
* registered app hotkey immediately and are emitted by the provider as
|
|
47
|
+
* `custom-hotkeys-change`, ready to save.
|
|
48
|
+
*/
|
|
49
|
+
function useCustomHotkeys() {
|
|
50
|
+
const { store, state } = useRequiredStore("useCustomHotkeys");
|
|
51
|
+
return {
|
|
52
|
+
customHotkeys: computed(() => {
|
|
53
|
+
state.value;
|
|
54
|
+
return store.customHotkeys;
|
|
55
|
+
}),
|
|
56
|
+
setCustomHotkey: (id, hotkey) => store.setCustomHotkey(id, hotkey),
|
|
57
|
+
resetCustomHotkey: (id) => store.resetCustomHotkey(id),
|
|
58
|
+
resetCustomHotkeys: () => store.resetCustomHotkeys(),
|
|
59
|
+
findConflicts: (id, hotkey) => store.findConflicts(id, hotkey)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { useAppHotkeyList, useAppHotkeys, useCustomHotkeys };
|
package/dist/useHotkey.d.ts
CHANGED
|
@@ -1,83 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppHotkey, HotkeyCallback, RegisterableHotkey, Target } from "@tanstack/hotkeys";
|
|
2
2
|
import { MaybeRefOrGetter } from "vue";
|
|
3
|
+
import { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from "@tanstack/hotkeys/adapter";
|
|
3
4
|
//#region src/useHotkey.d.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The element to listen on: a ref, getter, element, or null. A target that
|
|
7
|
+
* resolves to `null` skips registration until it is set. Defaults to document.
|
|
8
|
+
*/
|
|
9
|
+
export type UseHotkeyTarget = MaybeRefOrGetter<Target | null>;
|
|
10
|
+
/** Lets `enabled` be a ref or getter. */
|
|
11
|
+
type WithReactiveEnabled<TOptions> = Omit<TOptions, 'enabled'> & {
|
|
12
|
+
/** Whether the hotkey is active. Can be a ref, getter, or boolean. Defaults to true. */
|
|
10
13
|
enabled?: MaybeRefOrGetter<boolean>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
};
|
|
15
|
+
/** Options shared by chords and sequences. */
|
|
16
|
+
export type UseHotkeyOptions = WithReactiveEnabled<AdapterHotkeyOptions<UseHotkeyTarget>>;
|
|
17
|
+
/** Options for a chord such as `'Mod+S'`. */
|
|
18
|
+
export type UseHotkeyChordOptions = WithReactiveEnabled<AdapterChordOptions<UseHotkeyTarget>>;
|
|
19
|
+
/** Options for a sequence such as `['G', 'G']`. */
|
|
20
|
+
export type UseHotkeySequenceOptions = WithReactiveEnabled<AdapterSequenceOptions<UseHotkeyTarget>>;
|
|
21
|
+
/** Options applied to every hotkey, such as provider defaults. Each applies to the kinds that support it. */
|
|
22
|
+
export type UseHotkeyCommonOptions = WithReactiveEnabled<AdapterCommonOptions<UseHotkeyTarget>>;
|
|
23
|
+
/** The options type for a hotkey: chord options for chords, sequence options for sequences. */
|
|
24
|
+
export type UseHotkeyOptionsFor<T extends RegisterableHotkey> = WithReactiveEnabled<AdapterOptionsFor<T, UseHotkeyTarget>>;
|
|
25
|
+
/** Call-site options for an app hotkey, typed by its declared default kind. */
|
|
26
|
+
export type UseAppHotkeyOptions<T extends AppHotkey = AppHotkey> = WithReactiveEnabled<AdapterAppHotkeyOptions<T, UseHotkeyTarget>>;
|
|
18
27
|
/**
|
|
19
|
-
* Vue composable for registering a
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* The callback receives both the keyboard event and a context object
|
|
23
|
-
* containing the hotkey string and parsed hotkey.
|
|
24
|
-
*
|
|
25
|
-
* This composable automatically tracks reactive dependencies and updates
|
|
26
|
-
* the registration when options or the callback change.
|
|
27
|
-
*
|
|
28
|
-
* @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)
|
|
29
|
-
* @param callback - The function to call when the hotkey is pressed
|
|
30
|
-
* @param options - Options for the hotkey behavior
|
|
28
|
+
* Vue composable for registering a hotkey: a chord such as `'Mod+S'`, a
|
|
29
|
+
* sequence such as `['G', 'G']`, or an app hotkey from `defineAppHotkeys`.
|
|
30
|
+
* The hotkey and options may be refs or getters.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* import { useHotkey } from '@tanstack/vue-hotkeys'
|
|
37
|
-
*
|
|
38
|
-
* const count = ref(0)
|
|
39
|
-
*
|
|
40
|
-
* // Callback always has access to latest count value
|
|
41
|
-
* useHotkey('Mod+S', (event, { hotkey }) => {
|
|
42
|
-
* console.log(`Save triggered, count is ${count.value}`)
|
|
43
|
-
* handleSave()
|
|
44
|
-
* })
|
|
45
|
-
* </script>
|
|
46
|
-
* ```
|
|
32
|
+
* Chords accept `requireReset`; sequences accept `timeout`. A one-step
|
|
33
|
+
* sequence registers as its chord. An app hotkey uses its effective hotkey
|
|
34
|
+
* from `HotkeysProvider` (including the user's custom hotkey) and its
|
|
35
|
+
* declared meta and options, and registers nothing while unbound.
|
|
47
36
|
*
|
|
48
37
|
* @example
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* const isOpen = ref(false)
|
|
55
|
-
*
|
|
56
|
-
* // enabled option is reactive
|
|
57
|
-
* useHotkey('Escape', () => {
|
|
58
|
-
* isOpen.value = false
|
|
59
|
-
* }, { enabled: isOpen })
|
|
60
|
-
* </script>
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```vue
|
|
65
|
-
* <script setup>
|
|
66
|
-
* import { ref } from 'vue'
|
|
67
|
-
* import { useHotkey } from '@tanstack/vue-hotkeys'
|
|
68
|
-
*
|
|
69
|
-
* const editorRef = ref<HTMLDivElement | null>(null)
|
|
70
|
-
*
|
|
71
|
-
* // Scoped to a specific element
|
|
72
|
-
* useHotkey('Mod+S', () => {
|
|
73
|
-
* save()
|
|
74
|
-
* }, { target: editorRef })
|
|
75
|
-
* </script>
|
|
76
|
-
*
|
|
77
|
-
* <template>
|
|
78
|
-
* <div ref="editorRef">...</div>
|
|
79
|
-
* </template>
|
|
38
|
+
* ```ts
|
|
39
|
+
* useHotkey('Mod+S', () => save())
|
|
40
|
+
* useHotkey(['G', 'G'], () => scrollToTop(), { timeout: 500 })
|
|
41
|
+
* useHotkey('Escape', () => close(), { enabled: isOpen })
|
|
80
42
|
* ```
|
|
81
43
|
*/
|
|
82
|
-
export declare function useHotkey(hotkey: MaybeRefOrGetter<
|
|
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, options?: MaybeRefOrGetter<UseHotkeyOptionsFor<T>>): void;
|
|
83
46
|
//#endregion
|