@tanstack/svelte-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/HotkeysCtx.d.ts +12 -2
- package/dist/HotkeysCtx.js +28 -4
- package/dist/HotkeysProvider.svelte +6 -0
- package/dist/createHotkey.svelte.d.ts +3 -3
- package/dist/createHotkeyRecorder.svelte.d.ts +1 -1
- package/dist/createHotkeys.svelte.d.ts +4 -4
- package/dist/getAppHotkeys.svelte.d.ts +2 -2
- package/dist/getAppHotkeys.svelte.js +2 -2
- package/dist/internal.svelte.d.ts +5 -0
- package/dist/internal.svelte.js +9 -0
- 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
|
|
package/dist/HotkeysCtx.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AppHotkeysStore } from '@tanstack/hotkeys';
|
|
2
2
|
import type { AppHotkeys, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from '@tanstack/hotkeys';
|
|
3
|
+
import type { HotkeysProviderScopeProps } from '@tanstack/hotkeys/adapter';
|
|
3
4
|
import type { CreateHotkeyCommonOptions } from './createHotkey.svelte';
|
|
4
5
|
import type { Snippet } from 'svelte';
|
|
5
6
|
export interface HotkeysProviderOptions {
|
|
@@ -12,7 +13,8 @@ export interface HotkeysProviderOptions {
|
|
|
12
13
|
hotkeyRecorder?: Partial<Omit<HotkeyChordRecorderOptions & HotkeySequenceRecorderOptions, 'maxSteps' | 'onRecord' | 'validate'>>;
|
|
13
14
|
}
|
|
14
15
|
/** Options for `setHotkeysContext` and props for `HotkeysProvider`. */
|
|
15
|
-
export interface HotkeysContextOptions {
|
|
16
|
+
export interface HotkeysContextOptions extends HotkeysProviderScopeProps {
|
|
17
|
+
/** Merged with the parent context's defaults. */
|
|
16
18
|
defaultOptions?: HotkeysProviderOptions;
|
|
17
19
|
/**
|
|
18
20
|
* Every app hotkey, from `defineAppHotkeys`. Read when the context is set;
|
|
@@ -33,11 +35,19 @@ export interface HotkeysProviderProps extends HotkeysContextOptions {
|
|
|
33
35
|
export declare const DEFAULT_OPTIONS: HotkeysProviderOptions;
|
|
34
36
|
interface HotkeysContextValue {
|
|
35
37
|
readonly appHotkeysStore: AppHotkeysStore | null;
|
|
38
|
+
/** Merged with every ancestor's defaults, including `hotkey.scope`. */
|
|
36
39
|
readonly defaultOptions: HotkeysProviderOptions;
|
|
40
|
+
/** Whether this context and every ancestor are enabled. */
|
|
41
|
+
readonly enabled: boolean;
|
|
37
42
|
}
|
|
38
43
|
/**
|
|
39
44
|
* Sets the hotkeys context for descendants. `HotkeysProvider` calls this; call
|
|
40
|
-
* it directly in a
|
|
45
|
+
* it directly in a component's script instead of rendering the provider.
|
|
46
|
+
*
|
|
47
|
+
* Nest contexts to create hotkey scopes. A nested context inherits app
|
|
48
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
49
|
+
* while the component is mounted and enabled; with `exclusive`, only its
|
|
50
|
+
* hotkeys fire.
|
|
41
51
|
*
|
|
42
52
|
* @example
|
|
43
53
|
* ```svelte
|
package/dist/HotkeysCtx.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { createContext, onMount } from 'svelte';
|
|
2
2
|
import { AppHotkeysStore, publishAppHotkeysStore } from '@tanstack/hotkeys';
|
|
3
|
+
import { getHotkeysProviderScopeKey, mergeHotkeysProviderDefaults, } from '@tanstack/hotkeys/adapter';
|
|
4
|
+
import { activateScopeWhileMounted } from './internal.svelte';
|
|
3
5
|
export const DEFAULT_OPTIONS = {};
|
|
4
6
|
const [useHotkeysContext, setHotkeysContextValue] = createContext();
|
|
5
7
|
/**
|
|
6
8
|
* Sets the hotkeys context for descendants. `HotkeysProvider` calls this; call
|
|
7
|
-
* it directly in a
|
|
9
|
+
* it directly in a component's script instead of rendering the provider.
|
|
10
|
+
*
|
|
11
|
+
* Nest contexts to create hotkey scopes. A nested context inherits app
|
|
12
|
+
* hotkeys and merges default options. With `scope`, its hotkeys fire only
|
|
13
|
+
* while the component is mounted and enabled; with `exclusive`, only its
|
|
14
|
+
* hotkeys fire.
|
|
8
15
|
*
|
|
9
16
|
* @example
|
|
10
17
|
* ```svelte
|
|
@@ -23,6 +30,7 @@ export function setHotkeysContext(options = {}) {
|
|
|
23
30
|
}
|
|
24
31
|
/** Sets the context from a getter, so default options stay reactive. */
|
|
25
32
|
export function setHotkeysContextSource(source) {
|
|
33
|
+
const parent = getHotkeysContext();
|
|
26
34
|
const { appHotkeys, customHotkeys } = source();
|
|
27
35
|
const store = appHotkeys
|
|
28
36
|
? new AppHotkeysStore(appHotkeys, {
|
|
@@ -33,12 +41,28 @@ export function setHotkeysContextSource(source) {
|
|
|
33
41
|
// Publish the store so devtools can list declared hotkeys.
|
|
34
42
|
if (store)
|
|
35
43
|
onMount(() => publishAppHotkeysStore(store));
|
|
36
|
-
|
|
37
|
-
appHotkeysStore: store,
|
|
44
|
+
const context = setHotkeysContextValue({
|
|
45
|
+
appHotkeysStore: store ?? parent?.appHotkeysStore ?? null,
|
|
38
46
|
get defaultOptions() {
|
|
39
|
-
|
|
47
|
+
const { defaultOptions, scope } = source();
|
|
48
|
+
return mergeHotkeysProviderDefaults(parent?.defaultOptions, defaultOptions, scope);
|
|
49
|
+
},
|
|
50
|
+
get enabled() {
|
|
51
|
+
return (parent?.enabled ?? true) && source().enabled !== false;
|
|
40
52
|
},
|
|
41
53
|
});
|
|
54
|
+
// Compared by value, so a new `exclusive` object does not reactivate the
|
|
55
|
+
// scope and lose its precedence.
|
|
56
|
+
activateScopeWhileMounted(() => {
|
|
57
|
+
const { scope, exclusive } = source();
|
|
58
|
+
return getHotkeysProviderScopeKey({
|
|
59
|
+
scope,
|
|
60
|
+
exclusive,
|
|
61
|
+
active: context.enabled,
|
|
62
|
+
parent: parent?.defaultOptions.hotkey?.scope,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
return context;
|
|
42
66
|
}
|
|
43
67
|
export function getHotkeysContext() {
|
|
44
68
|
try {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
appHotkeys,
|
|
10
10
|
customHotkeys,
|
|
11
11
|
onCustomHotkeysChange,
|
|
12
|
+
scope,
|
|
13
|
+
exclusive,
|
|
14
|
+
enabled,
|
|
12
15
|
}: HotkeysProviderProps = $props()
|
|
13
16
|
|
|
14
17
|
const context = setHotkeysContextSource(() => ({
|
|
@@ -16,6 +19,9 @@
|
|
|
16
19
|
appHotkeys,
|
|
17
20
|
customHotkeys,
|
|
18
21
|
onCustomHotkeysChange,
|
|
22
|
+
scope,
|
|
23
|
+
exclusive,
|
|
24
|
+
enabled,
|
|
19
25
|
}))
|
|
20
26
|
|
|
21
27
|
// Keep declarations current (for example after hot module replacement).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Attachment } from 'svelte/attachments';
|
|
2
|
-
import type { AppHotkey, HotkeyCallback, RegisterableHotkey } from '@tanstack/hotkeys';
|
|
2
|
+
import type { AppHotkey, HotkeyCallback, HotkeyCallbackContextFor, RegisterableHotkey } from '@tanstack/hotkeys';
|
|
3
3
|
import type { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from '@tanstack/hotkeys/adapter';
|
|
4
4
|
import type { MaybeGetter } from './internal.svelte';
|
|
5
5
|
/** The document or window to listen on. Use an attachment for elements. */
|
|
@@ -37,7 +37,7 @@ export type CreateAppHotkeyOptions<T extends AppHotkey = AppHotkey> = AdapterApp
|
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
39
|
export declare function createHotkey<T extends AppHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback, options?: MaybeGetter<CreateAppHotkeyOptions<T>>): void;
|
|
40
|
-
export declare function createHotkey<T extends RegisterableHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback
|
|
40
|
+
export declare function createHotkey<const T extends RegisterableHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: MaybeGetter<CreateHotkeyOptionsFor<T>>): void;
|
|
41
41
|
/**
|
|
42
42
|
* Create an attachment for an element-scoped hotkey: a chord, a sequence, or
|
|
43
43
|
* an app hotkey that listens on the attached element.
|
|
@@ -52,4 +52,4 @@ export declare function createHotkey<T extends RegisterableHotkey>(hotkey: Maybe
|
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
54
|
export declare function createHotkeyAttachment<T extends AppHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback, options?: MaybeGetter<CreateAppHotkeyOptions<T>>): Attachment<HTMLElement>;
|
|
55
|
-
export declare function createHotkeyAttachment<T extends RegisterableHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback
|
|
55
|
+
export declare function createHotkeyAttachment<const T extends RegisterableHotkey>(hotkey: MaybeGetter<T>, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: MaybeGetter<CreateHotkeyOptionsFor<T>>): Attachment<HTMLElement>;
|
|
@@ -27,7 +27,7 @@ export interface SvelteHotkeyRecorder<THotkey extends Hotkey = Hotkey> {
|
|
|
27
27
|
* ```svelte
|
|
28
28
|
* <script lang="ts">
|
|
29
29
|
* const recorder = createHotkeyRecorder({ onRecord: (hotkey) => (shortcut = hotkey) })
|
|
30
|
-
* const sequenceRecorder = createHotkeyRecorder({ maxSteps:
|
|
30
|
+
* const sequenceRecorder = createHotkeyRecorder({ maxSteps: Infinity, onRecord: save })
|
|
31
31
|
* </script>
|
|
32
32
|
*
|
|
33
33
|
* <button onclick={recorder.startRecording}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Attachment } from 'svelte/attachments';
|
|
2
|
-
import type { AppHotkey, HotkeyCallback,
|
|
2
|
+
import type { AppHotkey, HotkeyCallback, RegisterableHotkey, RegisterableHotkeyChord, RegisterableHotkeySequence } from '@tanstack/hotkeys';
|
|
3
3
|
import type { MaybeGetter } from './internal.svelte';
|
|
4
4
|
import type { CreateAppHotkeyOptions, CreateHotkeyChordOptions, CreateHotkeyCommonOptions, CreateHotkeyOptions, CreateHotkeySequenceOptions } from './createHotkey.svelte';
|
|
5
5
|
/**
|
|
@@ -8,15 +8,15 @@ import type { CreateAppHotkeyOptions, CreateHotkeyChordOptions, CreateHotkeyComm
|
|
|
8
8
|
* kind accept only shared options.
|
|
9
9
|
*/
|
|
10
10
|
export type CreateHotkeyDefinition = {
|
|
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: MaybeGetter<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?: MaybeGetter<CreateHotkeyChordOptions>;
|
|
17
17
|
} | {
|
|
18
|
-
/** A sequence such as `['G', 'G']
|
|
19
|
-
hotkey: MaybeGetter<
|
|
18
|
+
/** A sequence such as `['G', 'G']`, with each step a string or an object */
|
|
19
|
+
hotkey: MaybeGetter<RegisterableHotkeySequence>;
|
|
20
20
|
callback: HotkeyCallback;
|
|
21
21
|
options?: MaybeGetter<CreateHotkeySequenceOptions>;
|
|
22
22
|
} | {
|
|
@@ -10,8 +10,8 @@ export interface SvelteAppHotkeys {
|
|
|
10
10
|
* @example
|
|
11
11
|
* ```svelte
|
|
12
12
|
* <script lang="ts">
|
|
13
|
-
* const
|
|
14
|
-
* createHotkey(() =>
|
|
13
|
+
* const appHotkeys = getAppHotkeys()
|
|
14
|
+
* createHotkey(() => appHotkeys.current['doc.save'], () => save())
|
|
15
15
|
* </script>
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
@@ -18,8 +18,8 @@ function requireStore(name) {
|
|
|
18
18
|
* @example
|
|
19
19
|
* ```svelte
|
|
20
20
|
* <script lang="ts">
|
|
21
|
-
* const
|
|
22
|
-
* createHotkey(() =>
|
|
21
|
+
* const appHotkeys = getAppHotkeys()
|
|
22
|
+
* createHotkey(() => appHotkeys.current['doc.save'], () => save())
|
|
23
23
|
* </script>
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
@@ -13,4 +13,9 @@ export declare function createStoreSubscriber<TState>(store: SubscribableStore<T
|
|
|
13
13
|
* hotkeys store, so it re-runs when app hotkeys or custom hotkeys change.
|
|
14
14
|
*/
|
|
15
15
|
export declare function createAppHotkeysSubscriber(store: AppHotkeysStore | null): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Activates a provider's scope while the component is mounted, and again
|
|
18
|
+
* whenever the key from `getHotkeysProviderScopeKey` changes.
|
|
19
|
+
*/
|
|
20
|
+
export declare function activateScopeWhileMounted(getKey: () => string | null): void;
|
|
16
21
|
export {};
|
package/dist/internal.svelte.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createSubscriber } from 'svelte/reactivity';
|
|
2
|
+
import { activateHotkeysProviderScope } from '@tanstack/hotkeys/adapter';
|
|
2
3
|
export function resolveMaybeGetter(value) {
|
|
3
4
|
return typeof value === 'function' ? value() : value;
|
|
4
5
|
}
|
|
@@ -18,3 +19,11 @@ const noop = () => { };
|
|
|
18
19
|
export function createAppHotkeysSubscriber(store) {
|
|
19
20
|
return store ? createStoreSubscriber(store.store) : noop;
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Activates a provider's scope while the component is mounted, and again
|
|
24
|
+
* whenever the key from `getHotkeysProviderScopeKey` changes.
|
|
25
|
+
*/
|
|
26
|
+
export function activateScopeWhileMounted(getKey) {
|
|
27
|
+
const key = $derived(getKey());
|
|
28
|
+
$effect(() => (key ? activateHotkeysProviderScope(key) : undefined));
|
|
29
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/svelte-hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Svelte adapter for TanStack Hotkeys",
|
|
5
5
|
"author": "Kunal Rao",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@tanstack/hotkeys": "0.
|
|
42
|
+
"@tanstack/hotkeys": "0.16.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@sveltejs/package": "^3.0.0",
|