@tanstack/vue-hotkeys 0.18.0 → 0.19.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.
@@ -5,8 +5,9 @@ import { HotkeysProviderScopeProps } from "@tanstack/hotkeys/adapter";
5
5
  //#region src/HotkeysProvider.d.ts
6
6
  /**
7
7
  * Vue component that provides default options, app hotkeys, and the user's
8
- * custom hotkeys. `customHotkeys` is read once; listen to
9
- * `custom-hotkeys-change` to save changes.
8
+ * custom hotkeys. A new `customHotkeys` value replaces the current custom
9
+ * hotkeys, `undefined` leaves them unchanged, and `null` clears them. Listen
10
+ * to `custom-hotkeys-change` to save changes.
10
11
  *
11
12
  * Nest providers to create hotkey scopes. A nested provider inherits app
12
13
  * hotkeys and merges default options. With `scope`, its hotkeys fire only
@@ -4,8 +4,9 @@ import { defineComponent } from "vue";
4
4
  //#region src/HotkeysProvider.tsx
5
5
  /**
6
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
+ * custom hotkeys. A new `customHotkeys` value replaces the current custom
8
+ * hotkeys, `undefined` leaves them unchanged, and `null` clears them. Listen
9
+ * to `custom-hotkeys-change` to save changes.
9
10
  *
10
11
  * Nest providers to create hotkey scopes. A nested provider inherits app
11
12
  * hotkeys and merges default options. With `scope`, its hotkeys fire only
@@ -67,7 +68,7 @@ const HotkeysProvider = defineComponent({
67
68
  provideHotkeysContext({
68
69
  defaultOptions: () => props.defaultOptions,
69
70
  appHotkeys: () => props.appHotkeys,
70
- customHotkeys: props.customHotkeys,
71
+ customHotkeys: () => props.customHotkeys,
71
72
  scope: () => props.scope,
72
73
  exclusive: () => props.exclusive,
73
74
  enabled: () => props.enabled,
@@ -35,10 +35,12 @@ export interface ProvideHotkeysContextOptions {
35
35
  */
36
36
  appHotkeys?: MaybeRefOrGetter<AppHotkeys | undefined>;
37
37
  /**
38
- * Starting custom hotkeys, such as saved data. Read once; the context owns
39
- * the state afterwards. Invalid entries are ignored with a warning.
38
+ * The user's saved custom hotkeys. When the value changes, such as after
39
+ * saved data loads or the user signs in, it replaces the current custom
40
+ * hotkeys. `undefined` leaves them unchanged; `null` clears them. Invalid
41
+ * entries are ignored with a warning.
40
42
  */
41
- customHotkeys?: CustomHotkeys | null;
43
+ customHotkeys?: MaybeRefOrGetter<CustomHotkeys | null | undefined>;
42
44
  /** Called with the custom hotkeys after every change, ready to save. */
43
45
  onCustomHotkeysChange?: (customHotkeys: CustomHotkeys) => void;
44
46
  }
