@tanstack/alpine-hotkeys 0.5.0 → 0.7.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/createHotkeyHint.js +4 -2
- package/dist/createHotkeyScopesState.js +9 -0
- package/dist/createHotkeysScope.js +2 -0
- package/dist/hotkeysPlugin.d.ts +5 -1
- package/dist/hotkeysPlugin.js +7 -1
- package/dist/scope.js +16 -6
- package/dist/types.d.ts +3 -1
- package/package.json +3 -3
- package/skills/alpine-hotkeys/SKILL.md +20 -17
package/dist/createHotkeyHint.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { read } from "./scope.js";
|
|
2
|
-
import { getKeyStateTracker, isAppHotkey, matchesHeldModifiers, resolveAppHotkey } from "@tanstack/hotkeys";
|
|
2
|
+
import { getHotkeyManager, getKeyStateTracker, isAppHotkey, matchesHeldModifiers, resolveAppHotkey } from "@tanstack/hotkeys";
|
|
3
3
|
|
|
4
4
|
//#region src/createHotkeyHint.ts
|
|
5
5
|
function createHotkeyHint(scope, hotkey, options = {}) {
|
|
6
|
+
const manager = getHotkeyManager();
|
|
7
|
+
const registrations = scope.select(manager.registrations, (state) => state);
|
|
6
8
|
return scope.select(getKeyStateTracker().store, (state) => {
|
|
7
9
|
const value = read(hotkey);
|
|
8
10
|
const resolved = isAppHotkey(value) ? resolveAppHotkey(value, scope.appHotkeys()).hotkey : value;
|
|
9
|
-
return resolved !== null && matchesHeldModifiers(resolved, state.heldKeys, read(options));
|
|
11
|
+
return resolved !== null && matchesHeldModifiers(resolved, state.heldKeys, read(options)) && registrations.value.size > 0 && manager.hasActiveRegistration(value);
|
|
10
12
|
});
|
|
11
13
|
}
|
|
12
14
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getHotkeyManager } from "@tanstack/hotkeys";
|
|
2
|
+
|
|
3
|
+
//#region src/createHotkeyScopesState.ts
|
|
4
|
+
function createHotkeyScopesState(scope) {
|
|
5
|
+
return scope.select(getHotkeyManager().scopes, (state) => state);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
export { createHotkeyScopesState };
|
|
@@ -6,6 +6,7 @@ import { createHeldKeyCodes } from "./createHeldKeyCodes.js";
|
|
|
6
6
|
import { createKeyHold } from "./createKeyHold.js";
|
|
7
7
|
import { createHotkeyHint } from "./createHotkeyHint.js";
|
|
8
8
|
import { createHotkeyRegistrations } from "./createHotkeyRegistrations.js";
|
|
9
|
+
import { createHotkeyScopesState } from "./createHotkeyScopesState.js";
|
|
9
10
|
import { createHotkeyRecorder } from "./createHotkeyRecorder.js";
|
|
10
11
|
import { createAppHotkeyList, createAppHotkeys, createCustomHotkeys } from "./createAppHotkeys.js";
|
|
11
12
|
|
|
@@ -25,6 +26,7 @@ function createHotkeysScope(defaultOptions = {}) {
|
|
|
25
26
|
createKeyHold: (...args) => createKeyHold(scope, ...args),
|
|
26
27
|
createHotkeyHint: (...args) => createHotkeyHint(scope, ...args),
|
|
27
28
|
createHotkeyRegistrations: (...args) => createHotkeyRegistrations(scope, ...args),
|
|
29
|
+
createHotkeyScopesState: () => createHotkeyScopesState(scope),
|
|
28
30
|
createHotkeyRecorder: ((options) => createHotkeyRecorder(scope, options)),
|
|
29
31
|
createAppHotkeys: () => createAppHotkeys(scope),
|
|
30
32
|
createAppHotkeyList: () => createAppHotkeyList(scope),
|
package/dist/hotkeysPlugin.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import Alpine from "alpinejs";
|
|
2
2
|
//#region src/hotkeysPlugin.d.ts
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Installs $hotkeys, whose registrations and subscriptions belong to its
|
|
5
|
+
* element. Every hotkeys scope, including ones from `createHotkeysScope`, uses
|
|
6
|
+
* the Alpine instance passed here.
|
|
7
|
+
*/
|
|
4
8
|
export declare function hotkeysPlugin(alpine: typeof Alpine): void;
|
|
5
9
|
//#endregion
|
package/dist/hotkeysPlugin.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { setAlpine } from "./scope.js";
|
|
1
2
|
import { createHotkeysScope } from "./createHotkeysScope.js";
|
|
2
3
|
|
|
3
4
|
//#region src/hotkeysPlugin.ts
|
|
4
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Installs $hotkeys, whose registrations and subscriptions belong to its
|
|
7
|
+
* element. Every hotkeys scope, including ones from `createHotkeysScope`, uses
|
|
8
|
+
* the Alpine instance passed here.
|
|
9
|
+
*/
|
|
5
10
|
function hotkeysPlugin(alpine) {
|
|
11
|
+
setAlpine(alpine);
|
|
6
12
|
const scopes = /* @__PURE__ */ new WeakMap();
|
|
7
13
|
alpine.magic("hotkeys", (element, { cleanup }) => {
|
|
8
14
|
let scope = scopes.get(element);
|
package/dist/scope.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { getHotkeyManager } from "@tanstack/hotkeys";
|
|
2
|
-
import Alpine from "alpinejs";
|
|
3
2
|
import { subscribePublishedAppHotkeys } from "@tanstack/hotkeys/adapter";
|
|
4
3
|
|
|
5
4
|
//#region src/scope.ts
|
|
5
|
+
let pluginAlpine;
|
|
6
|
+
/** Records the Alpine instance passed to `hotkeysPlugin`. */
|
|
7
|
+
function setAlpine(alpine) {
|
|
8
|
+
pluginAlpine = alpine;
|
|
9
|
+
}
|
|
10
|
+
function getAlpine() {
|
|
11
|
+
const alpine = pluginAlpine ?? globalThis.Alpine;
|
|
12
|
+
if (!alpine) throw new Error("[TanStack Hotkeys] Alpine was not found. Call Alpine.plugin(hotkeysPlugin) before Alpine.start(), or set window.Alpine.");
|
|
13
|
+
return alpine;
|
|
14
|
+
}
|
|
6
15
|
function read(value) {
|
|
7
16
|
return typeof value === "function" ? value() : value;
|
|
8
17
|
}
|
|
@@ -14,14 +23,15 @@ function createScope(defaultOptions) {
|
|
|
14
23
|
}
|
|
15
24
|
function effect(callback) {
|
|
16
25
|
assertActive();
|
|
17
|
-
const
|
|
26
|
+
const alpine = getAlpine();
|
|
27
|
+
const runner = alpine.effect(() => {
|
|
18
28
|
if (!destroyed) callback();
|
|
19
29
|
});
|
|
20
|
-
cleanups.add(() =>
|
|
30
|
+
cleanups.add(() => alpine.release(runner));
|
|
21
31
|
}
|
|
22
32
|
function select(store, selector) {
|
|
23
33
|
assertActive();
|
|
24
|
-
const state =
|
|
34
|
+
const state = getAlpine().reactive({ snapshot: store.state });
|
|
25
35
|
const subscription = store.subscribe(() => {
|
|
26
36
|
state.snapshot = store.state;
|
|
27
37
|
});
|
|
@@ -37,7 +47,7 @@ function createScope(defaultOptions) {
|
|
|
37
47
|
*/
|
|
38
48
|
function appHotkeys() {
|
|
39
49
|
if (!appHotkeysState) {
|
|
40
|
-
const state =
|
|
50
|
+
const state = getAlpine().reactive({ version: 0 });
|
|
41
51
|
appHotkeysState = state;
|
|
42
52
|
cleanups.add(subscribePublishedAppHotkeys(() => state.version++));
|
|
43
53
|
}
|
|
@@ -64,4 +74,4 @@ function createScope(defaultOptions) {
|
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
//#endregion
|
|
67
|
-
export { createScope, read };
|
|
77
|
+
export { createScope, read, setAlpine };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppHotkey, AppHotkeyListItem, CustomHotkeys, HeldModifierOptions, Hotkey, HotkeyCallback, HotkeyCallbackContextFor, HotkeyChord, HotkeyChordRecorderOptions, HotkeyRecorderOptions, HotkeyRegistrationView, HotkeySequence, HotkeySequenceRecorderOptions, IndividualKey, RegisterableHotkey, RegisteredAppHotkeys, Target } from "@tanstack/hotkeys";
|
|
1
|
+
import { AppHotkey, AppHotkeyListItem, CustomHotkeys, HeldModifierOptions, Hotkey, HotkeyCallback, HotkeyCallbackContextFor, HotkeyChord, HotkeyChordRecorderOptions, HotkeyRecorderOptions, HotkeyRegistrationView, HotkeyScopesState, HotkeySequence, HotkeySequenceRecorderOptions, IndividualKey, RegisterableHotkey, RegisteredAppHotkeys, Target } from "@tanstack/hotkeys";
|
|
2
2
|
import { AdapterAppHotkeyOptions, AdapterCommonOptions, AdapterHotkeyDefinition, AdapterOptionsFor } from "@tanstack/hotkeys/adapter";
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
/** A reactive value. Read `.value` where the framework tracks dependencies. */
|
|
@@ -87,6 +87,8 @@ export interface AlpineHotkeys {
|
|
|
87
87
|
createHotkeyHint: (hotkey: MaybeGetter<RegisterableHotkey | AppHotkey>, options?: MaybeGetter<HeldModifierOptions>) => AlpineHotkeyState<boolean>;
|
|
88
88
|
/** Read live registrations, including disabled entries. */
|
|
89
89
|
createHotkeyRegistrations: () => HotkeyRegistrationsResult;
|
|
90
|
+
/** Read the active, exclusive, allowed, and suspended scopes through `.value`. */
|
|
91
|
+
createHotkeyScopesState: () => AlpineHotkeyState<HotkeyScopesState>;
|
|
90
92
|
/** Create a recorder whose options can follow Alpine state. */
|
|
91
93
|
createHotkeyRecorder: AlpineCreateHotkeyRecorder;
|
|
92
94
|
/** Read the effective app hotkeys from `provideAppHotkeys` through `.value`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/alpine-hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Alpine adapter for TanStack Hotkeys",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"skills"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@tanstack/hotkeys": "0.
|
|
38
|
+
"@tanstack/hotkeys": "0.19.0",
|
|
39
39
|
"@tanstack/store": "^0.11.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"alpinejs": "^3.17.4"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"alpinejs": "^3.
|
|
46
|
+
"alpinejs": "^3.13.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"clean": "premove ./build ./dist",
|
|
@@ -33,7 +33,9 @@ Before starting, load the `@tanstack/hotkeys#hotkeys-core` skill (`npx @tanstack
|
|
|
33
33
|
|
|
34
34
|
```ts no-check
|
|
35
35
|
import Alpine from 'alpinejs'
|
|
36
|
-
import { createHotkeysScope } from '@tanstack/alpine-hotkeys'
|
|
36
|
+
import { createHotkeysScope, hotkeysPlugin } from '@tanstack/alpine-hotkeys'
|
|
37
|
+
|
|
38
|
+
Alpine.plugin(hotkeysPlugin) // before Alpine.start()
|
|
37
39
|
|
|
38
40
|
Alpine.data('panel', () => ({
|
|
39
41
|
dirty: false,
|
|
@@ -56,33 +58,34 @@ Alpine.data('panel', () => ({
|
|
|
56
58
|
}))
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
Install `Alpine.plugin(hotkeysPlugin)` before `Alpine.start()`. It gives the adapter the app's Alpine instance; without it, the adapter falls back to `window.Alpine` and throws when neither exists. The plugin also adds the `$hotkeys` magic for markup-only components, which is destroyed with its element: `x-init="$hotkeys.createHotkey('Mod+S', () => save())"`.
|
|
60
62
|
|
|
61
63
|
## API
|
|
62
64
|
|
|
63
65
|
| API | What it's for |
|
|
64
66
|
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
65
|
-
| `Alpine.plugin(hotkeysPlugin)` |
|
|
67
|
+
| `Alpine.plugin(hotkeysPlugin)` | Give the adapter the app's Alpine, and install the `$hotkeys` magic, an owner destroyed with its element. |
|
|
66
68
|
| `createHotkeysScope(defaults?)` | Create an owner for one `Alpine.data` component, with optional default options. |
|
|
67
69
|
| `provideAppHotkeys(appHotkeys, options?)` | Declare app hotkeys and load the user's custom hotkeys once at startup, since Alpine has no provider. |
|
|
68
70
|
| `getHotkeyManager().activateScope(scope, options?)` | Turn on a scope, such as an exclusive one for a dialog; it returns the function that turns the scope off. |
|
|
69
71
|
|
|
70
72
|
Each owner has these methods. Read their state through `.value`, or `.hotkeys` for registrations.
|
|
71
73
|
|
|
72
|
-
| Method | What it's for
|
|
73
|
-
| -------------------------------------------- |
|
|
74
|
-
| `createHotkey(hotkey, callback, options?)` | Register one chord, sequence, or app hotkey until the owner is destroyed; options can be a getter.
|
|
75
|
-
| `createHotkeys(definitions, commonOptions?)` | Register several hotkeys, or a getter of a list built from data, in one call.
|
|
76
|
-
| `createHotkeyRecorder(options)` | Record a chord or sequence the user presses, for a settings screen.
|
|
77
|
-
| `createAppHotkeys()` | Get the declared app hotkeys with the user's custom hotkeys applied.
|
|
78
|
-
| `createAppHotkeyList()` | List every app hotkey with its status, for a cheat sheet or settings screen.
|
|
79
|
-
| `createCustomHotkeys()` | Read, change, and reset the user's custom hotkeys, and check a new one for conflicts.
|
|
80
|
-
| `createHotkeyRegistrations()` | List every registered hotkey with its options and `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
74
|
+
| Method | What it's for |
|
|
75
|
+
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| `createHotkey(hotkey, callback, options?)` | Register one chord, sequence, or app hotkey until the owner is destroyed; options can be a getter. |
|
|
77
|
+
| `createHotkeys(definitions, commonOptions?)` | Register several hotkeys, or a getter of a list built from data, in one call. |
|
|
78
|
+
| `createHotkeyRecorder(options)` | Record a chord or sequence the user presses, for a settings screen. |
|
|
79
|
+
| `createAppHotkeys()` | Get the declared app hotkeys with the user's custom hotkeys applied. |
|
|
80
|
+
| `createAppHotkeyList()` | List every app hotkey with its status, for a cheat sheet or settings screen. |
|
|
81
|
+
| `createCustomHotkeys()` | Read, change, and reset the user's custom hotkeys, and check a new one for conflicts. |
|
|
82
|
+
| `createHotkeyRegistrations()` | List every registered hotkey with its options, `meta`, and `status` (whether it's enabled and in an active scope). |
|
|
83
|
+
| `createHotkeyScopesState()` | Get the active scopes and the exclusive scope that owns the keyboard. |
|
|
84
|
+
| `createHotkeyHint(hotkey, options?)` | Get whether held modifiers should reveal a shortcut's hint. False unless a registration of the hotkey can fire: enabled, in an active scope, and with focus inside its element target. |
|
|
85
|
+
| `createKeyHold(key)` | Get whether one key is held. |
|
|
86
|
+
| `createHeldKeys()` | Get every key that's held right now. |
|
|
87
|
+
| `createHeldKeyCodes()` | Map each held key to its physical `event.code`. |
|
|
88
|
+
| `destroy()` | Release every hotkey, subscription, and recorder the owner created. |
|
|
86
89
|
|
|
87
90
|
The package also re-exports `@tanstack/hotkeys`, such as `formatForDisplay`, `matchesKeyboardEvent`, and `defineAppHotkeys`.
|
|
88
91
|
|