@remcostoeten/use-shortcut 2.0.0 → 2.1.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 +65 -0
- package/dist/cli/index.mjs +20 -6
- package/dist/index.d.ts +135 -4
- package/dist/index.js +1 -795
- package/dist/index.mjs +1 -781
- package/package.json +4 -6
- package/CHANGELOG.md +0 -57
- package/dist/index.d.mts +0 -337
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/src/__tests__/features.test.ts +0 -164
- package/src/builder.ts +0 -179
- package/src/constants.ts +0 -160
- package/src/formatter.ts +0 -97
- package/src/hook.ts +0 -332
- package/src/index.ts +0 -48
- package/src/parser.ts +0 -122
- package/src/runtime/binding.ts +0 -136
- package/src/runtime/conflicts.ts +0 -43
- package/src/runtime/debug.ts +0 -6
- package/src/runtime/guards.ts +0 -82
- package/src/runtime/keys.ts +0 -63
- package/src/runtime/listener.ts +0 -142
- package/src/runtime/recording.ts +0 -39
- package/src/runtime/types.ts +0 -48
- package/src/types.ts +0 -267
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ WIP keyboard shortcut library for React with a chainable API.
|
|
|
10
10
|
## Implemented Features
|
|
11
11
|
|
|
12
12
|
- Chainable shortcut builder: `$.mod.key("k").on(handler)`
|
|
13
|
+
- Bulk shortcut maps: `useShortcutMap()` and `registerShortcutMap()`
|
|
13
14
|
- Modifier support: `ctrl`, `shift`, `alt`, `cmd`, `mod`
|
|
14
15
|
- Sequence support: `$.key("g").then("d")`
|
|
15
16
|
- Scope-aware shortcuts:
|
|
@@ -17,19 +18,83 @@ WIP keyboard shortcut library for React with a chainable API.
|
|
|
17
18
|
- Runtime controls: `setScopes`, `enableScope`, `disableScope`, `getScopes`, `isScopeActive`
|
|
18
19
|
- Exception predicates/presets with `.except(...)`
|
|
19
20
|
- Recording mode: `$.record({ timeoutMs })`
|
|
21
|
+
- Structured debug stream: `$.onDebug(...)` for every keypress
|
|
22
|
+
- Per-shortcut attempt inspection: `result.onAttempt((matched, event, details) => ...)`
|
|
20
23
|
- Conflict detection (`exact`, `sequence-prefix`)
|
|
21
24
|
- Priority ordering and `stopOnMatch`
|
|
22
25
|
- Global guard/filter support via `eventFilter`
|
|
23
26
|
- React entry point:
|
|
24
27
|
- `useShortcut`
|
|
28
|
+
- `useShortcutMap`
|
|
29
|
+
- `useShortcutGroup`
|
|
25
30
|
|
|
26
31
|
## API Intention (Consumer-Facing)
|
|
27
32
|
|
|
28
33
|
- `useShortcut(options?)`
|
|
29
34
|
- Main React hook. Use this for the chainable API (`$.mod.key("s").on(...)`).
|
|
35
|
+
- `useShortcutMap(shortcutMap, options?)`
|
|
36
|
+
- React-safe bulk registration for render paths where a declarative object is cleaner than multiple `.on()` calls.
|
|
37
|
+
- `registerShortcutMap(builder, shortcutMap)`
|
|
38
|
+
- Imperative bulk registration helper when you already have a `useShortcut()` builder.
|
|
30
39
|
|
|
31
40
|
Internal helpers follow underscore naming (for example `_createShortcutBuilder`, `_canonicalizeParsed`) and are not re-exported from `src/index.ts`.
|
|
32
41
|
|
|
42
|
+
## Shortcut Map Example
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useShortcutMap } from "@remcostoeten/use-shortcut"
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
useShortcutMap(
|
|
49
|
+
{
|
|
50
|
+
openPalette: {
|
|
51
|
+
keys: "mod+k",
|
|
52
|
+
handler: () => openPalette(),
|
|
53
|
+
options: { preventDefault: true },
|
|
54
|
+
},
|
|
55
|
+
closePalette: {
|
|
56
|
+
keys: "escape",
|
|
57
|
+
handler: () => closePalette(),
|
|
58
|
+
},
|
|
59
|
+
toggleSidebar: {
|
|
60
|
+
keys: "g then s",
|
|
61
|
+
handler: () => toggleSidebar(),
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{ ignoreInputs: false },
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return <div>Shortcuts ready</div>
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If you already have a builder from `useShortcut()`, you can bulk register with `registerShortcutMap($, shortcutMap)` and unbind the returned handles on cleanup.
|
|
72
|
+
|
|
73
|
+
## Debug Example
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const $ = useShortcut({
|
|
77
|
+
debug: {
|
|
78
|
+
console: true,
|
|
79
|
+
includeCode: true,
|
|
80
|
+
includeLocation: true,
|
|
81
|
+
includeKeyCode: true,
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const unsubscribeDebug = $.onDebug((event) => {
|
|
86
|
+
console.log("key", event.input.combo, event.attempts)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const result = $.shift.key("e").then("e").on(runProbe, {
|
|
90
|
+
description: "sequence probe",
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const unsubscribeAttempt = result.onAttempt?.((matched, _event, details) => {
|
|
94
|
+
console.log(matched ? "matched" : details?.status, details?.steps)
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
33
98
|
## Architecture Notes
|
|
34
99
|
|
|
35
100
|
- Core runtime lives in `src/builder.ts`
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{existsSync as h,mkdirSync as f,readFileSync as
|
|
2
|
+
import{existsSync as h,mkdirSync as f,readFileSync as A,writeFileSync as x}from"fs";import{join as l,dirname as B}from"path";import{fileURLToPath as I}from"url";function m(t){return{"scopes.ts":`/** App-defined scope catalog used by the scaffolded provider. */
|
|
3
3
|
export const shortcutScopes = ["global", "navigation", "editor", "modal"] as const
|
|
4
4
|
|
|
5
5
|
export type ShortcutScope = (typeof shortcutScopes)[number]
|
|
@@ -82,7 +82,7 @@ export type ShortcutContextValue = {
|
|
|
82
82
|
actions: ShortcutActions
|
|
83
83
|
meta: ShortcutMeta
|
|
84
84
|
}
|
|
85
|
-
`,"runtime.ts":`import type { ShortcutMap } from "@remcostoeten/use-shortcut"
|
|
85
|
+
`,"runtime.ts":`import type { HandlerOptions, ShortcutMap } from "@remcostoeten/use-shortcut"
|
|
86
86
|
import { shortcutRegistry, type ShortcutActionId, type ShortcutBindings } from "./registry"
|
|
87
87
|
import type { ShortcutHandlers } from "./types"
|
|
88
88
|
|
|
@@ -120,11 +120,15 @@ export function buildShortcutMap(bindings: ShortcutBindings, handlers: ShortcutH
|
|
|
120
120
|
continue
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
const definitionOptions: Partial<HandlerOptions> = ("options" in definition && definition.options)
|
|
124
|
+
? definition.options
|
|
125
|
+
: {}
|
|
126
|
+
|
|
123
127
|
map[actionId] = {
|
|
124
128
|
keys: bindings[actionId],
|
|
125
129
|
handler,
|
|
126
130
|
options: {
|
|
127
|
-
...
|
|
131
|
+
...definitionOptions,
|
|
128
132
|
scopes: definition.scopes,
|
|
129
133
|
description: definition.description,
|
|
130
134
|
},
|
|
@@ -431,6 +435,16 @@ It follows a scalable architecture with a strict split between:
|
|
|
431
435
|
3. Optionally expose a user-configurable key in your settings UI through \`useShortcutManager().actions.setBinding\`.
|
|
432
436
|
4. Activate scopes from feature boundaries (for example editor route enters \`editor\` scope).
|
|
433
437
|
|
|
438
|
+
## Wiring A React App
|
|
439
|
+
|
|
440
|
+
Scaffold the shortcut files into a React app shell:
|
|
441
|
+
|
|
442
|
+
\`\`\`bash
|
|
443
|
+
npx @remcostoeten/use-shortcut scaffold --framework react --target apps/shortcut-playground/src
|
|
444
|
+
\`\`\`
|
|
445
|
+
|
|
446
|
+
Then wire those generated files into your app root by wrapping your app in \`<ShortcutProvider handlers={...} />\`.
|
|
447
|
+
|
|
434
448
|
${t==="next"?"## Next.js Integration\n\n1. Create a client provider wrapper at `app/shortcut-provider.tsx` and render `<ShortcutProvider />` there.\n2. Render that provider inside `app/layout.tsx` around your app shell.\n3. Keep page/server components pure; shortcut handlers stay in client components.\n":"## React Integration\n\n1. Wrap your app root (for example in `main.tsx`) with `<ShortcutProvider />`.\n2. Keep handlers in a top-level client component and pass them to the provider via `handlers`.\n3. Use `useShortcutManager()` inside feature components to toggle scopes and bindings.\n"}
|
|
435
449
|
## Rules For Scale
|
|
436
450
|
|
|
@@ -438,16 +452,16 @@ ${t==="next"?"## Next.js Integration\n\n1. Create a client provider wrapper at `
|
|
|
438
452
|
- Use scopes instead of conditionals in handlers.
|
|
439
453
|
- Persist only key bindings, not executable handlers.
|
|
440
454
|
- Treat \`registry.ts\` as your architectural contract.
|
|
441
|
-
`}}var k=I(import.meta.url),
|
|
455
|
+
`}}var k=I(import.meta.url),O=B(k),e={reset:"\x1B[0m",green:"\x1B[32m",cyan:"\x1B[36m",yellow:"\x1B[33m",dim:"\x1B[2m",red:"\x1B[31m"};function r(t,o=e.reset){console.log(`${o}${t}${e.reset}`)}function _(){return l(O,"..","src")}function R(t){return l(process.cwd(),t,"use-shortcut")}function C(t,o){return l(process.cwd(),t,o)}function p(t,o,a){let s=t.indexOf(o);if(s===-1)return a;let n=t[s+1];return!n||n.startsWith("--")?a:n}function g(t,o){return t.includes(o)}var P=["index.ts","hook.ts","builder.ts","types.ts","parser.ts","constants.ts","formatter.ts","runtime/types.ts","runtime/binding.ts","runtime/conflicts.ts","runtime/debug.ts","runtime/guards.ts","runtime/keys.ts","runtime/listener.ts","runtime/recording.ts"];function E(t="hooks",o=!1){let a=_(),s=R(t);if(r(`
|
|
442
456
|
use-shortcut CLI
|
|
443
457
|
`,e.cyan),h(s)&&!o){r(`Directory already exists: ${s}`,e.yellow),r(`Use --force to overwrite existing files
|
|
444
|
-
`,e.dim);return}f(s,{recursive:!0});let n=0;for(let i of P){let c=l(a,i),d=l(s,i);if(f(B(d),{recursive:!0}),!h(c)){r(`Source file not found: ${i}`,e.yellow);continue}let u=
|
|
458
|
+
`,e.dim);return}f(s,{recursive:!0});let n=0;for(let i of P){let c=l(a,i),d=l(s,i);if(f(B(d),{recursive:!0}),!h(c)){r(`Source file not found: ${i}`,e.yellow);continue}let u=A(c,"utf-8");x(d,u),n+=1,r(` wrote ${i}`,e.green)}r(`
|
|
445
459
|
Copied ${n} files to:`,e.green),r(` ${s}
|
|
446
460
|
`,e.dim),r("Usage:",e.cyan),r(` import { useShortcut } from "@/${t}/use-shortcut"`,e.dim),r(" const $ = useShortcut()",e.dim),r(` $.mod.key("k").on(() => console.log("Search"))
|
|
447
461
|
`,e.dim)}function y(t,o="src",a="shortcuts",s=!1){let n=C(o,a),i=m(t);r(`
|
|
448
462
|
use-shortcut CLI
|
|
449
463
|
`,e.cyan),r(`Scaffolding ${t} architecture in ${n}
|
|
450
|
-
`,e.dim),f(n,{recursive:!0});let c=0,d=0;for(let[u,
|
|
464
|
+
`,e.dim),f(n,{recursive:!0});let c=0,d=0;for(let[u,w]of Object.entries(i)){let S=l(n,u);if(h(S)&&!s){d+=1,r(` skipped ${u} (already exists)`,e.yellow);continue}x(S,w),c+=1,r(` wrote ${u}`,e.green)}r("",e.reset),r(`Architecture scaffold complete: ${c} written, ${d} skipped.`,e.green),r(`Location: ${n}
|
|
451
465
|
`,e.dim),r("Next steps:",e.cyan),r(` 1. Open ${l(o,a,"registry.ts")} and define your action catalog`,e.dim),r(" 2. Wire app handlers into <ShortcutProvider handlers={...} />",e.dim),r(" 3. Toggle scopes from feature boundaries via useShortcutManager()",e.dim),r(` 4. Optionally expose setBinding/resetBinding in your settings UI
|
|
452
466
|
`,e.dim)}function b(){r(`
|
|
453
467
|
use-shortcut CLI
|
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,57 @@ type ShortcutConflict = {
|
|
|
101
101
|
existingCombo: string;
|
|
102
102
|
reason: "exact" | "sequence-prefix";
|
|
103
103
|
};
|
|
104
|
+
type ShortcutAttemptStatus = "matched" | "partial" | "wrong-order" | "mismatch";
|
|
105
|
+
type ShortcutDebugTokenStatus = "match" | "wrong-order" | "mismatch";
|
|
106
|
+
type ShortcutDebugToken = {
|
|
107
|
+
token: string;
|
|
108
|
+
kind: "modifier" | "key";
|
|
109
|
+
status: ShortcutDebugTokenStatus;
|
|
110
|
+
};
|
|
111
|
+
type ShortcutDebugStep = {
|
|
112
|
+
index: number;
|
|
113
|
+
expected: string;
|
|
114
|
+
actual?: string;
|
|
115
|
+
status: "match" | "partial" | "pending" | "wrong-order" | "mismatch";
|
|
116
|
+
tokens: ShortcutDebugToken[];
|
|
117
|
+
};
|
|
118
|
+
type ShortcutDebugInput = {
|
|
119
|
+
key: string;
|
|
120
|
+
code: string;
|
|
121
|
+
location: number;
|
|
122
|
+
repeat: boolean;
|
|
123
|
+
keyCode?: number;
|
|
124
|
+
which?: number;
|
|
125
|
+
combo: string;
|
|
126
|
+
modifiers: ModifierState;
|
|
127
|
+
};
|
|
128
|
+
type ShortcutAttemptDebugEvent = {
|
|
129
|
+
combo: string;
|
|
130
|
+
display: string;
|
|
131
|
+
description?: string;
|
|
132
|
+
status: ShortcutAttemptStatus;
|
|
133
|
+
matched: boolean;
|
|
134
|
+
progress: number;
|
|
135
|
+
expectedSteps: string[];
|
|
136
|
+
actualSteps: string[];
|
|
137
|
+
stepIndex: number;
|
|
138
|
+
input: ShortcutDebugInput;
|
|
139
|
+
steps: ShortcutDebugStep[];
|
|
140
|
+
};
|
|
141
|
+
type ShortcutDebugEvent = {
|
|
142
|
+
input: ShortcutDebugInput;
|
|
143
|
+
attempts: ShortcutAttemptDebugEvent[];
|
|
144
|
+
};
|
|
145
|
+
type ShortcutDebugOptions = {
|
|
146
|
+
/** Log shortcut attempts to the console (default: true) */
|
|
147
|
+
console?: boolean;
|
|
148
|
+
/** Include `KeyboardEvent.code` in console output */
|
|
149
|
+
includeCode?: boolean;
|
|
150
|
+
/** Include `KeyboardEvent.location` in console output */
|
|
151
|
+
includeLocation?: boolean;
|
|
152
|
+
/** Include deprecated numeric key metadata in console output when available */
|
|
153
|
+
includeKeyCode?: boolean;
|
|
154
|
+
};
|
|
104
155
|
/**
|
|
105
156
|
* Options for shortcut handler registration
|
|
106
157
|
*/
|
|
@@ -146,7 +197,7 @@ type ShortcutResult = {
|
|
|
146
197
|
/** Temporarily disable the shortcut */
|
|
147
198
|
disable: () => void;
|
|
148
199
|
/** Subscribe to shortcut attempt events (useful for visual feedback) */
|
|
149
|
-
onAttempt?: (callback: (matched: boolean, event: KeyboardEvent) => void) => () => void;
|
|
200
|
+
onAttempt?: (callback: (matched: boolean, event: KeyboardEvent, details?: ShortcutAttemptDebugEvent) => void) => () => void;
|
|
150
201
|
};
|
|
151
202
|
/**
|
|
152
203
|
* Chainable modifier builder with type-safe exhaustion
|
|
@@ -234,6 +285,8 @@ type ShortcutBuilder = ModifierChain<EmptyModifiers> & {
|
|
|
234
285
|
getScopes: () => string[];
|
|
235
286
|
/** Check if a scope is active */
|
|
236
287
|
isScopeActive: (scope: string) => boolean;
|
|
288
|
+
/** Subscribe to every keyboard input evaluated by this shortcut registry */
|
|
289
|
+
onDebug: (callback: (event: ShortcutDebugEvent) => void) => () => void;
|
|
237
290
|
/** Record the next key combo */
|
|
238
291
|
record: (options?: ShortcutRecordingOptions) => Promise<string>;
|
|
239
292
|
};
|
|
@@ -241,8 +294,8 @@ type ShortcutBuilder = ModifierChain<EmptyModifiers> & {
|
|
|
241
294
|
* Options for the `useShortcut` hook
|
|
242
295
|
*/
|
|
243
296
|
type UseShortcutOptions = {
|
|
244
|
-
/** Enable debug logging to console */
|
|
245
|
-
debug?: boolean;
|
|
297
|
+
/** Enable debug logging to console or configure structured debug output */
|
|
298
|
+
debug?: boolean | ShortcutDebugOptions;
|
|
246
299
|
/** Global delay for all handlers in milliseconds */
|
|
247
300
|
delay?: number;
|
|
248
301
|
/** Skip shortcuts when focused on input elements (default: `true`) */
|
|
@@ -264,6 +317,26 @@ type UseShortcutOptions = {
|
|
|
264
317
|
/** Global event filter; return false to skip all shortcuts for the event */
|
|
265
318
|
eventFilter?: (event: KeyboardEvent) => boolean;
|
|
266
319
|
};
|
|
320
|
+
/** Single shortcut-map entry used by `registerShortcutMap` and `useShortcutMap`. */
|
|
321
|
+
type ShortcutMapEntry = {
|
|
322
|
+
keys: string | string[];
|
|
323
|
+
handler: ShortcutHandler;
|
|
324
|
+
options?: HandlerOptions;
|
|
325
|
+
};
|
|
326
|
+
/** Bulk registration shape mapping action ids to key+handler definitions. */
|
|
327
|
+
type ShortcutMap = Record<string, ShortcutMapEntry>;
|
|
328
|
+
/** Return type for map registrations, keyed by the same ids as the source map. */
|
|
329
|
+
type ShortcutMapResult<T extends ShortcutMap = ShortcutMap> = {
|
|
330
|
+
[K in keyof T]: ShortcutResult;
|
|
331
|
+
};
|
|
332
|
+
/** Imperative grouping controller for binding/unbinding many shortcut registrations together. */
|
|
333
|
+
type ShortcutGroup = {
|
|
334
|
+
add: (...results: ShortcutResult[]) => void;
|
|
335
|
+
addMany: (results: ShortcutResult[] | Record<string, ShortcutResult>) => void;
|
|
336
|
+
unbindAll: () => void;
|
|
337
|
+
clear: () => void;
|
|
338
|
+
getResults: () => ShortcutResult[];
|
|
339
|
+
};
|
|
267
340
|
|
|
268
341
|
/**
|
|
269
342
|
* Parse a shortcut string into its components
|
|
@@ -317,6 +390,23 @@ declare function matchesAnyShortcut(event: KeyboardEvent, parsedShortcuts: Parse
|
|
|
317
390
|
*/
|
|
318
391
|
declare function formatShortcut(shortcut: string, platform?: PlatformType): string;
|
|
319
392
|
|
|
393
|
+
/**
|
|
394
|
+
* Registers an object-based shortcut map in one call and returns per-action handles.
|
|
395
|
+
*
|
|
396
|
+
* @param builder - Builder returned by `useShortcut()`
|
|
397
|
+
* @param shortcutMap - Record of action ids to key bindings, handlers, and options
|
|
398
|
+
* @returns A result map with one `ShortcutResult` per shortcut id
|
|
399
|
+
*
|
|
400
|
+
* @example
|
|
401
|
+
* ```ts
|
|
402
|
+
* const $ = useShortcut()
|
|
403
|
+
* const results = registerShortcutMap($, {
|
|
404
|
+
* save: { keys: "mod+s", handler: onSave },
|
|
405
|
+
* nav: { keys: ["g", "d"], handler: onGoDashboard },
|
|
406
|
+
* })
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
declare function registerShortcutMap<T extends ShortcutMap>(builder: ShortcutBuilder, shortcutMap: T): ShortcutMapResult<T>;
|
|
320
410
|
/**
|
|
321
411
|
* React hook for registering chainable keyboard shortcuts
|
|
322
412
|
*
|
|
@@ -333,5 +423,46 @@ declare function formatShortcut(shortcut: string, platform?: PlatformType): stri
|
|
|
333
423
|
* ```
|
|
334
424
|
*/
|
|
335
425
|
declare function useShortcut(options?: UseShortcutOptions): ShortcutBuilder;
|
|
426
|
+
/**
|
|
427
|
+
* React hook that registers a shortcut map and automatically unbinds on cleanup.
|
|
428
|
+
*
|
|
429
|
+
* @param shortcutMap - Record of action ids to key bindings, handlers, and options
|
|
430
|
+
* @param options - Same options as `useShortcut()`
|
|
431
|
+
* @returns A map of `ShortcutResult` keyed by your shortcut ids
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```ts
|
|
435
|
+
* const mapResults = useShortcutMap({
|
|
436
|
+
* save: { keys: "mod+s", handler: onSave },
|
|
437
|
+
* close: { keys: "escape", handler: onClose },
|
|
438
|
+
* })
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
declare function useShortcutMap<T extends ShortcutMap>(shortcutMap: T, options?: UseShortcutOptions): ShortcutMapResult<T>;
|
|
442
|
+
/**
|
|
443
|
+
* Creates an imperative group controller for many shortcut registrations.
|
|
444
|
+
*
|
|
445
|
+
* @returns A `ShortcutGroup` that can add and unbind multiple shortcuts together
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```ts
|
|
449
|
+
* const group = createShortcutGroup()
|
|
450
|
+
* group.add($.mod.key("s").on(onSave))
|
|
451
|
+
* group.add($.key("escape").on(onClose))
|
|
452
|
+
* group.unbindAll()
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
declare function createShortcutGroup(): ShortcutGroup;
|
|
456
|
+
/**
|
|
457
|
+
* React hook that returns a stable `ShortcutGroup` instance.
|
|
458
|
+
*
|
|
459
|
+
* @returns A memoized `ShortcutGroup` tied to the component lifecycle
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```ts
|
|
463
|
+
* const group = useShortcutGroup()
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
declare function useShortcutGroup(): ShortcutGroup;
|
|
336
467
|
|
|
337
|
-
export { type ActionKey, type AlphaKey, type ExceptPredicate, type ExceptPreset, type FunctionKey, type HandlerOptions, type KeyChain, ModifierAliases, type ModifierChain, ModifierDisplayOrder, ModifierDisplaySymbols, type ModifierFlags, ModifierKey, type ModifierName, type ModifierState, type NavigationKey, type NumericKey, type ParsedShortcut, Platform, type ShortcutBuilder, type ShortcutConflict, type ShortcutHandler, type ShortcutRecordingOptions, type ShortcutResult, type ShortcutScope, type SpecialKey, SpecialKeyMap, type SymbolKey, type UseShortcutOptions, detectPlatform, formatShortcut, matchesAnyShortcut, matchesShortcut, parseShortcut, parseShortcuts, useShortcut };
|
|
468
|
+
export { type ActionKey, type AlphaKey, type ExceptPredicate, type ExceptPreset, type FunctionKey, type HandlerOptions, type KeyChain, ModifierAliases, type ModifierChain, ModifierDisplayOrder, ModifierDisplaySymbols, type ModifierFlags, ModifierKey, type ModifierName, type ModifierState, type NavigationKey, type NumericKey, type ParsedShortcut, Platform, type ShortcutAttemptDebugEvent, type ShortcutAttemptStatus, type ShortcutBuilder, type ShortcutConflict, type ShortcutDebugEvent, type ShortcutDebugInput, type ShortcutDebugOptions, type ShortcutDebugStep, type ShortcutDebugToken, type ShortcutDebugTokenStatus, type ShortcutGroup, type ShortcutHandler, type ShortcutMap, type ShortcutMapEntry, type ShortcutMapResult, type ShortcutRecordingOptions, type ShortcutResult, type ShortcutScope, type SpecialKey, SpecialKeyMap, type SymbolKey, type UseShortcutOptions, createShortcutGroup, detectPlatform, formatShortcut, matchesAnyShortcut, matchesShortcut, parseShortcut, parseShortcuts, registerShortcutMap, useShortcut, useShortcutGroup, useShortcutMap };
|