@tanstack/hotkeys-devtools 0.4.4 → 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/README.md +1 -1
- package/dist/HotkeysContextProvider.js +25 -2
- package/dist/HotkeysContextProvider.js.map +1 -1
- package/dist/components/DetailsPanel.js +367 -217
- package/dist/components/DetailsPanel.js.map +1 -1
- package/dist/components/HeldKeysTopbar.js +7 -4
- package/dist/components/HeldKeysTopbar.js.map +1 -1
- package/dist/components/HotkeyList.js +229 -195
- package/dist/components/HotkeyList.js.map +1 -1
- package/dist/components/Shell.js +100 -43
- package/dist/components/Shell.js.map +1 -1
- package/dist/sequence-progress.js +20 -0
- package/dist/sequence-progress.js.map +1 -0
- package/dist/styles/use-styles.js +107 -2
- package/dist/styles/use-styles.js.map +1 -1
- package/package.json +2 -2
- package/src/HotkeysContextProvider.tsx +35 -0
- package/src/components/DetailsPanel.tsx +201 -44
- package/src/components/HeldKeysTopbar.tsx +9 -5
- package/src/components/HotkeyList.tsx +187 -151
- package/src/components/Shell.tsx +101 -34
- package/src/sequence-progress.ts +29 -0
- package/src/styles/use-styles.ts +109 -2
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
# TanStack Hotkeys
|
|
38
38
|
|
|
39
39
|
> [!NOTE]
|
|
40
|
-
> TanStack Hotkeys is
|
|
40
|
+
> TanStack Hotkeys is alpha. We are actively developing the library and are open to feedback and contributions.
|
|
41
41
|
|
|
42
42
|
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.
|
|
43
43
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { needsSequenceProgressClock } from "./sequence-progress.js";
|
|
1
2
|
import { createComponent } from "solid-js/web";
|
|
2
3
|
import { createContext, createEffect, createSignal, onCleanup, useContext } from "solid-js";
|
|
3
4
|
import { HotkeyManager, KeyStateTracker, SequenceManager } from "@tanstack/hotkeys";
|
|
@@ -7,7 +8,8 @@ const HotkeysDevtoolsContext = createContext({
|
|
|
7
8
|
registrations: () => [],
|
|
8
9
|
sequenceRegistrations: () => [],
|
|
9
10
|
heldKeys: () => [],
|
|
10
|
-
heldCodes: () => ({})
|
|
11
|
+
heldCodes: () => ({}),
|
|
12
|
+
sequenceProgressNow: () => Date.now()
|
|
11
13
|
});
|
|
12
14
|
function HotkeysContextProvider(props) {
|
|
13
15
|
const manager = HotkeyManager.getInstance();
|
|
@@ -36,12 +38,33 @@ function HotkeysContextProvider(props) {
|
|
|
36
38
|
}).unsubscribe;
|
|
37
39
|
onCleanup(() => unsubscribe());
|
|
38
40
|
});
|
|
41
|
+
const [sequenceProgressNow, setSequenceProgressNow] = createSignal(Date.now());
|
|
42
|
+
createEffect(() => {
|
|
43
|
+
const regs = sequenceRegistrations();
|
|
44
|
+
let id;
|
|
45
|
+
const tick = () => {
|
|
46
|
+
const t = Date.now();
|
|
47
|
+
setSequenceProgressNow(t);
|
|
48
|
+
if (!needsSequenceProgressClock(sequenceRegistrations(), t)) {
|
|
49
|
+
if (id !== void 0) {
|
|
50
|
+
clearInterval(id);
|
|
51
|
+
id = void 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (needsSequenceProgressClock(regs, Date.now())) id = setInterval(tick, 50);
|
|
56
|
+
else setSequenceProgressNow(Date.now());
|
|
57
|
+
onCleanup(() => {
|
|
58
|
+
if (id !== void 0) clearInterval(id);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
39
61
|
return createComponent(HotkeysDevtoolsContext.Provider, {
|
|
40
62
|
value: {
|
|
41
63
|
registrations,
|
|
42
64
|
sequenceRegistrations,
|
|
43
65
|
heldKeys,
|
|
44
|
-
heldCodes
|
|
66
|
+
heldCodes,
|
|
67
|
+
sequenceProgressNow
|
|
45
68
|
},
|
|
46
69
|
get children() {
|
|
47
70
|
return props.children;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HotkeysContextProvider.js","names":["createContext","createEffect","createSignal","onCleanup","useContext","HotkeyManager","KeyStateTracker","SequenceManager","Accessor","HotkeyRegistration","SequenceRegistrationView","HotkeysDevtoolsContextType","registrations","Array","sequenceRegistrations","heldKeys","heldCodes","Record","HotkeysDevtoolsContext","HotkeysContextProvider","props","children","manager","getInstance","sequenceManager","tracker","setRegistrations","from","state","values","setSequenceRegistrations","setHeldKeys","store","setHeldCodes","unsubscribe","subscribe","_$createComponent","Provider","value","useHotkeysDevtoolsState"],"sources":["../src/HotkeysContextProvider.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createSignal,\n onCleanup,\n useContext,\n} from 'solid-js'\nimport {\n HotkeyManager,\n KeyStateTracker,\n SequenceManager,\n} from '@tanstack/hotkeys'\nimport type { Accessor } from 'solid-js'\nimport type {\n HotkeyRegistration,\n SequenceRegistrationView,\n} from '@tanstack/hotkeys'\n\ninterface HotkeysDevtoolsContextType {\n registrations: Accessor<Array<HotkeyRegistration>>\n sequenceRegistrations: Accessor<Array<SequenceRegistrationView>>\n heldKeys: Accessor<Array<string>>\n heldCodes: Accessor<Record<string, string>>\n}\n\nconst HotkeysDevtoolsContext = createContext<HotkeysDevtoolsContextType>({\n registrations: () => [],\n sequenceRegistrations: () => [],\n heldKeys: () => [],\n heldCodes: () => ({}),\n})\n\nexport function HotkeysContextProvider(props: { children: any }) {\n const manager = HotkeyManager.getInstance()\n const sequenceManager = SequenceManager.getInstance()\n const tracker = KeyStateTracker.getInstance()\n\n // Create local signals that will be updated by subscriptions\n const [registrations, setRegistrations] = createSignal<\n Array<HotkeyRegistration>\n >(Array.from(manager.registrations.state.values()))\n const [sequenceRegistrations, setSequenceRegistrations] = createSignal<\n Array<SequenceRegistrationView>\n >(Array.from(sequenceManager.registrations.state.values()))\n const [heldKeys, setHeldKeys] = createSignal<Array<string>>(\n tracker.store.state.heldKeys,\n )\n const [heldCodes, setHeldCodes] = createSignal<Record<string, string>>(\n tracker.store.state.heldCodes,\n )\n\n // Subscribe to HotkeyManager registrations store\n createEffect(() => {\n const unsubscribe = manager.registrations.subscribe(() => {\n setRegistrations(Array.from(manager.registrations.state.values()))\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n // Subscribe to SequenceManager registrations store\n createEffect(() => {\n const unsubscribe = sequenceManager.registrations.subscribe(() => {\n setSequenceRegistrations(\n Array.from(sequenceManager.registrations.state.values()),\n )\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n // Subscribe to KeyStateTracker store\n createEffect(() => {\n const unsubscribe = tracker.store.subscribe(() => {\n setHeldKeys(tracker.store.state.heldKeys)\n setHeldCodes(tracker.store.state.heldCodes)\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n return (\n <HotkeysDevtoolsContext.Provider\n value={{\n registrations,\n sequenceRegistrations,\n heldKeys,\n heldCodes,\n }}\n >\n {props.children}\n </HotkeysDevtoolsContext.Provider>\n )\n}\n\nexport function useHotkeysDevtoolsState() {\n return useContext(HotkeysDevtoolsContext)\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"HotkeysContextProvider.js","names":["createContext","createEffect","createSignal","onCleanup","useContext","HotkeyManager","KeyStateTracker","SequenceManager","needsSequenceProgressClock","Accessor","HotkeyRegistration","SequenceRegistrationView","HotkeysDevtoolsContextType","registrations","Array","sequenceRegistrations","heldKeys","heldCodes","Record","sequenceProgressNow","HotkeysDevtoolsContext","Date","now","HotkeysContextProvider","props","children","manager","getInstance","sequenceManager","tracker","setRegistrations","from","state","values","setSequenceRegistrations","setHeldKeys","store","setHeldCodes","unsubscribe","subscribe","setSequenceProgressNow","regs","id","ReturnType","setInterval","tick","t","undefined","clearInterval","_$createComponent","Provider","value","useHotkeysDevtoolsState"],"sources":["../src/HotkeysContextProvider.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createSignal,\n onCleanup,\n useContext,\n} from 'solid-js'\nimport {\n HotkeyManager,\n KeyStateTracker,\n SequenceManager,\n} from '@tanstack/hotkeys'\nimport { needsSequenceProgressClock } from './sequence-progress'\nimport type { Accessor } from 'solid-js'\nimport type {\n HotkeyRegistration,\n SequenceRegistrationView,\n} from '@tanstack/hotkeys'\n\ninterface HotkeysDevtoolsContextType {\n registrations: Accessor<Array<HotkeyRegistration>>\n sequenceRegistrations: Accessor<Array<SequenceRegistrationView>>\n heldKeys: Accessor<Array<string>>\n heldCodes: Accessor<Record<string, string>>\n /** Monotonic clock for sequence in-progress UI (updates while a sequence match is active). */\n sequenceProgressNow: Accessor<number>\n}\n\nconst HotkeysDevtoolsContext = createContext<HotkeysDevtoolsContextType>({\n registrations: () => [],\n sequenceRegistrations: () => [],\n heldKeys: () => [],\n heldCodes: () => ({}),\n sequenceProgressNow: () => Date.now(),\n})\n\nexport function HotkeysContextProvider(props: { children: any }) {\n const manager = HotkeyManager.getInstance()\n const sequenceManager = SequenceManager.getInstance()\n const tracker = KeyStateTracker.getInstance()\n\n // Create local signals that will be updated by subscriptions\n const [registrations, setRegistrations] = createSignal<\n Array<HotkeyRegistration>\n >(Array.from(manager.registrations.state.values()))\n const [sequenceRegistrations, setSequenceRegistrations] = createSignal<\n Array<SequenceRegistrationView>\n >(Array.from(sequenceManager.registrations.state.values()))\n const [heldKeys, setHeldKeys] = createSignal<Array<string>>(\n tracker.store.state.heldKeys,\n )\n const [heldCodes, setHeldCodes] = createSignal<Record<string, string>>(\n tracker.store.state.heldCodes,\n )\n\n // Subscribe to HotkeyManager registrations store\n createEffect(() => {\n const unsubscribe = manager.registrations.subscribe(() => {\n setRegistrations(Array.from(manager.registrations.state.values()))\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n // Subscribe to SequenceManager registrations store\n createEffect(() => {\n const unsubscribe = sequenceManager.registrations.subscribe(() => {\n setSequenceRegistrations(\n Array.from(sequenceManager.registrations.state.values()),\n )\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n // Subscribe to KeyStateTracker store\n createEffect(() => {\n const unsubscribe = tracker.store.subscribe(() => {\n setHeldKeys(tracker.store.state.heldKeys)\n setHeldCodes(tracker.store.state.heldCodes)\n }).unsubscribe\n onCleanup(() => unsubscribe())\n })\n\n const [sequenceProgressNow, setSequenceProgressNow] = createSignal(Date.now())\n\n createEffect(() => {\n const regs = sequenceRegistrations()\n let id: ReturnType<typeof setInterval> | undefined\n\n const tick = () => {\n const t = Date.now()\n setSequenceProgressNow(t)\n if (!needsSequenceProgressClock(sequenceRegistrations(), t)) {\n if (id !== undefined) {\n clearInterval(id)\n id = undefined\n }\n }\n }\n\n if (needsSequenceProgressClock(regs, Date.now())) {\n id = setInterval(tick, 50)\n } else {\n setSequenceProgressNow(Date.now())\n }\n\n onCleanup(() => {\n if (id !== undefined) {\n clearInterval(id)\n }\n })\n })\n\n return (\n <HotkeysDevtoolsContext.Provider\n value={{\n registrations,\n sequenceRegistrations,\n heldKeys,\n heldCodes,\n sequenceProgressNow,\n }}\n >\n {props.children}\n </HotkeysDevtoolsContext.Provider>\n )\n}\n\nexport function useHotkeysDevtoolsState() {\n return useContext(HotkeysDevtoolsContext)\n}\n"],"mappings":";;;;;;AA4BA,MAAMoB,yBAAyBpB,cAA0C;CACvEa,qBAAqB,EAAE;CACvBE,6BAA6B,EAAE;CAC/BC,gBAAgB,EAAE;CAClBC,kBAAkB,EAAE;CACpBE,2BAA2BE,KAAKC,KAAI;CACrC,CAAC;AAEF,SAAgBC,uBAAuBC,OAA0B;CAC/D,MAAME,UAAUrB,cAAcsB,aAAa;CAC3C,MAAMC,kBAAkBrB,gBAAgBoB,aAAa;CACrD,MAAME,UAAUvB,gBAAgBqB,aAAa;CAG7C,MAAM,CAACd,eAAeiB,oBAAoB5B,aAExCY,MAAMiB,KAAKL,QAAQb,cAAcmB,MAAMC,QAAQ,CAAC,CAAC;CACnD,MAAM,CAAClB,uBAAuBmB,4BAA4BhC,aAExDY,MAAMiB,KAAKH,gBAAgBf,cAAcmB,MAAMC,QAAQ,CAAC,CAAC;CAC3D,MAAM,CAACjB,UAAUmB,eAAejC,aAC9B2B,QAAQO,MAAMJ,MAAMhB,SACrB;CACD,MAAM,CAACC,WAAWoB,gBAAgBnC,aAChC2B,QAAQO,MAAMJ,MAAMf,UACrB;AAGDhB,oBAAmB;EACjB,MAAMqC,cAAcZ,QAAQb,cAAc0B,gBAAgB;AACxDT,oBAAiBhB,MAAMiB,KAAKL,QAAQb,cAAcmB,MAAMC,QAAQ,CAAC,CAAC;IAClE,CAACK;AACHnC,kBAAgBmC,aAAa,CAAC;GAC9B;AAGFrC,oBAAmB;EACjB,MAAMqC,cAAcV,gBAAgBf,cAAc0B,gBAAgB;AAChEL,4BACEpB,MAAMiB,KAAKH,gBAAgBf,cAAcmB,MAAMC,QAAQ,CACzD,CAAC;IACD,CAACK;AACHnC,kBAAgBmC,aAAa,CAAC;GAC9B;AAGFrC,oBAAmB;EACjB,MAAMqC,cAAcT,QAAQO,MAAMG,gBAAgB;AAChDJ,eAAYN,QAAQO,MAAMJ,MAAMhB,SAAS;AACzCqB,gBAAaR,QAAQO,MAAMJ,MAAMf,UAAU;IAC3C,CAACqB;AACHnC,kBAAgBmC,aAAa,CAAC;GAC9B;CAEF,MAAM,CAACnB,qBAAqBqB,0BAA0BtC,aAAamB,KAAKC,KAAK,CAAC;AAE9ErB,oBAAmB;EACjB,MAAMwC,OAAO1B,uBAAuB;EACpC,IAAI2B;EAEJ,MAAMG,aAAa;GACjB,MAAMC,IAAIzB,KAAKC,KAAK;AACpBkB,0BAAuBM,EAAE;AACzB,OAAI,CAACtC,2BAA2BO,uBAAuB,EAAE+B,EAAE,EACzD;QAAIJ,OAAOK,QAAW;AACpBC,mBAAcN,GAAG;AACjBA,UAAKK;;;;AAKX,MAAIvC,2BAA2BiC,MAAMpB,KAAKC,KAAK,CAAC,CAC9CoB,MAAKE,YAAYC,MAAM,GAAG;MAE1BL,wBAAuBnB,KAAKC,KAAK,CAAC;AAGpCnB,kBAAgB;AACd,OAAIuC,OAAOK,OACTC,eAAcN,GAAG;IAEnB;GACF;AAEF,QAAAO,gBACG7B,uBAAuB8B,UAAQ;EAC9BC,OAAO;GACLtC;GACAE;GACAC;GACAC;GACAE;GACD;EAAA,IAAAM,WAAA;AAAA,UAEAD,MAAMC;;EAAQ,CAAA;;AAKrB,SAAgB2B,0BAA0B;AACxC,QAAOhD,WAAWgB,uBAAuB"}
|