@tanstack/hotkeys 0.5.0 → 0.6.1
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/constants.cjs +70 -10
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +57 -4
- package/dist/constants.d.ts +57 -4
- package/dist/constants.js +67 -10
- package/dist/constants.js.map +1 -1
- package/dist/format.cjs +20 -125
- package/dist/format.cjs.map +1 -1
- package/dist/format.d.cts +8 -72
- package/dist/format.d.ts +8 -72
- package/dist/format.js +23 -127
- package/dist/format.js.map +1 -1
- package/dist/hotkey-manager.cjs.map +1 -1
- package/dist/hotkey-manager.d.cts +5 -1
- package/dist/hotkey-manager.d.ts +5 -1
- package/dist/hotkey-manager.js.map +1 -1
- package/dist/hotkey.d.cts +2 -0
- package/dist/hotkey.d.ts +2 -0
- package/dist/index.cjs +7 -5
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/parse.cjs +53 -91
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.d.cts +31 -72
- package/dist/parse.d.ts +31 -72
- package/dist/parse.js +51 -89
- package/dist/parse.js.map +1 -1
- package/dist/recorder-chord.cjs +3 -2
- package/dist/recorder-chord.cjs.map +1 -1
- package/dist/recorder-chord.js +4 -3
- package/dist/recorder-chord.js.map +1 -1
- package/dist/sequence-manager.cjs +1 -1
- package/dist/sequence-manager.cjs.map +1 -1
- package/dist/sequence-manager.js +2 -2
- package/dist/sequence-manager.js.map +1 -1
- package/package.json +2 -2
- package/src/constants.ts +75 -21
- package/src/format.ts +58 -196
- package/src/hotkey-manager.ts +5 -1
- package/src/hotkey.ts +2 -0
- package/src/parse.ts +91 -131
- package/src/recorder-chord.ts +4 -5
- package/src/sequence-manager.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/hotkeys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Type-safe, framework-agnostic keyboard hotkey management for the browser",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"src"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@tanstack/store": "^0.9.
|
|
46
|
+
"@tanstack/store": "^0.9.3"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"clean": "premove ./build ./dist",
|
package/src/constants.ts
CHANGED
|
@@ -8,10 +8,6 @@ import type {
|
|
|
8
8
|
PunctuationKey,
|
|
9
9
|
} from './hotkey'
|
|
10
10
|
|
|
11
|
-
// =============================================================================
|
|
12
|
-
// Platform Detection
|
|
13
|
-
// =============================================================================
|
|
14
|
-
|
|
15
11
|
/**
|
|
16
12
|
* Detects the current platform based on browser navigator properties.
|
|
17
13
|
*
|
|
@@ -46,10 +42,6 @@ export function detectPlatform(): 'mac' | 'windows' | 'linux' {
|
|
|
46
42
|
return 'linux'
|
|
47
43
|
}
|
|
48
44
|
|
|
49
|
-
// =============================================================================
|
|
50
|
-
// Modifier Aliases
|
|
51
|
-
// =============================================================================
|
|
52
|
-
|
|
53
45
|
/**
|
|
54
46
|
* Canonical order for modifiers in normalized hotkey strings.
|
|
55
47
|
*
|
|
@@ -124,6 +116,12 @@ export const MODIFIER_ALIASES: Record<string, CanonicalModifier | 'Mod'> = {
|
|
|
124
116
|
cmd: 'Meta',
|
|
125
117
|
meta: 'Meta',
|
|
126
118
|
|
|
119
|
+
// DOM `KeyboardEvent.key` spellings for the meta / Windows key
|
|
120
|
+
OS: 'Meta',
|
|
121
|
+
os: 'Meta',
|
|
122
|
+
Win: 'Meta',
|
|
123
|
+
win: 'Meta',
|
|
124
|
+
|
|
127
125
|
// Platform-adaptive (resolved at runtime)
|
|
128
126
|
CommandOrControl: 'Mod',
|
|
129
127
|
Mod: 'Mod',
|
|
@@ -162,10 +160,6 @@ export function resolveModifier(
|
|
|
162
160
|
return modifier
|
|
163
161
|
}
|
|
164
162
|
|
|
165
|
-
// =============================================================================
|
|
166
|
-
// Valid Keys
|
|
167
|
-
// =============================================================================
|
|
168
|
-
|
|
169
163
|
/**
|
|
170
164
|
* Set of all valid letter keys (A-Z).
|
|
171
165
|
*
|
|
@@ -311,16 +305,16 @@ export const PUNCTUATION_KEYS = new Set<PunctuationKey>([
|
|
|
311
305
|
* fallbacks for letters and digits.
|
|
312
306
|
*/
|
|
313
307
|
export const PUNCTUATION_CODE_MAP: Record<string, string> = {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
Slash: '/',
|
|
308
|
+
Backquote: '`',
|
|
309
|
+
Backslash: '\\',
|
|
317
310
|
BracketLeft: '[',
|
|
318
311
|
BracketRight: ']',
|
|
319
|
-
Backslash: '\\',
|
|
320
312
|
Comma: ',',
|
|
313
|
+
Equal: '=',
|
|
314
|
+
Minus: '-',
|
|
321
315
|
Period: '.',
|
|
322
|
-
Backquote: '`',
|
|
323
316
|
Semicolon: ';',
|
|
317
|
+
Slash: '/',
|
|
324
318
|
}
|
|
325
319
|
|
|
326
320
|
/**
|
|
@@ -446,6 +440,20 @@ export function isSingleLetterKey(key: string): boolean {
|
|
|
446
440
|
return /^\p{Letter}$/u.test(key)
|
|
447
441
|
}
|
|
448
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Normalizes a key name to its canonical form.
|
|
445
|
+
*
|
|
446
|
+
* @param key - The key name to normalize (can be an alias, lowercase, etc.)
|
|
447
|
+
* @returns The canonical key name
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```ts
|
|
451
|
+
* normalizeKeyName('esc') // 'Escape'
|
|
452
|
+
* normalizeKeyName('a') // 'A'
|
|
453
|
+
* normalizeKeyName('f1') // 'F1'
|
|
454
|
+
* normalizeKeyName('ArrowUp') // 'ArrowUp' (already canonical)
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
449
457
|
export function normalizeKeyName(key: string): string {
|
|
450
458
|
// Check aliases first
|
|
451
459
|
if (key in KEY_ALIASES) {
|
|
@@ -488,11 +496,35 @@ export function normalizeKeyName(key: string): string {
|
|
|
488
496
|
* MAC_MODIFIER_SYMBOLS['Shift'] // '⇧'
|
|
489
497
|
* ```
|
|
490
498
|
*/
|
|
491
|
-
export const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier, string> = {
|
|
499
|
+
export const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier | 'Mod', string> = {
|
|
492
500
|
Control: '⌃',
|
|
493
501
|
Alt: '⌥',
|
|
494
502
|
Shift: '⇧',
|
|
495
503
|
Meta: '⌘',
|
|
504
|
+
Mod: '⌘',
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Modifier key labels for macOS display.
|
|
509
|
+
*
|
|
510
|
+
* Used by formatting functions to display hotkeys with macOS-style text labels
|
|
511
|
+
* (e.g., 'Control' for Control, 'Option' for Alt, 'Cmd' for Meta) instead of symbols.
|
|
512
|
+
* This provides a familiar macOS look and feel in hotkey displays.
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```ts
|
|
516
|
+
* MAC_MODIFIER_LABELS['Control'] // 'control'
|
|
517
|
+
* MAC_MODIFIER_LABELS['Alt'] // 'option'
|
|
518
|
+
* MAC_MODIFIER_LABELS['Shift'] // 'shift'
|
|
519
|
+
* MAC_MODIFIER_LABELS['Meta'] // 'cmd'
|
|
520
|
+
* ```
|
|
521
|
+
*/
|
|
522
|
+
export const MAC_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string> = {
|
|
523
|
+
Control: 'Control',
|
|
524
|
+
Alt: 'Option',
|
|
525
|
+
Shift: 'Shift',
|
|
526
|
+
Meta: 'Cmd',
|
|
527
|
+
Mod: 'Cmd',
|
|
496
528
|
}
|
|
497
529
|
|
|
498
530
|
/**
|
|
@@ -510,13 +542,35 @@ export const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier, string> = {
|
|
|
510
542
|
* STANDARD_MODIFIER_LABELS['Shift'] // 'Shift'
|
|
511
543
|
* ```
|
|
512
544
|
*/
|
|
513
|
-
export const
|
|
545
|
+
export const WINDOWS_MODIFIER_LABELS: Record<
|
|
546
|
+
CanonicalModifier | 'Mod',
|
|
547
|
+
string
|
|
548
|
+
> = {
|
|
514
549
|
Control: 'Ctrl',
|
|
515
550
|
Alt: 'Alt',
|
|
516
551
|
Shift: 'Shift',
|
|
517
552
|
Meta: 'Win',
|
|
553
|
+
Mod: 'Ctrl',
|
|
518
554
|
}
|
|
519
555
|
|
|
556
|
+
export const LINUX_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string> =
|
|
557
|
+
{
|
|
558
|
+
...WINDOWS_MODIFIER_LABELS,
|
|
559
|
+
Meta: 'Super',
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
export const PUNCTUATION_KEY_DISPLAY_LABELS = {
|
|
563
|
+
'`': 'Backquote',
|
|
564
|
+
'\\': 'Backslash',
|
|
565
|
+
'[': 'Left Bracket',
|
|
566
|
+
']': 'Right Bracket',
|
|
567
|
+
',': 'Comma',
|
|
568
|
+
'=': 'Equal',
|
|
569
|
+
'-': 'Minus',
|
|
570
|
+
'.': 'Period',
|
|
571
|
+
';': 'Semicolon',
|
|
572
|
+
} as const satisfies Record<string, string>
|
|
573
|
+
|
|
520
574
|
/**
|
|
521
575
|
* Special key symbols for display formatting.
|
|
522
576
|
*
|
|
@@ -532,7 +586,7 @@ export const STANDARD_MODIFIER_LABELS: Record<CanonicalModifier, string> = {
|
|
|
532
586
|
* KEY_DISPLAY_SYMBOLS['Space'] // '␣'
|
|
533
587
|
* ```
|
|
534
588
|
*/
|
|
535
|
-
export const KEY_DISPLAY_SYMBOLS
|
|
589
|
+
export const KEY_DISPLAY_SYMBOLS = {
|
|
536
590
|
ArrowUp: '↑',
|
|
537
591
|
ArrowDown: '↓',
|
|
538
592
|
ArrowLeft: '←',
|
|
@@ -543,4 +597,4 @@ export const KEY_DISPLAY_SYMBOLS: Record<string, string> = {
|
|
|
543
597
|
Delete: '⌦',
|
|
544
598
|
Tab: '⇥',
|
|
545
599
|
Space: '␣',
|
|
546
|
-
}
|
|
600
|
+
} as const satisfies Record<string, string>
|
package/src/format.ts
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KEY_DISPLAY_SYMBOLS,
|
|
3
|
+
LINUX_MODIFIER_LABELS,
|
|
4
|
+
MAC_MODIFIER_LABELS,
|
|
3
5
|
MAC_MODIFIER_SYMBOLS,
|
|
6
|
+
MODIFIER_ALIASES,
|
|
4
7
|
MODIFIER_ORDER,
|
|
5
|
-
|
|
8
|
+
PUNCTUATION_KEY_DISPLAY_LABELS,
|
|
9
|
+
WINDOWS_MODIFIER_LABELS,
|
|
6
10
|
detectPlatform,
|
|
7
11
|
} from './constants'
|
|
8
|
-
import {
|
|
9
|
-
|
|
12
|
+
import {
|
|
13
|
+
isModifierKey,
|
|
14
|
+
normalizeHotkeyFromParsed,
|
|
15
|
+
normalizeRegisterableHotkey,
|
|
16
|
+
} from './parse'
|
|
17
|
+
import type {
|
|
18
|
+
CanonicalModifier,
|
|
19
|
+
FormatDisplayOptions,
|
|
20
|
+
Hotkey,
|
|
21
|
+
ParsedHotkey,
|
|
22
|
+
RegisterableHotkey,
|
|
23
|
+
} from './hotkey'
|
|
10
24
|
|
|
11
25
|
/**
|
|
12
26
|
* Converts a hotkey sequence array to a display string.
|
|
@@ -55,8 +69,8 @@ export function formatHotkey(parsed: ParsedHotkey): string {
|
|
|
55
69
|
/**
|
|
56
70
|
* Formats a hotkey for display in a user interface.
|
|
57
71
|
*
|
|
58
|
-
* On macOS, uses symbols (⌘⇧S).
|
|
59
|
-
* On Windows/Linux, uses text (Ctrl+Shift+S).
|
|
72
|
+
* On macOS, uses symbols (⌘⇧S) in the same modifier order as {@link normalizeHotkeyFromParsed}.
|
|
73
|
+
* On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.
|
|
60
74
|
*
|
|
61
75
|
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
62
76
|
* @param options - Formatting options
|
|
@@ -65,7 +79,7 @@ export function formatHotkey(parsed: ParsedHotkey): string {
|
|
|
65
79
|
* @example
|
|
66
80
|
* ```ts
|
|
67
81
|
* formatForDisplay('Mod+Shift+S', { platform: 'mac' })
|
|
68
|
-
* // Returns: '
|
|
82
|
+
* // Returns: '⌘ ⇧ S' (symbols separated by spaces on macOS)
|
|
69
83
|
*
|
|
70
84
|
* formatForDisplay('Mod+Shift+S', { platform: 'windows' })
|
|
71
85
|
* // Returns: 'Ctrl+Shift+S'
|
|
@@ -75,203 +89,51 @@ export function formatHotkey(parsed: ParsedHotkey): string {
|
|
|
75
89
|
* ```
|
|
76
90
|
*/
|
|
77
91
|
export function formatForDisplay(
|
|
78
|
-
hotkey:
|
|
92
|
+
hotkey: RegisterableHotkey | (string & {}),
|
|
79
93
|
options: FormatDisplayOptions = {},
|
|
80
94
|
): string {
|
|
81
95
|
const platform = options.platform ?? detectPlatform()
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
* Formats a hotkey for Windows/Linux display using text labels.
|
|
116
|
-
*/
|
|
117
|
-
function formatForStandard(parsed: ParsedHotkey): string {
|
|
118
|
-
const parts: Array<string> = []
|
|
119
|
-
|
|
120
|
-
// Add modifiers in canonical order
|
|
121
|
-
for (const modifier of MODIFIER_ORDER) {
|
|
122
|
-
if (parsed.modifiers.includes(modifier)) {
|
|
123
|
-
parts.push(STANDARD_MODIFIER_LABELS[modifier])
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Add the key (use symbol/short form if available)
|
|
128
|
-
const keyDisplay = KEY_DISPLAY_SYMBOLS[parsed.key] ?? parsed.key
|
|
129
|
-
parts.push(keyDisplay)
|
|
130
|
-
|
|
131
|
-
// On Windows/Linux, use + as separator
|
|
132
|
-
return parts.join('+')
|
|
96
|
+
const useSymbols = options.useSymbols ?? true
|
|
97
|
+
const normalizedHotkey = normalizeRegisterableHotkey(
|
|
98
|
+
hotkey as RegisterableHotkey,
|
|
99
|
+
platform,
|
|
100
|
+
)
|
|
101
|
+
return normalizedHotkey
|
|
102
|
+
.split('+')
|
|
103
|
+
.map((segment) => {
|
|
104
|
+
if (isModifierKey(segment)) {
|
|
105
|
+
const modifierToken = (MODIFIER_ALIASES[segment] ??
|
|
106
|
+
MODIFIER_ALIASES[segment.toLowerCase()]) as CanonicalModifier | 'Mod'
|
|
107
|
+
return platform === 'mac'
|
|
108
|
+
? useSymbols
|
|
109
|
+
? MAC_MODIFIER_SYMBOLS[modifierToken]
|
|
110
|
+
: MAC_MODIFIER_LABELS[modifierToken]
|
|
111
|
+
: platform === 'windows'
|
|
112
|
+
? WINDOWS_MODIFIER_LABELS[modifierToken]
|
|
113
|
+
: LINUX_MODIFIER_LABELS[modifierToken]
|
|
114
|
+
} else {
|
|
115
|
+
const keyDisplaySymbol =
|
|
116
|
+
useSymbols &&
|
|
117
|
+
KEY_DISPLAY_SYMBOLS[segment as keyof typeof KEY_DISPLAY_SYMBOLS]
|
|
118
|
+
if (keyDisplaySymbol) return keyDisplaySymbol
|
|
119
|
+
|
|
120
|
+
const punctuationKeyDisplayLabel =
|
|
121
|
+
!useSymbols &&
|
|
122
|
+
PUNCTUATION_KEY_DISPLAY_LABELS[
|
|
123
|
+
segment as keyof typeof PUNCTUATION_KEY_DISPLAY_LABELS
|
|
124
|
+
]
|
|
125
|
+
return punctuationKeyDisplayLabel || segment
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
.join(platform === 'mac' && useSymbols ? ' ' : '+')
|
|
133
129
|
}
|
|
134
130
|
|
|
135
131
|
/**
|
|
136
|
-
*
|
|
137
|
-
* Uses 'Cmd' on Mac and 'Ctrl' for Control, etc.
|
|
138
|
-
*
|
|
139
|
-
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
140
|
-
* @param platform - The target platform
|
|
141
|
-
* @returns A formatted string with platform-appropriate labels
|
|
132
|
+
* @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.
|
|
142
133
|
*/
|
|
143
134
|
export function formatWithLabels(
|
|
144
|
-
hotkey:
|
|
145
|
-
|
|
146
|
-
): string {
|
|
147
|
-
const parsed =
|
|
148
|
-
typeof hotkey === 'string' ? parseHotkey(hotkey, platform) : hotkey
|
|
149
|
-
const parts: Array<string> = []
|
|
150
|
-
|
|
151
|
-
// Custom labels for more readable output
|
|
152
|
-
const labels: Record<string, string> = {
|
|
153
|
-
Control: 'Ctrl',
|
|
154
|
-
Alt: platform === 'mac' ? 'Option' : 'Alt',
|
|
155
|
-
Shift: 'Shift',
|
|
156
|
-
Meta: platform === 'mac' ? 'Cmd' : 'Win',
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
for (const modifier of MODIFIER_ORDER) {
|
|
160
|
-
if (parsed.modifiers.includes(modifier)) {
|
|
161
|
-
parts.push(labels[modifier] ?? modifier)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Add the key
|
|
166
|
-
parts.push(parsed.key)
|
|
167
|
-
|
|
168
|
-
return parts.join('+')
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// =============================================================================
|
|
172
|
-
// Debugging Display Labels
|
|
173
|
-
// =============================================================================
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Maps canonical modifier names to debugging-friendly labels per platform.
|
|
177
|
-
*/
|
|
178
|
-
const MODIFIER_DEBUG_LABELS: Record<string, Record<string, string>> = {
|
|
179
|
-
mac: { Meta: 'Mod (Cmd)', Control: 'Ctrl', Alt: 'Opt', Shift: 'Shift' },
|
|
180
|
-
windows: { Control: 'Mod (Ctrl)', Meta: 'Win', Alt: 'Alt', Shift: 'Shift' },
|
|
181
|
-
linux: { Control: 'Mod (Ctrl)', Meta: 'Super', Alt: 'Alt', Shift: 'Shift' },
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Options for formatting a single key for debugging display.
|
|
186
|
-
*/
|
|
187
|
-
export interface FormatKeyDebuggingOptions {
|
|
188
|
-
/** The target platform. Defaults to auto-detection. */
|
|
189
|
-
platform?: 'mac' | 'windows' | 'linux'
|
|
190
|
-
/**
|
|
191
|
-
* Whether the input value comes from `event.key` or `event.code`.
|
|
192
|
-
*
|
|
193
|
-
* - `'key'` (default): Applies rich platform-aware formatting (modifier
|
|
194
|
-
* labels, special-key symbols, etc.).
|
|
195
|
-
* - `'code'`: Returns the value unchanged — physical key codes like
|
|
196
|
-
* `"MetaLeft"` or `"KeyA"` are already descriptive for debugging.
|
|
197
|
-
*/
|
|
198
|
-
source?: 'key' | 'code'
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Formats a single key name for debugging/devtools display.
|
|
203
|
-
*
|
|
204
|
-
* Unlike `formatForDisplay` which formats full hotkey strings for end-user UIs,
|
|
205
|
-
* this function formats individual key names (from `event.key`) with rich
|
|
206
|
-
* platform-aware labels suitable for debugging tools and developer-facing displays.
|
|
207
|
-
*
|
|
208
|
-
* Features:
|
|
209
|
-
* - Modifier keys show their platform role (e.g., "Mod (Cmd)" for Meta on Mac)
|
|
210
|
-
* - On macOS, modifier keys are prefixed with their symbol (e.g., "⌘ Mod (Cmd)")
|
|
211
|
-
* - Special keys use display symbols (ArrowUp -> "↑", Escape -> "Esc")
|
|
212
|
-
* - Regular keys pass through unchanged
|
|
213
|
-
*
|
|
214
|
-
* @param key - A single key name (e.g., "Meta", "Shift", "ArrowUp", "A")
|
|
215
|
-
* @param options - Formatting options
|
|
216
|
-
* @returns A formatted label suitable for debugging display
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```ts
|
|
220
|
-
* // On macOS:
|
|
221
|
-
* formatKeyForDebuggingDisplay('Meta') // '⌘ Mod (Cmd)'
|
|
222
|
-
* formatKeyForDebuggingDisplay('Control') // '⌃ Ctrl'
|
|
223
|
-
* formatKeyForDebuggingDisplay('Alt') // '⌥ Opt'
|
|
224
|
-
* formatKeyForDebuggingDisplay('Shift') // '⇧ Shift'
|
|
225
|
-
*
|
|
226
|
-
* // On Windows:
|
|
227
|
-
* formatKeyForDebuggingDisplay('Control') // 'Mod (Ctrl)'
|
|
228
|
-
* formatKeyForDebuggingDisplay('Meta') // 'Win'
|
|
229
|
-
*
|
|
230
|
-
* // Special keys (all platforms):
|
|
231
|
-
* formatKeyForDebuggingDisplay('ArrowUp') // '↑'
|
|
232
|
-
* formatKeyForDebuggingDisplay('Escape') // 'Esc'
|
|
233
|
-
* formatKeyForDebuggingDisplay('Space') // '␣'
|
|
234
|
-
*
|
|
235
|
-
* // Regular keys pass through:
|
|
236
|
-
* formatKeyForDebuggingDisplay('A') // 'A'
|
|
237
|
-
*
|
|
238
|
-
* // With source: 'code', values pass through unchanged:
|
|
239
|
-
* formatKeyForDebuggingDisplay('MetaLeft', { source: 'code' }) // 'MetaLeft'
|
|
240
|
-
* formatKeyForDebuggingDisplay('KeyA', { source: 'code' }) // 'KeyA'
|
|
241
|
-
* ```
|
|
242
|
-
*/
|
|
243
|
-
export function formatKeyForDebuggingDisplay(
|
|
244
|
-
key: string,
|
|
245
|
-
options: FormatKeyDebuggingOptions = {},
|
|
135
|
+
hotkey: RegisterableHotkey,
|
|
136
|
+
options: Omit<FormatDisplayOptions, 'useSymbols'> = {},
|
|
246
137
|
): string {
|
|
247
|
-
|
|
248
|
-
// descriptive for debugging (e.g. "MetaLeft", "KeyA", "ShiftRight").
|
|
249
|
-
if (options.source === 'code') {
|
|
250
|
-
return key
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const platform = options.platform ?? detectPlatform()
|
|
254
|
-
|
|
255
|
-
// Check if it's a modifier key
|
|
256
|
-
const modLabel = MODIFIER_DEBUG_LABELS[platform]?.[key]
|
|
257
|
-
if (modLabel) {
|
|
258
|
-
// On Mac, prefix modifier labels with their symbol
|
|
259
|
-
if (platform === 'mac') {
|
|
260
|
-
const symbol =
|
|
261
|
-
MAC_MODIFIER_SYMBOLS[key as keyof typeof MAC_MODIFIER_SYMBOLS]
|
|
262
|
-
if (symbol) {
|
|
263
|
-
return `${symbol} ${modLabel}`
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return modLabel
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Check if it's a special key with a display symbol
|
|
270
|
-
const symbol = KEY_DISPLAY_SYMBOLS[key]
|
|
271
|
-
if (symbol) {
|
|
272
|
-
return symbol
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Regular key — pass through
|
|
276
|
-
return key
|
|
138
|
+
return formatForDisplay(hotkey, { ...options, useSymbols: false })
|
|
277
139
|
}
|
package/src/hotkey-manager.ts
CHANGED
|
@@ -27,7 +27,11 @@ export type { ConflictBehavior }
|
|
|
27
27
|
export interface HotkeyOptions {
|
|
28
28
|
/** Behavior when this hotkey conflicts with an existing registration on the same target. Defaults to 'warn' */
|
|
29
29
|
conflictBehavior?: ConflictBehavior
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Soft-disable: when `false`, the callback does not run but the registration
|
|
32
|
+
* stays in `HotkeyManager` (and in devtools). Toggling this should update the
|
|
33
|
+
* existing handle via `setOptions` rather than unregistering. Defaults to `true`.
|
|
34
|
+
*/
|
|
31
35
|
enabled?: boolean
|
|
32
36
|
/** The event type to listen for. Defaults to 'keydown' */
|
|
33
37
|
eventType?: 'keydown' | 'keyup'
|
package/src/hotkey.ts
CHANGED
|
@@ -368,6 +368,8 @@ export type RegisterableHotkey = Hotkey | RawHotkey
|
|
|
368
368
|
export interface FormatDisplayOptions {
|
|
369
369
|
/** The target platform. Defaults to auto-detection. */
|
|
370
370
|
platform?: 'mac' | 'windows' | 'linux'
|
|
371
|
+
/** Whether to use symbols for the display. Defaults to true. */
|
|
372
|
+
useSymbols?: boolean
|
|
371
373
|
}
|
|
372
374
|
|
|
373
375
|
/**
|