@tanstack/svelte-hotkeys 0.13.0 → 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.
@@ -1,23 +1,59 @@
1
- import type { HotkeyRecorderOptions, HotkeySequenceRecorderOptions } from '@tanstack/hotkeys';
2
- import type { CreateHotkeyOptions } from './createHotkey.svelte';
1
+ import { AppHotkeysStore } from '@tanstack/hotkeys';
2
+ import type { AppHotkeys, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from '@tanstack/hotkeys';
3
+ import type { CreateHotkeyCommonOptions } from './createHotkey.svelte';
3
4
  import type { Snippet } from 'svelte';
4
- import type { CreateHotkeySequenceOptions } from './createHotkeySequence.svelte';
5
5
  export interface HotkeysProviderOptions {
6
- hotkey?: Partial<CreateHotkeyOptions>;
7
- hotkeyRecorder?: Partial<HotkeyRecorderOptions>;
8
- hotkeySequenceRecorder?: Partial<HotkeySequenceRecorderOptions>;
9
- hotkeySequence?: Partial<CreateHotkeySequenceOptions>;
6
+ /**
7
+ * Defaults for every hotkey registered by `createHotkey` and `createHotkeys`.
8
+ * `requireReset` applies to chords and `timeout` applies to sequences.
9
+ */
10
+ hotkey?: CreateHotkeyCommonOptions;
11
+ /** Defaults for every `createHotkeyRecorder`. */
12
+ hotkeyRecorder?: Partial<Omit<HotkeyChordRecorderOptions & HotkeySequenceRecorderOptions, 'maxSteps' | 'onRecord' | 'validate'>>;
10
13
  }
11
- export interface HotkeysProviderProps {
12
- children: Snippet;
14
+ /** Options for `setHotkeysContext` and props for `HotkeysProvider`. */
15
+ export interface HotkeysContextOptions {
13
16
  defaultOptions?: HotkeysProviderOptions;
17
+ /**
18
+ * Every app hotkey, from `defineAppHotkeys`. Read when the context is set;
19
+ * listed by `getAppHotkeyList` whether or not they are registered.
20
+ */
21
+ appHotkeys?: AppHotkeys;
22
+ /**
23
+ * Starting custom hotkeys, such as saved data. Read once; the context owns
24
+ * the state afterwards. Invalid entries are ignored with a warning.
25
+ */
26
+ customHotkeys?: CustomHotkeys | null;
27
+ /** Called with the custom hotkeys after every change, ready to save. */
28
+ onCustomHotkeysChange?: (customHotkeys: CustomHotkeys) => void;
29
+ }
30
+ export interface HotkeysProviderProps extends HotkeysContextOptions {
31
+ children: Snippet;
14
32
  }
15
33
  export declare const DEFAULT_OPTIONS: HotkeysProviderOptions;
16
34
  interface HotkeysContextValue {
17
- defaultOptions: HotkeysProviderOptions;
35
+ readonly appHotkeysStore: AppHotkeysStore | null;
36
+ readonly defaultOptions: HotkeysProviderOptions;
18
37
  }
19
- export declare function setHotkeysContext(defaultOptions?: HotkeysProviderOptions): HotkeysContextValue;
20
- export declare function setHotkeysContextSource(defaultOptions: () => HotkeysProviderOptions): HotkeysContextValue;
38
+ /**
39
+ * Sets the hotkeys context for descendants. `HotkeysProvider` calls this; call
40
+ * it directly in a root component's script instead of rendering the provider.
41
+ *
42
+ * @example
43
+ * ```svelte
44
+ * <script lang="ts">
45
+ * setHotkeysContext({
46
+ * appHotkeys,
47
+ * customHotkeys: JSON.parse(localStorage.getItem('hotkeys') ?? '{}'),
48
+ * onCustomHotkeysChange: (custom) =>
49
+ * localStorage.setItem('hotkeys', JSON.stringify(custom)),
50
+ * })
51
+ * </script>
52
+ * ```
53
+ */
54
+ export declare function setHotkeysContext(options?: HotkeysContextOptions): HotkeysContextValue;
55
+ /** Sets the context from a getter, so default options stay reactive. */
56
+ export declare function setHotkeysContextSource(source: () => HotkeysContextOptions): HotkeysContextValue;
21
57
  export declare function getHotkeysContext(): HotkeysContextValue | null;
22
58
  export declare function getDefaultHotkeysOptions(): HotkeysProviderOptions;
23
59
  export {};
@@ -1,17 +1,42 @@
1
- import { createContext } from 'svelte';
1
+ import { createContext, onMount } from 'svelte';
2
+ import { AppHotkeysStore, publishAppHotkeysStore } from '@tanstack/hotkeys';
2
3
  export const DEFAULT_OPTIONS = {};
3
4
  const [useHotkeysContext, setHotkeysContextValue] = createContext();
4
- export function setHotkeysContext(defaultOptions = DEFAULT_OPTIONS) {
5
- return setHotkeysContextValue({
6
- get defaultOptions() {
7
- return defaultOptions;
8
- },
9
- });
5
+ /**
6
+ * Sets the hotkeys context for descendants. `HotkeysProvider` calls this; call
7
+ * it directly in a root component's script instead of rendering the provider.
8
+ *
9
+ * @example
10
+ * ```svelte
11
+ * <script lang="ts">
12
+ * setHotkeysContext({
13
+ * appHotkeys,
14
+ * customHotkeys: JSON.parse(localStorage.getItem('hotkeys') ?? '{}'),
15
+ * onCustomHotkeysChange: (custom) =>
16
+ * localStorage.setItem('hotkeys', JSON.stringify(custom)),
17
+ * })
18
+ * </script>
19
+ * ```
20
+ */
21
+ export function setHotkeysContext(options = {}) {
22
+ return setHotkeysContextSource(() => options);
10
23
  }
11
- export function setHotkeysContextSource(defaultOptions) {
24
+ /** Sets the context from a getter, so default options stay reactive. */
25
+ export function setHotkeysContextSource(source) {
26
+ const { appHotkeys, customHotkeys } = source();
27
+ const store = appHotkeys
28
+ ? new AppHotkeysStore(appHotkeys, {
29
+ customHotkeys,
30
+ onCustomHotkeysChange: (custom) => source().onCustomHotkeysChange?.(custom),
31
+ })
32
+ : null;
33
+ // Publish the store so devtools can list declared hotkeys.
34
+ if (store)
35
+ onMount(() => publishAppHotkeysStore(store));
12
36
  return setHotkeysContextValue({
37
+ appHotkeysStore: store,
13
38
  get defaultOptions() {
14
- return defaultOptions();
39
+ return source().defaultOptions ?? DEFAULT_OPTIONS;
15
40
  },
16
41
  });
17
42
  }
@@ -1,12 +1,27 @@
1
1
  <script lang="ts">
2
- import { DEFAULT_OPTIONS, setHotkeysContextSource } from './HotkeysCtx'
2
+ import { setHotkeysContextSource } from './HotkeysCtx'
3
3
 
4
4
  import type { HotkeysProviderProps } from './HotkeysCtx'
5
5
 
6
- let { children, defaultOptions = DEFAULT_OPTIONS }: HotkeysProviderProps =
7
- $props()
6
+ let {
7
+ children,
8
+ defaultOptions,
9
+ appHotkeys,
10
+ customHotkeys,
11
+ onCustomHotkeysChange,
12
+ }: HotkeysProviderProps = $props()
8
13
 
9
- setHotkeysContextSource(() => defaultOptions)
14
+ const context = setHotkeysContextSource(() => ({
15
+ defaultOptions,
16
+ appHotkeys,
17
+ customHotkeys,
18
+ onCustomHotkeysChange,
19
+ }))
20
+
21
+ // Keep declarations current (for example after hot module replacement).
22
+ $effect(() => {
23
+ if (appHotkeys) context.appHotkeysStore?.setAppHotkeys(appHotkeys)
24
+ })
10
25
  </script>
11
26
 
12
27
  {@render children()}
@@ -1,42 +1,55 @@
1
- import type { HotkeyCallback, HotkeyOptions, RegisterableHotkey } from '@tanstack/hotkeys';
2
- import type { MaybeGetter } from './internal.svelte';
3
1
  import type { Attachment } from 'svelte/attachments';
4
- export interface CreateHotkeyOptions extends Omit<HotkeyOptions, 'target'> {
5
- target?: Document | Window;
6
- }
2
+ import type { AppHotkey, HotkeyCallback, RegisterableHotkey } from '@tanstack/hotkeys';
3
+ import type { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from '@tanstack/hotkeys/adapter';
4
+ import type { MaybeGetter } from './internal.svelte';
5
+ /** The document or window to listen on. Use an attachment for elements. */
6
+ export type CreateHotkeyTarget = Document | Window;
7
+ /** Options shared by chords and sequences. */
8
+ export type CreateHotkeyOptions = AdapterHotkeyOptions<CreateHotkeyTarget>;
9
+ /** Options for a chord such as `'Mod+S'`. */
10
+ export type CreateHotkeyChordOptions = AdapterChordOptions<CreateHotkeyTarget>;
11
+ /** Options for a sequence such as `['G', 'G']`. */
12
+ export type CreateHotkeySequenceOptions = AdapterSequenceOptions<CreateHotkeyTarget>;
13
+ /** Options applied to every hotkey, such as provider defaults. Each applies to the kinds that support it. */
14
+ export type CreateHotkeyCommonOptions = AdapterCommonOptions<CreateHotkeyTarget>;
15
+ /** The options type for a hotkey: chord options for chords, sequence options for sequences. */
16
+ export type CreateHotkeyOptionsFor<T extends RegisterableHotkey> = AdapterOptionsFor<T, CreateHotkeyTarget>;
17
+ /** Call-site options for an app hotkey, typed by its declared default kind. */
18
+ export type CreateAppHotkeyOptions<T extends AppHotkey = AppHotkey> = AdapterAppHotkeyOptions<T, CreateHotkeyTarget>;
7
19
  /**
8
- * Register a global hotkey for the current component.
20
+ * Svelte function for registering a hotkey on the document: a chord such as
21
+ * `'Mod+S'`, a sequence such as `['G', 'G']`, or an app hotkey from
22
+ * `defineAppHotkeys`. Pass getters for reactive values. Use
23
+ * `createHotkeyAttachment` for element-scoped hotkeys.
24
+ *
25
+ * Chords accept `requireReset`; sequences accept `timeout`. A one-step
26
+ * sequence registers as its chord. An app hotkey uses its effective hotkey
27
+ * from `HotkeysProvider` (including the user's custom hotkey) and its
28
+ * declared meta and options, and registers nothing while unbound.
9
29
  *
10
30
  * @example
11
31
  * ```svelte
12
32
  * <script lang="ts">
13
- * import { createHotkey } from '@tanstack/svelte-hotkeys'
14
- *
15
- * createHotkey('Mod+S', () => {
16
- * console.log('Mod+S pressed')
17
- * })
33
+ * createHotkey('Mod+S', () => save())
34
+ * createHotkey(['G', 'G'], () => scrollToTop(), { timeout: 500 })
35
+ * createHotkey('Escape', () => close(), () => ({ enabled: isOpen }))
18
36
  * </script>
19
37
  * ```
20
38
  */
21
- export declare function createHotkey(hotkey: MaybeGetter<RegisterableHotkey>, callback: HotkeyCallback, options?: MaybeGetter<CreateHotkeyOptions>): void;
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, options?: MaybeGetter<CreateHotkeyOptionsFor<T>>): void;
22
41
  /**
23
- * Create an attachment for element-scoped hotkeys.
42
+ * Create an attachment for an element-scoped hotkey: a chord, a sequence, or
43
+ * an app hotkey that listens on the attached element.
24
44
  *
25
45
  * @example
26
46
  * ```svelte
27
47
  * <script lang="ts">
28
- * import { createHotkeyAttachment } from '@tanstack/svelte-hotkeys'
29
- *
30
- * let count = $state(0)
31
- * const saveHotkey = createHotkeyAttachment('Mod+S', () => {
32
- * count++
33
- * })
34
- *
48
+ * const saveKey = createHotkeyAttachment('Mod+S', () => save())
35
49
  * </script>
36
50
  *
37
- * <div tabindex="0" {@attach saveHotkey}>
38
- * Count: {count}
39
- * </div>
51
+ * <div tabindex="0" {@attach saveKey}>Editor content</div>
40
52
  * ```
41
53
  */
42
- export declare function createHotkeyAttachment(hotkey: MaybeGetter<RegisterableHotkey>, callback: HotkeyCallback, options?: MaybeGetter<CreateHotkeyOptions>): Attachment<HTMLElement>;
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, options?: MaybeGetter<CreateHotkeyOptionsFor<T>>): Attachment<HTMLElement>;
@@ -1,110 +1,7 @@
1
- import { detectPlatform, getHotkeyManager, normalizeRegisterableHotkey, } from '@tanstack/hotkeys';
2
- import { onDestroy } from 'svelte';
3
- import { getDefaultHotkeysOptions } from './HotkeysCtx';
4
- import { resolveMaybeGetter } from './internal.svelte';
5
- function registerHotkey(target, hotkey, callback, mergedOptions) {
6
- return getHotkeyManager().register(normalizeRegisterableHotkey(hotkey, mergedOptions.platform ?? detectPlatform()), callback, {
7
- ...mergedOptions,
8
- target,
9
- });
10
- }
11
- /**
12
- * Register a global hotkey for the current component.
13
- *
14
- * @example
15
- * ```svelte
16
- * <script lang="ts">
17
- * import { createHotkey } from '@tanstack/svelte-hotkeys'
18
- *
19
- * createHotkey('Mod+S', () => {
20
- * console.log('Mod+S pressed')
21
- * })
22
- * </script>
23
- * ```
24
- */
1
+ import { createHotkeys, createHotkeysAttachment } from './createHotkeys.svelte';
25
2
  export function createHotkey(hotkey, callback, options = {}) {
26
- let registration = null;
27
- let lastHotkeyStr = null;
28
- $effect(() => {
29
- if (typeof document === 'undefined') {
30
- return;
31
- }
32
- const resolvedHotkey = resolveMaybeGetter(hotkey);
33
- const resolvedOptions = resolveMaybeGetter(options);
34
- const mergedOptions = {
35
- ...getDefaultHotkeysOptions().hotkey,
36
- ...resolvedOptions,
37
- };
38
- const hotkeyStr = normalizeRegisterableHotkey(resolvedHotkey, mergedOptions.platform ?? detectPlatform());
39
- const { target: _t, ...optionsWithoutTarget } = mergedOptions;
40
- if (registration?.isActive && lastHotkeyStr === hotkeyStr) {
41
- registration.callback = callback;
42
- registration.setOptions(optionsWithoutTarget);
43
- return;
44
- }
45
- if (registration?.isActive) {
46
- registration.unregister();
47
- registration = null;
48
- }
49
- registration = registerHotkey(document, resolvedHotkey, callback, mergedOptions);
50
- lastHotkeyStr = hotkeyStr;
51
- });
52
- onDestroy(() => {
53
- if (registration?.isActive) {
54
- registration.unregister();
55
- registration = null;
56
- }
57
- });
3
+ createHotkeys([{ hotkey, callback, options }]);
58
4
  }
59
- /**
60
- * Create an attachment for element-scoped hotkeys.
61
- *
62
- * @example
63
- * ```svelte
64
- * <script lang="ts">
65
- * import { createHotkeyAttachment } from '@tanstack/svelte-hotkeys'
66
- *
67
- * let count = $state(0)
68
- * const saveHotkey = createHotkeyAttachment('Mod+S', () => {
69
- * count++
70
- * })
71
- *
72
- * </script>
73
- *
74
- * <div tabindex="0" {@attach saveHotkey}>
75
- * Count: {count}
76
- * </div>
77
- * ```
78
- */
79
5
  export function createHotkeyAttachment(hotkey, callback, options = {}) {
80
- return (element) => {
81
- let registration = null;
82
- let lastHotkeyStr = null;
83
- $effect(() => {
84
- const resolvedHotkey = resolveMaybeGetter(hotkey);
85
- const resolvedOptions = resolveMaybeGetter(options);
86
- const mergedOptions = {
87
- ...getDefaultHotkeysOptions().hotkey,
88
- ...resolvedOptions,
89
- };
90
- const hotkeyStr = normalizeRegisterableHotkey(resolvedHotkey, mergedOptions.platform ?? detectPlatform());
91
- const { target: _t, ...optionsWithoutTarget } = mergedOptions;
92
- if (registration?.isActive && lastHotkeyStr === hotkeyStr) {
93
- registration.callback = callback;
94
- registration.setOptions(optionsWithoutTarget);
95
- return;
96
- }
97
- if (registration?.isActive) {
98
- registration.unregister();
99
- registration = null;
100
- }
101
- registration = registerHotkey(element, resolvedHotkey, callback, mergedOptions);
102
- lastHotkeyStr = hotkeyStr;
103
- });
104
- return () => {
105
- if (registration?.isActive) {
106
- registration.unregister();
107
- }
108
- };
109
- };
6
+ return createHotkeysAttachment([{ hotkey, callback, options }]);
110
7
  }
@@ -1,15 +1,42 @@
1
- import type { Hotkey, HotkeyRecorderOptions } from '@tanstack/hotkeys';
2
- import type { MaybeGetter } from './internal.svelte';
3
- export interface SvelteHotkeyRecorder {
1
+ import type { Hotkey, HotkeyChord, HotkeyChordRecorderOptions, HotkeyRecorderOptions, HotkeySequence, HotkeySequenceRecorderOptions } from '@tanstack/hotkeys';
2
+ export interface SvelteHotkeyRecorder<THotkey extends Hotkey = Hotkey> {
4
3
  /** Whether recording is currently active */
5
4
  readonly isRecording: boolean;
6
- /** The currently recorded hotkey (for live preview) */
7
- readonly recordedHotkey: Hotkey | null;
5
+ /** Chords recorded so far in a multi-step recording (for live preview) */
6
+ readonly steps: HotkeySequence;
7
+ /** The last committed hotkey */
8
+ readonly recordedHotkey: THotkey | null;
8
9
  /** Start recording a new hotkey */
9
10
  startRecording: () => void;
10
- /** Stop recording (same as cancel) */
11
+ /** Stop recording without calling onCancel */
11
12
  stopRecording: () => void;
12
- /** Cancel recording without saving */
13
+ /** Cancel recording and call onCancel */
13
14
  cancelRecording: () => void;
15
+ /** Commit the recorded steps now (multi-step recordings) */
16
+ commitRecording: () => void;
14
17
  }
15
- export declare function createHotkeyRecorder(options: MaybeGetter<HotkeyRecorderOptions>): SvelteHotkeyRecorder;
18
+ /**
19
+ * Svelte function for recording keyboard shortcuts. Options may be a getter.
20
+ *
21
+ * With the default `maxSteps: 1`, the first valid chord is recorded. With a
22
+ * larger `maxSteps`, each chord adds a step; the recording commits on Enter
23
+ * (unless `commitKeys: 'none'`), after `idleTimeoutMs`, or at `maxSteps`, and
24
+ * `onRecord` receives a chord (one step) or a sequence.
25
+ *
26
+ * @example
27
+ * ```svelte
28
+ * <script lang="ts">
29
+ * const recorder = createHotkeyRecorder({ onRecord: (hotkey) => (shortcut = hotkey) })
30
+ * const sequenceRecorder = createHotkeyRecorder({ maxSteps: 3, onRecord: save })
31
+ * </script>
32
+ *
33
+ * <button onclick={recorder.startRecording}>
34
+ * {recorder.isRecording ? 'Press keys…' : formatForDisplay(shortcut)}
35
+ * </button>
36
+ * ```
37
+ */
38
+ export declare function createHotkeyRecorder(options: HotkeyChordRecorderOptions): SvelteHotkeyRecorder<HotkeyChord>;
39
+ export declare function createHotkeyRecorder(options: HotkeySequenceRecorderOptions): SvelteHotkeyRecorder;
40
+ export declare function createHotkeyRecorder(options: () => HotkeySequenceRecorderOptions): SvelteHotkeyRecorder;
41
+ export declare function createHotkeyRecorder(options: () => HotkeyChordRecorderOptions): SvelteHotkeyRecorder<HotkeyChord>;
42
+ export declare function createHotkeyRecorder(options: () => HotkeyRecorderOptions): SvelteHotkeyRecorder;
@@ -2,42 +2,6 @@ import { HotkeyRecorder } from '@tanstack/hotkeys';
2
2
  import { onDestroy } from 'svelte';
3
3
  import { getDefaultHotkeysOptions } from './HotkeysCtx';
4
4
  import { createStoreSubscriber, resolveMaybeGetter } from './internal.svelte';
5
- /**
6
- * Svelte function for recording keyboard shortcuts.
7
- *
8
- * This function provides a thin wrapper around the framework-agnostic `HotkeyRecorder`
9
- * class, managing all the complexity of capturing keyboard events, converting them
10
- * to hotkey strings, and handling edge cases like Escape to cancel or Backspace/Delete
11
- * to clear.
12
- *
13
- * @param options - Configuration options for the recorder
14
- * @returns An object with recording state and control functions
15
- *
16
- * @example
17
- * ```svelte
18
- * <script>
19
- * import { createHotkeyRecorder } from '@tanstack/svelte-hotkeys'
20
- *
21
- * const recorder = createHotkeyRecorder({
22
- * onRecord: (hotkey) => {
23
- * console.log('Recorded:', hotkey) // e.g., "Mod+Shift S"
24
- * },
25
- * onCancel: () => {
26
- * console.log('Recording cancelled')
27
- * },
28
- * })
29
- * </script>
30
- *
31
- * <div>
32
- * <button onclick={recorder.startRecording}>
33
- * {recorder.isRecording ? 'Recording...' : 'Edit Shortcut'}
34
- * </button>
35
- * {#if recorder.recordedHotkey}
36
- * <div>Recording: {recorder.recordedHotkey}</div>
37
- * {/if}
38
- * </div>
39
- * ```
40
- */
41
5
  class SvelteHotkeyRecorderState {
42
6
  #recorder;
43
7
  #subscribe;
@@ -49,6 +13,10 @@ class SvelteHotkeyRecorderState {
49
13
  this.#subscribe();
50
14
  return this.#recorder.store.state.isRecording;
51
15
  }
16
+ get steps() {
17
+ this.#subscribe();
18
+ return this.#recorder.store.state.steps;
19
+ }
52
20
  get recordedHotkey() {
53
21
  this.#subscribe();
54
22
  return this.#recorder.store.state.recordedHotkey;
@@ -56,32 +24,32 @@ class SvelteHotkeyRecorderState {
56
24
  setOptions(options) {
57
25
  this.#recorder.setOptions(options);
58
26
  }
59
- // Keep the recorder receiver when used directly as an event handler.
27
+ // Arrow functions keep the receiver when used directly as event handlers.
60
28
  startRecording = () => {
61
29
  this.#recorder.start();
62
30
  };
63
- // Keep the recorder receiver when used directly as an event handler.
64
31
  stopRecording = () => {
65
32
  this.#recorder.stop();
66
33
  };
67
- // Keep the recorder receiver when used directly as an event handler.
68
34
  cancelRecording = () => {
69
35
  this.#recorder.cancel();
70
36
  };
37
+ commitRecording = () => {
38
+ this.#recorder.commit();
39
+ };
71
40
  destroy() {
72
41
  this.#recorder.destroy();
73
42
  }
74
43
  }
75
44
  export function createHotkeyRecorder(options) {
76
- const recorder = new SvelteHotkeyRecorderState({
45
+ const resolve = () => ({
77
46
  ...getDefaultHotkeysOptions().hotkeyRecorder,
78
47
  ...resolveMaybeGetter(options),
79
48
  });
49
+ // Overloads already checked the options; either shape is valid here.
50
+ const recorder = new SvelteHotkeyRecorderState(resolve());
80
51
  $effect(() => {
81
- recorder.setOptions({
82
- ...getDefaultHotkeysOptions().hotkeyRecorder,
83
- ...resolveMaybeGetter(options),
84
- });
52
+ recorder.setOptions(resolve());
85
53
  });
86
54
  onDestroy(() => {
87
55
  recorder.destroy();
@@ -1,52 +1,69 @@
1
- import type { HotkeyCallback, RegisterableHotkey } from '@tanstack/hotkeys';
2
- import type { CreateHotkeyOptions } from './createHotkey.svelte';
3
- import type { MaybeGetter } from './internal.svelte';
4
1
  import type { Attachment } from 'svelte/attachments';
2
+ import type { AppHotkey, HotkeyCallback, HotkeySequence, RegisterableHotkey, RegisterableHotkeyChord } from '@tanstack/hotkeys';
3
+ import type { MaybeGetter } from './internal.svelte';
4
+ import type { CreateAppHotkeyOptions, CreateHotkeyChordOptions, CreateHotkeyCommonOptions, CreateHotkeyOptions, CreateHotkeySequenceOptions } from './createHotkey.svelte';
5
5
  /**
6
- * A single hotkey definition for use with `createHotkeys`.
6
+ * One hotkey for `createHotkeys`. The hotkey and options may be getters.
7
+ * Chords accept `requireReset`; sequences accept `timeout`; hotkeys of unknown
8
+ * kind accept only shared options.
7
9
  */
8
- export interface CreateHotkeyDefinition {
9
- /** The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object */
10
- hotkey: MaybeGetter<RegisterableHotkey>;
10
+ export type CreateHotkeyDefinition = {
11
+ /** A chord string such as `'Mod+S'`, or a RawHotkey object */
12
+ hotkey: MaybeGetter<RegisterableHotkeyChord>;
11
13
  /** The function to call when the hotkey is pressed */
12
14
  callback: HotkeyCallback;
13
15
  /** Per-hotkey options (merged on top of commonOptions) */
16
+ options?: MaybeGetter<CreateHotkeyChordOptions>;
17
+ } | {
18
+ /** A sequence such as `['G', 'G']` */
19
+ hotkey: MaybeGetter<HotkeySequence>;
20
+ callback: HotkeyCallback;
21
+ options?: MaybeGetter<CreateHotkeySequenceOptions>;
22
+ } | {
23
+ /** An app hotkey from `defineAppHotkeys` */
24
+ hotkey: MaybeGetter<AppHotkey>;
25
+ callback: HotkeyCallback;
26
+ options?: MaybeGetter<CreateAppHotkeyOptions>;
27
+ } | {
28
+ /** A hotkey whose kind is not known statically. Accepts only shared options. */
29
+ hotkey: MaybeGetter<RegisterableHotkey>;
30
+ callback: HotkeyCallback;
14
31
  options?: MaybeGetter<CreateHotkeyOptions>;
15
- }
32
+ };
16
33
  /**
17
- * Register multiple global hotkeys for the current component.
34
+ * Svelte function for registering several hotkeys at once on the document:
35
+ * chords, sequences, and app hotkeys. Pass getters for reactive values. Use
36
+ * `createHotkeysAttachment` for element-scoped hotkeys.
37
+ *
38
+ * Options merge in this order: provider defaults, app hotkey declaration,
39
+ * commonOptions, per-hotkey options. Each option applies only to the kinds
40
+ * that support it. Unbound app hotkeys and empty sequences register nothing.
18
41
  *
19
42
  * @example
20
43
  * ```svelte
21
44
  * <script lang="ts">
22
- * import { createHotkeys } from '@tanstack/svelte-hotkeys'
23
- *
24
45
  * createHotkeys([
25
46
  * { hotkey: 'Mod+S', callback: () => save() },
26
- * { hotkey: 'Mod+Z', callback: () => undo() },
27
- * { hotkey: 'Escape', callback: () => close() },
47
+ * { hotkey: ['G', 'G'], callback: () => scrollToTop(), options: { timeout: 500 } },
28
48
  * ])
29
49
  * </script>
30
50
  * ```
31
51
  */
32
- export declare function createHotkeys(hotkeys: MaybeGetter<Array<CreateHotkeyDefinition>>, commonOptions?: MaybeGetter<CreateHotkeyOptions>): void;
52
+ export declare function createHotkeys(hotkeys: MaybeGetter<ReadonlyArray<CreateHotkeyDefinition>>, commonOptions?: MaybeGetter<CreateHotkeyCommonOptions>): void;
33
53
  /**
34
- * Create an attachment for element-scoped multi-hotkey registration.
54
+ * Create an attachment for element-scoped hotkeys: chords, sequences, and app
55
+ * hotkeys listen on the attached element.
35
56
  *
36
57
  * @example
37
58
  * ```svelte
38
59
  * <script lang="ts">
39
- * import { createHotkeysAttachment } from '@tanstack/svelte-hotkeys'
40
- *
41
60
  * const editorKeys = createHotkeysAttachment([
42
61
  * { hotkey: 'Mod+S', callback: () => save() },
43
- * { hotkey: 'Mod+Z', callback: () => undo() },
62
+ * { hotkey: ['G', 'G'], callback: () => scrollToTop() },
44
63
  * ])
45
64
  * </script>
46
65
  *
47
- * <div tabindex="0" {@attach editorKeys}>
48
- * Editor content
49
- * </div>
66
+ * <div tabindex="0" {@attach editorKeys}>Editor content</div>
50
67
  * ```
51
68
  */
52
- export declare function createHotkeysAttachment(hotkeys: MaybeGetter<Array<CreateHotkeyDefinition>>, commonOptions?: MaybeGetter<CreateHotkeyOptions>): Attachment<HTMLElement>;
69
+ export declare function createHotkeysAttachment(hotkeys: MaybeGetter<ReadonlyArray<CreateHotkeyDefinition>>, commonOptions?: MaybeGetter<CreateHotkeyCommonOptions>): Attachment<HTMLElement>;