@pyreon/hotkeys 0.24.5 → 0.25.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.
@@ -1,69 +0,0 @@
1
- import {
2
- renderApiReferenceEntries,
3
- renderLlmsFullSection,
4
- renderLlmsTxtLine,
5
- } from '@pyreon/manifest'
6
- import manifest from '../manifest'
7
-
8
- describe('gen-docs — hotkeys snapshot', () => {
9
- it('renders to llms.txt bullet', () => {
10
- expect(renderLlmsTxtLine(manifest)).toMatchInlineSnapshot(`"- @pyreon/hotkeys — Keyboard shortcut management — scope-aware, modifier keys, conflict detection. By default, shortcuts do NOT fire when focused on form elements (input, textarea, select). Pass \`enableOnFormElements: true\` in options to override. Escape is a common candidate for this override."`)
11
- })
12
-
13
- it('renders to llms-full.txt section', () => {
14
- expect(renderLlmsFullSection(manifest)).toMatchInlineSnapshot(`
15
- "## @pyreon/hotkeys — Keyboard Shortcuts
16
-
17
- Reactive keyboard shortcut management for Pyreon. Register global or scoped shortcuts with automatic lifecycle management. Supports \`mod\` alias (Command on Mac, Ctrl elsewhere), multi-key combos, scope-based activation for context-aware shortcuts, and conflict detection. Component-scoped hooks auto-unregister on unmount. Imperative API available for non-component contexts.
18
-
19
- \`\`\`typescript
20
- import { useHotkey, useHotkeyScope, registerHotkey, getRegisteredHotkeys, enableScope, disableScope } from '@pyreon/hotkeys'
21
-
22
- // Global shortcut — auto-unregisters on unmount
23
- useHotkey('mod+s', (e) => {
24
- e.preventDefault() // prevent browser save dialog
25
- save()
26
- }, { description: 'Save document' })
27
-
28
- // Platform-aware: mod = ⌘ on Mac, Ctrl on Windows/Linux
29
- useHotkey('mod+k', () => openCommandPalette())
30
-
31
- // Multi-key combo
32
- useHotkey('ctrl+shift+p', () => openPreferences())
33
-
34
- // Scoped shortcuts — only active when scope is enabled
35
- useHotkeyScope('editor') // activates 'editor' scope for this component's lifetime
36
-
37
- useHotkey('ctrl+z', () => undo(), { scope: 'editor', description: 'Undo' })
38
- useHotkey('ctrl+shift+z', () => redo(), { scope: 'editor', description: 'Redo' })
39
- useHotkey('ctrl+d', () => duplicateLine(), { scope: 'editor' })
40
-
41
- // Imperative API — for non-component contexts (stores, middleware)
42
- const unregister = registerHotkey('ctrl+q', () => quit(), { scope: 'global' })
43
- // unregister() when done
44
-
45
- // Introspection
46
- const hotkeys = getRegisteredHotkeys() // all registered shortcuts
47
- enableScope('modal') // programmatically enable a scope
48
- disableScope('editor') // programmatically disable a scope
49
-
50
- // Shortcuts can filter input elements — by default, shortcuts
51
- // don't fire when focused on <input>, <textarea>, <select>.
52
- // Override with:
53
- useHotkey('escape', () => closeModal(), { enableOnFormElements: true })
54
- \`\`\`
55
-
56
- > **Note**: By default, shortcuts do NOT fire when focused on form elements (input, textarea, select). Pass \`enableOnFormElements: true\` in options to override. Escape is a common candidate for this override.
57
- >
58
- > **mod alias**: \`mod\` maps to Command on macOS, Ctrl on Windows/Linux. Write \`mod+s\` instead of platform-specific \`ctrl+s\` / \`cmd+s\` for cross-platform shortcuts.
59
- >
60
- > **Scopes**: Scoped shortcuts only fire when their scope is active. Activate with \`useHotkeyScope(scope)\` (component-scoped) or \`enableScope(scope)\` (imperative). Without activation, scoped handlers are silently dormant.
61
- "
62
- `)
63
- })
64
-
65
- it('renders to MCP api-reference entries', () => {
66
- const record = renderApiReferenceEntries(manifest)
67
- expect(Object.keys(record).length).toBe(3)
68
- })
69
- })
package/src/types.ts DELETED
@@ -1,50 +0,0 @@
1
- // ─── Hotkey Types ────────────────────────────────────────────────────────────
2
-
3
- /**
4
- * A parsed key combination.
5
- * Example: 'ctrl+shift+s' → { ctrl: true, shift: true, alt: false, meta: false, key: 's' }
6
- */
7
- export interface KeyCombo {
8
- ctrl: boolean
9
- shift: boolean
10
- alt: boolean
11
- meta: boolean
12
- key: string
13
- }
14
-
15
- /**
16
- * Options for registering a hotkey.
17
- */
18
- export interface HotkeyOptions {
19
- /** Scope for the hotkey — only active when this scope is active. Default: 'global' */
20
- scope?: string
21
- /** Whether to prevent default browser behavior — default: true */
22
- preventDefault?: boolean
23
- /** Whether to stop event propagation — default: false */
24
- stopPropagation?: boolean
25
- /** Whether the hotkey fires when an input/textarea/contenteditable is focused — default: false */
26
- enableOnInputs?: boolean
27
- /** Description of what this hotkey does — useful for help dialogs */
28
- description?: string
29
- /** Whether the hotkey is enabled — default: true */
30
- enabled?: boolean | (() => boolean)
31
- }
32
-
33
- /**
34
- * A registered hotkey entry.
35
- */
36
- export interface HotkeyEntry {
37
- /** The original shortcut string (e.g. 'ctrl+s') */
38
- shortcut: string
39
- /** Parsed key combination */
40
- combo: KeyCombo
41
- /** The callback to invoke */
42
- handler: (event: KeyboardEvent) => void
43
- /** Options */
44
- options: Required<
45
- Pick<
46
- HotkeyOptions,
47
- 'scope' | 'preventDefault' | 'stopPropagation' | 'enableOnInputs' | 'enabled'
48
- >
49
- > & { description?: string }
50
- }
@@ -1,20 +0,0 @@
1
- import { onUnmount } from '@pyreon/core'
2
- import { disableScope, enableScope } from './registry'
3
-
4
- /**
5
- * Activate a hotkey scope for the lifetime of a component.
6
- * When the component unmounts, the scope is deactivated.
7
- *
8
- * @example
9
- * ```tsx
10
- * function Modal() {
11
- * useHotkeyScope('modal')
12
- * useHotkey('escape', () => closeModal(), { scope: 'modal' })
13
- * // ...
14
- * }
15
- * ```
16
- */
17
- export function useHotkeyScope(scope: string): void {
18
- enableScope(scope)
19
- onUnmount(() => disableScope(scope))
20
- }
package/src/use-hotkey.ts DELETED
@@ -1,26 +0,0 @@
1
- import { onUnmount } from '@pyreon/core'
2
- import { registerHotkey } from './registry'
3
- import type { HotkeyOptions } from './types'
4
-
5
- /**
6
- * Register a keyboard shortcut scoped to a component's lifecycle.
7
- * Automatically unregisters when the component unmounts.
8
- *
9
- * @example
10
- * ```ts
11
- * function Editor() {
12
- * useHotkey('ctrl+s', () => save(), { description: 'Save document' })
13
- * useHotkey('ctrl+z', () => undo())
14
- * useHotkey('ctrl+shift+z', () => redo())
15
- * // ...
16
- * }
17
- * ```
18
- */
19
- export function useHotkey(
20
- shortcut: string,
21
- handler: (event: KeyboardEvent) => void,
22
- options?: HotkeyOptions,
23
- ): void {
24
- const unregister = registerHotkey(shortcut, handler, options)
25
- onUnmount(unregister)
26
- }