@tanstack/octane-hotkeys 0.4.5 → 0.5.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 CHANGED
@@ -51,7 +51,7 @@
51
51
  # TanStack Hotkeys
52
52
 
53
53
  > [!NOTE]
54
- > TanStack Hotkeys is alpha. We are actively developing the library and are open to feedback and contributions.
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,5 +1,6 @@
1
1
  import { UseHotkeyCommonOptions } from "./useHotkey.js";
2
2
  import { AppHotkeys, AppHotkeysStore, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
3
+ import { HotkeysProviderScopeProps } from "@tanstack/hotkeys/adapter";
3
4
  //#region src/HotkeysProvider.d.ts
4
5
  export interface DefaultHotkeysOptions {
5
6
  /**
@@ -11,12 +12,16 @@ export interface DefaultHotkeysOptions {
11
12
  hotkeyRecorder?: Partial<Omit<HotkeyChordRecorderOptions & HotkeySequenceRecorderOptions, 'maxSteps' | 'onRecord' | 'validate'>>;
12
13
  }
13
14
  interface HotkeysContextValue {
15
+ /** Merged with every ancestor provider's defaults, including `hotkey.scope`. */
14
16
  defaultOptions: DefaultHotkeysOptions;
15
17
  appHotkeysStore: AppHotkeysStore | null;
18
+ /** Whether this provider and every ancestor are enabled. */
19
+ enabled: boolean;
16
20
  }
17
21
  export type HotkeysProviderOptions = DefaultHotkeysOptions;
18
- export interface HotkeysProviderProps {
22
+ export interface HotkeysProviderProps extends HotkeysProviderScopeProps {
19
23
  children?: unknown;
24
+ /** Merged with the parent provider's defaults. */
20
25
  defaultOptions?: HotkeysProviderOptions;
21
26
  /**
22
27
  * Every app hotkey, from `defineAppHotkeys`. Read when the provider first
@@ -35,11 +40,18 @@ export interface HotkeysProviderProps {
35
40
  export declare function useHotkeysContext(): HotkeysContextValue | null;
36
41
  /** Reads the nearest provider's defaults, or an empty object. */
37
42
  export declare function useDefaultHotkeysOptions(): DefaultHotkeysOptions;
38
- /** Sets defaults, app hotkeys, and custom hotkeys for descendant components. */
39
- export declare function HotkeysProvider({ children, defaultOptions, appHotkeys, customHotkeys, onCustomHotkeysChange }: HotkeysProviderProps): import("octane").ElementDescriptor<{
43
+ /**
44
+ * Sets defaults, app hotkeys, and custom hotkeys for descendant components.
45
+ *
46
+ * Nest providers to create hotkey scopes. A nested provider inherits app
47
+ * hotkeys and merges default options. With `scope`, its hotkeys fire only
48
+ * while it is mounted and enabled; with `exclusive`, only its hotkeys fire.
49
+ */
50
+ export declare function HotkeysProvider({ children, defaultOptions, appHotkeys, customHotkeys, onCustomHotkeysChange, scope, exclusive, enabled }: HotkeysProviderProps): import("octane").ElementDescriptor<{
40
51
  value: {
41
52
  defaultOptions: DefaultHotkeysOptions;
42
53
  appHotkeysStore: AppHotkeysStore<Readonly<Record<string, import("@tanstack/hotkeys").AppHotkey<string, import("@tanstack/hotkeys").HotkeyChord | import("@tanstack/hotkeys").HotkeySequence | null>>>> | null;
54
+ enabled: boolean;
43
55
  };
44
56
  children: unknown;
45
57
  }>;
@@ -1,6 +1,7 @@
1
1
  import { subSlot } from "./internal.js";
2
2
  import { AppHotkeysStore, publishAppHotkeysStore } from "@tanstack/hotkeys";
3
3
  import { createContext, createElement, useContext, useLayoutEffect, useRef } from "octane";
4
+ import { activateHotkeysProviderScope, getHotkeysProviderScopeKey, mergeHotkeysProviderDefaults } from "@tanstack/hotkeys/adapter";
4
5
 
5
6
  //#region src/HotkeysProvider.ts
6
7
  const HotkeysContext = createContext(null);
@@ -12,8 +13,15 @@ function useHotkeysContext() {
12
13
  function useDefaultHotkeysOptions() {
13
14
  return useContext(HotkeysContext)?.defaultOptions ?? {};
14
15
  }
15
- /** Sets defaults, app hotkeys, and custom hotkeys for descendant components. */
16
- function HotkeysProvider({ children, defaultOptions = {}, appHotkeys, customHotkeys, onCustomHotkeysChange }) {
16
+ /**
17
+ * Sets defaults, app hotkeys, and custom hotkeys for descendant components.
18
+ *
19
+ * Nest providers to create hotkey scopes. A nested provider inherits app
20
+ * hotkeys and merges default options. With `scope`, its hotkeys fire only
21
+ * while it is mounted and enabled; with `exclusive`, only its hotkeys fire.
22
+ */
23
+ function HotkeysProvider({ children, defaultOptions, appHotkeys, customHotkeys, onCustomHotkeysChange, scope, exclusive, enabled = true }) {
24
+ const parent = useContext(HotkeysContext);
17
25
  const callbackRef = useRef(onCustomHotkeysChange, subSlot(void 0, "provider-callback"));
18
26
  callbackRef.current = onCustomHotkeysChange;
19
27
  const storeRef = useRef(void 0, subSlot(void 0, "provider-store"));
@@ -26,10 +34,19 @@ function HotkeysProvider({ children, defaultOptions = {}, appHotkeys, customHotk
26
34
  if (appHotkeys) store?.setAppHotkeys(appHotkeys);
27
35
  }, [store, appHotkeys], subSlot(void 0, "provider-declarations"));
28
36
  useLayoutEffect(() => store ? publishAppHotkeysStore(store) : void 0, [store], subSlot(void 0, "provider-publish"));
37
+ const active = (parent?.enabled ?? true) && enabled;
38
+ const scopeKey = getHotkeysProviderScopeKey({
39
+ scope,
40
+ exclusive,
41
+ active,
42
+ parent: parent?.defaultOptions.hotkey?.scope
43
+ });
44
+ useLayoutEffect(() => scopeKey ? activateHotkeysProviderScope(scopeKey) : void 0, [scopeKey], subSlot(void 0, "provider-scope"));
29
45
  return createElement(HotkeysContext, {
30
46
  value: {
31
- defaultOptions,
32
- appHotkeysStore: store
47
+ defaultOptions: mergeHotkeysProviderDefaults(parent?.defaultOptions, defaultOptions, scope),
48
+ appHotkeysStore: store ?? parent?.appHotkeysStore ?? null,
49
+ enabled: active
33
50
  },
34
51
  children
35
52
  });
@@ -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 { AdapterAppHotkeyOptions, AdapterChordOptions, AdapterCommonOptions, AdapterHotkeyOptions, AdapterOptionsFor, AdapterSequenceOptions } from "@tanstack/hotkeys/adapter";
3
3
  //#region src/useHotkey.d.ts
4
4
  /** The element to listen on. A `null` target skips registration until it is set. */
@@ -21,5 +21,5 @@ export type UseAppHotkeyOptions<T extends AppHotkey = AppHotkey> = AdapterAppHot
21
21
  * options are refreshed after every commit.
22
22
  */
23
23
  export declare function useHotkey<T extends AppHotkey>(hotkey: T, callback: HotkeyCallback, options?: UseAppHotkeyOptions<T>): void;
24
- export declare function useHotkey<T extends RegisterableHotkey>(hotkey: T, callback: HotkeyCallback, options?: UseHotkeyOptionsFor<T>): void;
24
+ export declare function useHotkey<const T extends RegisterableHotkey>(hotkey: T, callback: HotkeyCallback<HotkeyCallbackContextFor<T>>, options?: UseHotkeyOptionsFor<T>): void;
25
25
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/octane-hotkeys",
3
- "version": "0.4.5",
3
+ "version": "0.5.0",
4
4
  "description": "Octane adapter for TanStack Hotkeys",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@tanstack/hotkeys": "0.15.1",
36
+ "@tanstack/hotkeys": "0.16.0",
37
37
  "@tanstack/octane-store": "^0.13.0"
38
38
  },
39
39
  "devDependencies": {