@@ -29,13 +29,14 @@ function provideHotkeysContext(options = {}) {
29
29
  const parent = inject(HotkeysContext, null);
30
30
  const appHotkeys = toValue(options.appHotkeys);
31
31
  const store = appHotkeys ? createAppHotkeysStore(appHotkeys, {
32
- customHotkeys: options.customHotkeys,
32
+ customHotkeys: toValue(options.customHotkeys),
33
33
  onCustomHotkeysChange: (custom) => options.onCustomHotkeysChange?.(custom)
34
34
  }) : null;
35
35
  if (store) {
36
36
  watch(() => toValue(options.appHotkeys), (next) => {
37
37
  if (next) store.setAppHotkeys(next);
38
38
  });
39
+ watch(() => toValue(options.customHotkeys), (customHotkeys) => store.setOptions({ customHotkeys }), { deep: true });
39
40
  if (typeof document !== "undefined") onScopeDispose(publishAppHotkeysStore(store));
40
41
  }
41
42
  const active = computed(() => (parent?.enabled ?? true) && toValue(options.enabled) !== false);
@@ -33,6 +33,7 @@ export type UseAppHotkeyOptions<T extends AppHotkey = AppHotkey> = WithReactiveE
33
33
  * sequence registers as its chord. An app hotkey uses its effective hotkey
34
34
  * from `HotkeysProvider` (including the user's custom hotkey) and its
35
35
  * declared meta and options, and registers nothing while unbound.
36
+ * `undefined`, `null`, or `''` registers nothing, for an optional shortcut.
36
37
  *
37
38
  * @example
38
39
  * ```ts
@@ -41,6 +42,6 @@ export type UseAppHotkeyOptions<T extends AppHotkey = AppHotkey> = WithReactiveE
41
42
  * useHotkey('Escape', () => close(), { enabled: isOpen })
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<const T extends RegisterableHotkey>(hotkey: MaybeRefOrGetter<T>, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: MaybeRefOrGetter<UseHotkeyOptionsFor<T>>): void;
45
+ export declare function useHotkey<T extends AppHotkey>(hotkey: MaybeRefOrGetter<T | null | undefined>, callback: HotkeyCallback, options?: MaybeRefOrGetter<UseAppHotkeyOptions<T>>): void;
46
+ export declare function useHotkey<const T extends RegisterableHotkey>(hotkey: MaybeRefOrGetter<T | null | undefined>, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: MaybeRefOrGetter<UseHotkeyOptionsFor<T>>): void;
46
47
  //#endregion
@@ -7,7 +7,8 @@ import { ComputedRef, MaybeRefOrGetter } from "vue";
7
7
  * enabled and in an active scope. Pass refs or getters to track changing
8
8
  * hotkeys and options. A sequence reveals its hint from its first step, and
9
9
  * an app hotkey matches its registrations by id and uses its effective hotkey
10
- * (false while unbound). This helper does not register a shortcut. A hotkey on an element counts only while focus is inside it.
10
+ * (false while unbound). No hotkey (`undefined`, `null`, or `''`) returns
11
+ * false. This helper does not register a shortcut. A hotkey on an element counts only while focus is inside it.
11
12
  */
12
- export declare function useHotkeyHint(hotkey: MaybeRefOrGetter<RegisterableHotkey | AppHotkey>, options?: MaybeRefOrGetter<HeldModifierOptions>): ComputedRef<boolean>;
13
+ export declare function useHotkeyHint(hotkey: MaybeRefOrGetter<RegisterableHotkey | AppHotkey | null | undefined>, options?: MaybeRefOrGetter<HeldModifierOptions>): ComputedRef<boolean>;
13
14
  //#endregion
@@ -10,7 +10,8 @@ import { computed, toValue } from "vue";
10
10
  * enabled and in an active scope. Pass refs or getters to track changing
11
11
  * hotkeys and options. A sequence reveals its hint from its first step, and
12
12
  * an app hotkey matches its registrations by id and uses its effective hotkey
13
- * (false while unbound). This helper does not register a shortcut. A hotkey on an element counts only while focus is inside it.
13
+ * (false while unbound). No hotkey (`undefined`, `null`, or `''`) returns
14
+ * false. This helper does not register a shortcut. A hotkey on an element counts only while focus is inside it.
14
15
  */
15
16
  function useHotkeyHint(hotkey, options = {}) {
16
17
  const appHotkeys = useAppHotkeysStoreSource();
@@ -2,14 +2,12 @@ import { useStoreSelector } from "./useStoreSelector.js";
2
2
  import { useDefaultHotkeysOptionsSource } from "./defaultOptions.js";
3
3
  import { HotkeyRecorder } from "@tanstack/hotkeys";
4
4
  import { onScopeDispose, toValue, watch } from "vue";
5
+ import { withDefaults } from "@tanstack/hotkeys/adapter";
5
6
 
6
7
  //#region src/useHotkeyRecorder.ts
7
8
  function useHotkeyRecorder(options) {
8
9
  const defaultOptions = useDefaultHotkeysOptionsSource();
9
- const resolve = () => ({
10
- ...defaultOptions().hotkeyRecorder,
11
- ...toValue(options)
12
- });
10
+ const resolve = () => withDefaults(defaultOptions().hotkeyRecorder, toValue(options));
13
11
  const recorder = new HotkeyRecorder(resolve());
14
12
  const isRecording = useStoreSelector(recorder.store, (state) => state.isRecording);
15
13
  const steps = useStoreSelector(recorder.store, (state) => state.steps);
@@ -25,8 +25,11 @@ export type UseHotkeyDefinition = {
25
25
  callback: HotkeyCallback;
26
26
  options?: MaybeRefOrGetter<UseAppHotkeyOptions>;
27
27
  } | {
28
- /** A hotkey whose kind is not known statically. Accepts only shared options. */
29
- hotkey: MaybeRefOrGetter<RegisterableHotkey>;
28
+ /**
29
+ * A hotkey whose kind is not known statically. Accepts only shared
30
+ * options. `undefined`, `null`, or `''` registers nothing.
31
+ */
32
+ hotkey: MaybeRefOrGetter<RegisterableHotkey | null | undefined>;
30
33
  callback: HotkeyCallback;
31
34
  options?: MaybeRefOrGetter<UseHotkeyOptions>;
32
35
  };
@@ -36,7 +39,8 @@ export type UseHotkeyDefinition = {
36
39
  *
37
40
  * Options merge in this order: provider defaults, app hotkey declaration,
38
41
  * commonOptions, per-hotkey options. Each option applies only to the kinds
39
- * that support it. Unbound app hotkeys and empty sequences register nothing.
42
+ * that support it. Unbound app hotkeys, empty sequences, and `undefined`,
43
+ * `null`, or `''` hotkeys register nothing.
40
44
  * A target that resolves to `null` skips registration until it is set.
41
45
  *
42
46
  * @example
@@ -18,7 +18,8 @@ function resolveEnabled(options) {
18
18
  *
19
19
  * Options merge in this order: provider defaults, app hotkey declaration,
20
20
  * commonOptions, per-hotkey options. Each option applies only to the kinds
21
- * that support it. Unbound app hotkeys and empty sequences register nothing.
21
+ * that support it. Unbound app hotkeys, empty sequences, and `undefined`,
22
+ * `null`, or `''` hotkeys register nothing.
22
23
  * A target that resolves to `null` skips registration until it is set.
23
24
  *
24
25
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/vue-hotkeys",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Vue adapter for TanStack Hotkeys",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "skills"
39
39
  ],
40
40
  "dependencies": {
41
- "@tanstack/hotkeys": "0.20.0"
41
+ "@tanstack/hotkeys": "0.21.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@vitejs/plugin-vue": "^6.0.9",