@tanstack/angular-hotkeys 0.20.0 → 0.21.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/dist/hotkeys-provider.d.ts +13 -3
- package/dist/hotkeys-provider.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/injectFormatForDisplay.d.ts +25 -0
- package/dist/injectFormatForDisplay.js +35 -0
- package/package.json +2 -2
- package/skills/angular-hotkeys/SKILL.md +2 -0
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { InjectHotkeyCommonOptions } from "./injectHotkey.js";
|
|
2
|
-
import { AppHotkeys, AppHotkeysState, AppHotkeysStore, CustomHotkeys, HotkeyChordRecorderOptions, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
|
|
2
|
+
import { AppHotkeys, AppHotkeysState, AppHotkeysStore, CustomHotkeys, HotkeyChordRecorderOptions, HotkeyPlatform, HotkeySequenceRecorderOptions } from "@tanstack/hotkeys";
|
|
3
3
|
import { InjectionToken, Provider, Signal } from "@angular/core";
|
|
4
4
|
import { HotkeysProviderScopeProps } from "@tanstack/hotkeys/adapter";
|
|
5
5
|
//#region src/hotkeys-provider.d.ts
|
|
6
6
|
export interface HotkeysProviderOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The user's platform, for labels from `injectFormatForDisplay`, hotkeys,
|
|
9
|
+
* and recorders. Detected when unset. On a server, set it from the request
|
|
10
|
+
* with `detectPlatform(userAgent)`.
|
|
11
|
+
*/
|
|
12
|
+
platform?: HotkeyPlatform;
|
|
7
13
|
/**
|
|
8
14
|
* Defaults for every hotkey registered by `injectHotkey` and `injectHotkeys`.
|
|
9
15
|
* `requireReset` applies to chords and `timeout` applies to sequences.
|
|
@@ -14,8 +20,12 @@ export interface HotkeysProviderOptions {
|
|
|
14
20
|
}
|
|
15
21
|
/** Options for `provideHotkeys`. */
|
|
16
22
|
export interface ProvideHotkeysOptions {
|
|
17
|
-
/**
|
|
18
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Merged with the parent provider's defaults. A getter runs in the
|
|
25
|
+
* provider's injection context, so it can `inject(REQUEST)` to set
|
|
26
|
+
* `platform` from the request during server rendering.
|
|
27
|
+
*/
|
|
28
|
+
defaultOptions?: MaybeGetter<HotkeysProviderOptions>;
|
|
19
29
|
/**
|
|
20
30
|
* See `HotkeysProviderScopeProps['scope']`. Getters, here and for
|
|
21
31
|
* `exclusive` and `enabled`, run in the provider's injection context, so
|
package/dist/hotkeys-provider.js
CHANGED
|
@@ -43,7 +43,7 @@ function createHotkeysContext(options) {
|
|
|
43
43
|
appHotkeysState = state.asReadonly();
|
|
44
44
|
}
|
|
45
45
|
const enabled = computed(() => parent.enabled() && read(options.enabled) !== false);
|
|
46
|
-
const defaultOptions = computed(() => mergeHotkeysProviderDefaults(parent.defaultOptions, options.defaultOptions, read(options.scope)));
|
|
46
|
+
const defaultOptions = computed(() => mergeHotkeysProviderDefaults(parent.defaultOptions, read(options.defaultOptions), read(options.scope)));
|
|
47
47
|
const scopeKey = computed(() => getHotkeysProviderScopeKey({
|
|
48
48
|
scope: read(options.scope),
|
|
49
49
|
exclusive: read(options.exclusive),
|
package/dist/index.d.ts
CHANGED
|
@@ -9,5 +9,6 @@ import { injectHotkeyRegistrations } from "./injectHotkeyRegistrations.js";
|
|
|
9
9
|
import { injectHotkeyScopesState } from "./injectHotkeyScopesState.js";
|
|
10
10
|
import { injectHotkeyHint } from "./injectHotkeyHint.js";
|
|
11
11
|
import { InjectCustomHotkeysResult, injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys } from "./injectAppHotkeys.js";
|
|
12
|
+
import { injectFormatForDisplay } from "./injectFormatForDisplay.js";
|
|
12
13
|
export * from "@tanstack/hotkeys";
|
|
13
|
-
export { AngularHotkeyRecorder, HOTKEYS_INJECTION_TOKEN, HotkeysContextValue, HotkeysProviderOptions, InjectAppHotkeyOptions, InjectCustomHotkeysResult, InjectHotkeyChordOptions, InjectHotkeyCommonOptions, InjectHotkeyDefinition, InjectHotkeyOptions, InjectHotkeyOptionsFor, InjectHotkeySequenceOptions, InjectHotkeyTarget, MaybeGetter, ProvideHotkeysOptions, injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys, injectDefaultHotkeysOptions, injectHeldKeyCodes, injectHeldKeys, injectHotkey, injectHotkeyHint, injectHotkeyRecorder, injectHotkeyRegistrations, injectHotkeyScopesState, injectHotkeys, injectHotkeysContext, injectKeyHold, provideHotkeys };
|
|
14
|
+
export { AngularHotkeyRecorder, HOTKEYS_INJECTION_TOKEN, HotkeysContextValue, HotkeysProviderOptions, InjectAppHotkeyOptions, InjectCustomHotkeysResult, InjectHotkeyChordOptions, InjectHotkeyCommonOptions, InjectHotkeyDefinition, InjectHotkeyOptions, InjectHotkeyOptionsFor, InjectHotkeySequenceOptions, InjectHotkeyTarget, MaybeGetter, ProvideHotkeysOptions, injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys, injectDefaultHotkeysOptions, injectFormatForDisplay, injectHeldKeyCodes, injectHeldKeys, injectHotkey, injectHotkeyHint, injectHotkeyRecorder, injectHotkeyRegistrations, injectHotkeyScopesState, injectHotkeys, injectHotkeysContext, injectKeyHold, provideHotkeys };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,8 @@ import { injectHotkeyRegistrations } from "./injectHotkeyRegistrations.js";
|
|
|
9
9
|
import { injectHotkeyScopesState } from "./injectHotkeyScopesState.js";
|
|
10
10
|
import { injectHotkeyHint } from "./injectHotkeyHint.js";
|
|
11
11
|
import { injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys } from "./injectAppHotkeys.js";
|
|
12
|
+
import { injectFormatForDisplay } from "./injectFormatForDisplay.js";
|
|
12
13
|
|
|
13
14
|
export * from "@tanstack/hotkeys"
|
|
14
15
|
|
|
15
|
-
export { HOTKEYS_INJECTION_TOKEN, injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys, injectDefaultHotkeysOptions, injectHeldKeyCodes, injectHeldKeys, injectHotkey, injectHotkeyHint, injectHotkeyRecorder, injectHotkeyRegistrations, injectHotkeyScopesState, injectHotkeys, injectHotkeysContext, injectKeyHold, provideHotkeys };
|
|
16
|
+
export { HOTKEYS_INJECTION_TOKEN, injectAppHotkeyList, injectAppHotkeys, injectCustomHotkeys, injectDefaultHotkeysOptions, injectFormatForDisplay, injectHeldKeyCodes, injectHeldKeys, injectHotkey, injectHotkeyHint, injectHotkeyRecorder, injectHotkeyRegistrations, injectHotkeyScopesState, injectHotkeys, injectHotkeysContext, injectKeyHold, provideHotkeys };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { formatForDisplay } from "@tanstack/hotkeys";
|
|
2
|
+
//#region src/injectFormatForDisplay.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Returns `formatForDisplay` with the provider's `platform` as the default,
|
|
5
|
+
* so labels match the user's platform. Call it in an injection context, such
|
|
6
|
+
* as a field initializer; the returned function works anywhere, including
|
|
7
|
+
* templates. An explicit `platform` option wins.
|
|
8
|
+
*
|
|
9
|
+
* Server-rendered apps should set the provider's `defaultOptions.platform`
|
|
10
|
+
* from the request user agent, such as
|
|
11
|
+
* `detectPlatform(inject(REQUEST)?.headers.get('user-agent'))`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* @Component({
|
|
16
|
+
* selector: 'app-save-button',
|
|
17
|
+
* template: `<kbd>{{ format('Mod+S') }}</kbd>`,
|
|
18
|
+
* })
|
|
19
|
+
* export class SaveButton {
|
|
20
|
+
* format = injectFormatForDisplay()
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function injectFormatForDisplay(): typeof formatForDisplay;
|
|
25
|
+
//#endregion
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { injectHotkeysContext } from "./hotkeys-provider.js";
|
|
2
|
+
import { formatForDisplay } from "@tanstack/hotkeys";
|
|
3
|
+
|
|
4
|
+
//#region src/injectFormatForDisplay.ts
|
|
5
|
+
/**
|
|
6
|
+
* Returns `formatForDisplay` with the provider's `platform` as the default,
|
|
7
|
+
* so labels match the user's platform. Call it in an injection context, such
|
|
8
|
+
* as a field initializer; the returned function works anywhere, including
|
|
9
|
+
* templates. An explicit `platform` option wins.
|
|
10
|
+
*
|
|
11
|
+
* Server-rendered apps should set the provider's `defaultOptions.platform`
|
|
12
|
+
* from the request user agent, such as
|
|
13
|
+
* `detectPlatform(inject(REQUEST)?.headers.get('user-agent'))`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* @Component({
|
|
18
|
+
* selector: 'app-save-button',
|
|
19
|
+
* template: `<kbd>{{ format('Mod+S') }}</kbd>`,
|
|
20
|
+
* })
|
|
21
|
+
* export class SaveButton {
|
|
22
|
+
* format = injectFormatForDisplay()
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function injectFormatForDisplay() {
|
|
27
|
+
const context = injectHotkeysContext();
|
|
28
|
+
return ((hotkey, options) => formatForDisplay(hotkey, {
|
|
29
|
+
...options,
|
|
30
|
+
platform: options?.platform ?? context.defaultOptions.platform
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { injectFormatForDisplay };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/angular-hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Angular adapter for TanStack Hotkeys",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"skills"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tanstack/hotkeys": "0.
|
|
40
|
+
"@tanstack/hotkeys": "0.23.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@angular/common": ">=19.0.0",
|
|
@@ -66,6 +66,7 @@ export class PanelComponent {
|
|
|
66
66
|
| `provideHotkeys(options)` | Set default options, a scope (`exclusive` for dialogs), `enabled`, and app hotkeys in the app config or a component's `providers`. |
|
|
67
67
|
| `injectHotkeysContext()` | Read the nearest provided defaults and enabled state. Activates that provider's scope. |
|
|
68
68
|
| `injectDefaultHotkeysOptions()` | Read the default options merged from every provider above. |
|
|
69
|
+
| `injectFormatForDisplay()` | Get `formatForDisplay` with the provider's `platform` filled in, for labels in server-rendered apps. Call it in an injection context. |
|
|
69
70
|
| `injectAppHotkeys()` | Get a signal of the declared app hotkeys with the user's custom hotkeys applied. |
|
|
70
71
|
| `injectAppHotkeyList()` | Get a signal listing every app hotkey with its status, for a cheat sheet or settings screen. |
|
|
71
72
|
| `injectCustomHotkeys()` | Read, change, and reset the user's custom hotkeys, and check a new one for conflicts. |
|
|
@@ -117,6 +118,7 @@ A component's `providers` apply to the component itself, so it can register its
|
|
|
117
118
|
- **Replace `@HostListener('document:keydown')` and `(keydown.control.s)` bindings with `injectHotkey`.**
|
|
118
119
|
- **Register runtime lists in the constructor.** `injectHotkey` throws outside an injection context, such as in `ngOnInit`. For hotkeys from data, use `injectHotkeys(() => this.items().map(...))`.
|
|
119
120
|
- **Call the inject functions directly.** A shortcut service or `injectShortcut(keys: string)` wrapper has to cast strings to hotkeys, which turns off type checking and drops sequences, signal options, and app hotkeys.
|
|
121
|
+
- **Server-rendered labels need the user's platform.** On the server, `formatForDisplay` can't see the user's OS, so it renders Linux labels that differ after hydration for Mac and Windows users. Pass `provideHotkeys({ defaultOptions: () => ({ platform: detectPlatform(inject(REQUEST)?.headers.get('user-agent')) }) })`, and format labels with `format = injectFormatForDisplay()` as a field, then `format(hotkey)` in the template. Keep plain `formatForDisplay` for labels that render only in the browser.
|
|
120
122
|
|
|
121
123
|
When declaring app hotkeys, building a cheat sheet, or letting users rebind shortcuts, load `@tanstack/hotkeys#app-hotkeys` and read [app hotkeys in Angular](references/app-hotkeys.md).
|
|
122
124
|
|