@tanstack/hotkeys 0.0.1 → 0.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/LICENSE +21 -0
- package/README.md +121 -45
- package/dist/constants.cjs +444 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +226 -0
- package/dist/constants.d.ts +226 -0
- package/dist/constants.js +428 -0
- package/dist/constants.js.map +1 -0
- package/dist/format.cjs +178 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +110 -0
- package/dist/format.d.ts +110 -0
- package/dist/format.js +175 -0
- package/dist/format.js.map +1 -0
- package/dist/hotkey-manager.cjs +420 -0
- package/dist/hotkey-manager.cjs.map +1 -0
- package/dist/hotkey-manager.d.cts +207 -0
- package/dist/hotkey-manager.d.ts +207 -0
- package/dist/hotkey-manager.js +419 -0
- package/dist/hotkey-manager.js.map +1 -0
- package/dist/hotkey.d.cts +278 -0
- package/dist/hotkey.d.ts +278 -0
- package/dist/index.cjs +54 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/key-state-tracker.cjs +197 -0
- package/dist/key-state-tracker.cjs.map +1 -0
- package/dist/key-state-tracker.d.cts +107 -0
- package/dist/key-state-tracker.d.ts +107 -0
- package/dist/key-state-tracker.js +196 -0
- package/dist/key-state-tracker.js.map +1 -0
- package/dist/match.cjs +143 -0
- package/dist/match.cjs.map +1 -0
- package/dist/match.d.cts +79 -0
- package/dist/match.d.ts +79 -0
- package/dist/match.js +141 -0
- package/dist/match.js.map +1 -0
- package/dist/parse.cjs +266 -0
- package/dist/parse.cjs.map +1 -0
- package/dist/parse.d.cts +169 -0
- package/dist/parse.d.ts +169 -0
- package/dist/parse.js +258 -0
- package/dist/parse.js.map +1 -0
- package/dist/recorder.cjs +177 -0
- package/dist/recorder.cjs.map +1 -0
- package/dist/recorder.d.cts +108 -0
- package/dist/recorder.d.ts +108 -0
- package/dist/recorder.js +177 -0
- package/dist/recorder.js.map +1 -0
- package/dist/sequence.cjs +242 -0
- package/dist/sequence.cjs.map +1 -0
- package/dist/sequence.d.cts +109 -0
- package/dist/sequence.d.ts +109 -0
- package/dist/sequence.js +240 -0
- package/dist/sequence.js.map +1 -0
- package/dist/validate.cjs +116 -0
- package/dist/validate.cjs.map +1 -0
- package/dist/validate.d.cts +56 -0
- package/dist/validate.d.ts +56 -0
- package/dist/validate.js +114 -0
- package/dist/validate.js.map +1 -0
- package/package.json +55 -7
- package/src/constants.ts +514 -0
- package/src/format.ts +261 -0
- package/src/hotkey-manager.ts +822 -0
- package/src/hotkey.ts +411 -0
- package/src/index.ts +10 -0
- package/src/key-state-tracker.ts +249 -0
- package/src/match.ts +222 -0
- package/src/parse.ts +368 -0
- package/src/recorder.ts +266 -0
- package/src/sequence.ts +391 -0
- package/src/validate.ts +171 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { FormatDisplayOptions, Hotkey, ParsedHotkey } from "./hotkey.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/format.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Converts a ParsedHotkey back to a hotkey string.
|
|
6
|
+
*
|
|
7
|
+
* @param parsed - The parsed hotkey object
|
|
8
|
+
* @returns A hotkey string in canonical form
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* formatHotkey({ key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] })
|
|
13
|
+
* // Returns: 'Control+Shift+S'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare function formatHotkey(parsed: ParsedHotkey): string;
|
|
17
|
+
/**
|
|
18
|
+
* Formats a hotkey for display in a user interface.
|
|
19
|
+
*
|
|
20
|
+
* On macOS, uses symbols (⌘⇧S).
|
|
21
|
+
* On Windows/Linux, uses text (Ctrl+Shift+S).
|
|
22
|
+
*
|
|
23
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
24
|
+
* @param options - Formatting options
|
|
25
|
+
* @returns A formatted string suitable for display
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'mac' })
|
|
30
|
+
* // Returns: '⇧⌘S'
|
|
31
|
+
*
|
|
32
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'windows' })
|
|
33
|
+
* // Returns: 'Ctrl+Shift+S'
|
|
34
|
+
*
|
|
35
|
+
* formatForDisplay('Escape')
|
|
36
|
+
* // Returns: 'Esc' (on all platforms)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function formatForDisplay(hotkey: Hotkey | (string & {}) | ParsedHotkey, options?: FormatDisplayOptions): string;
|
|
40
|
+
/**
|
|
41
|
+
* Formats a hotkey using platform-agnostic labels.
|
|
42
|
+
* Uses 'Cmd' on Mac and 'Ctrl' for Control, etc.
|
|
43
|
+
*
|
|
44
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
45
|
+
* @param platform - The target platform
|
|
46
|
+
* @returns A formatted string with platform-appropriate labels
|
|
47
|
+
*/
|
|
48
|
+
declare function formatWithLabels(hotkey: Hotkey | (string & {}), platform?: 'mac' | 'windows' | 'linux'): string;
|
|
49
|
+
/**
|
|
50
|
+
* Options for formatting a single key for debugging display.
|
|
51
|
+
*/
|
|
52
|
+
interface FormatKeyDebuggingOptions {
|
|
53
|
+
/** The target platform. Defaults to auto-detection. */
|
|
54
|
+
platform?: 'mac' | 'windows' | 'linux';
|
|
55
|
+
/**
|
|
56
|
+
* Whether the input value comes from `event.key` or `event.code`.
|
|
57
|
+
*
|
|
58
|
+
* - `'key'` (default): Applies rich platform-aware formatting (modifier
|
|
59
|
+
* labels, special-key symbols, etc.).
|
|
60
|
+
* - `'code'`: Returns the value unchanged — physical key codes like
|
|
61
|
+
* `"MetaLeft"` or `"KeyA"` are already descriptive for debugging.
|
|
62
|
+
*/
|
|
63
|
+
source?: 'key' | 'code';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Formats a single key name for debugging/devtools display.
|
|
67
|
+
*
|
|
68
|
+
* Unlike `formatForDisplay` which formats full hotkey strings for end-user UIs,
|
|
69
|
+
* this function formats individual key names (from `event.key`) with rich
|
|
70
|
+
* platform-aware labels suitable for debugging tools and developer-facing displays.
|
|
71
|
+
*
|
|
72
|
+
* Features:
|
|
73
|
+
* - Modifier keys show their platform role (e.g., "Mod (Cmd)" for Meta on Mac)
|
|
74
|
+
* - On macOS, modifier keys are prefixed with their symbol (e.g., "⌘ Mod (Cmd)")
|
|
75
|
+
* - Special keys use display symbols (ArrowUp -> "↑", Escape -> "Esc")
|
|
76
|
+
* - Regular keys pass through unchanged
|
|
77
|
+
*
|
|
78
|
+
* @param key - A single key name (e.g., "Meta", "Shift", "ArrowUp", "A")
|
|
79
|
+
* @param options - Formatting options
|
|
80
|
+
* @returns A formatted label suitable for debugging display
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* // On macOS:
|
|
85
|
+
* formatKeyForDebuggingDisplay('Meta') // '⌘ Mod (Cmd)'
|
|
86
|
+
* formatKeyForDebuggingDisplay('Control') // '⌃ Ctrl'
|
|
87
|
+
* formatKeyForDebuggingDisplay('Alt') // '⌥ Opt'
|
|
88
|
+
* formatKeyForDebuggingDisplay('Shift') // '⇧ Shift'
|
|
89
|
+
*
|
|
90
|
+
* // On Windows:
|
|
91
|
+
* formatKeyForDebuggingDisplay('Control') // 'Mod (Ctrl)'
|
|
92
|
+
* formatKeyForDebuggingDisplay('Meta') // 'Win'
|
|
93
|
+
*
|
|
94
|
+
* // Special keys (all platforms):
|
|
95
|
+
* formatKeyForDebuggingDisplay('ArrowUp') // '↑'
|
|
96
|
+
* formatKeyForDebuggingDisplay('Escape') // 'Esc'
|
|
97
|
+
* formatKeyForDebuggingDisplay('Space') // '␣'
|
|
98
|
+
*
|
|
99
|
+
* // Regular keys pass through:
|
|
100
|
+
* formatKeyForDebuggingDisplay('A') // 'A'
|
|
101
|
+
*
|
|
102
|
+
* // With source: 'code', values pass through unchanged:
|
|
103
|
+
* formatKeyForDebuggingDisplay('MetaLeft', { source: 'code' }) // 'MetaLeft'
|
|
104
|
+
* formatKeyForDebuggingDisplay('KeyA', { source: 'code' }) // 'KeyA'
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
declare function formatKeyForDebuggingDisplay(key: string, options?: FormatKeyDebuggingOptions): string;
|
|
108
|
+
//#endregion
|
|
109
|
+
export { FormatKeyDebuggingOptions, formatForDisplay, formatHotkey, formatKeyForDebuggingDisplay, formatWithLabels };
|
|
110
|
+
//# sourceMappingURL=format.d.cts.map
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { FormatDisplayOptions, Hotkey, ParsedHotkey } from "./hotkey.js";
|
|
2
|
+
|
|
3
|
+
//#region src/format.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Converts a ParsedHotkey back to a hotkey string.
|
|
6
|
+
*
|
|
7
|
+
* @param parsed - The parsed hotkey object
|
|
8
|
+
* @returns A hotkey string in canonical form
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* formatHotkey({ key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] })
|
|
13
|
+
* // Returns: 'Control+Shift+S'
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare function formatHotkey(parsed: ParsedHotkey): string;
|
|
17
|
+
/**
|
|
18
|
+
* Formats a hotkey for display in a user interface.
|
|
19
|
+
*
|
|
20
|
+
* On macOS, uses symbols (⌘⇧S).
|
|
21
|
+
* On Windows/Linux, uses text (Ctrl+Shift+S).
|
|
22
|
+
*
|
|
23
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
24
|
+
* @param options - Formatting options
|
|
25
|
+
* @returns A formatted string suitable for display
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'mac' })
|
|
30
|
+
* // Returns: '⇧⌘S'
|
|
31
|
+
*
|
|
32
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'windows' })
|
|
33
|
+
* // Returns: 'Ctrl+Shift+S'
|
|
34
|
+
*
|
|
35
|
+
* formatForDisplay('Escape')
|
|
36
|
+
* // Returns: 'Esc' (on all platforms)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare function formatForDisplay(hotkey: Hotkey | (string & {}) | ParsedHotkey, options?: FormatDisplayOptions): string;
|
|
40
|
+
/**
|
|
41
|
+
* Formats a hotkey using platform-agnostic labels.
|
|
42
|
+
* Uses 'Cmd' on Mac and 'Ctrl' for Control, etc.
|
|
43
|
+
*
|
|
44
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
45
|
+
* @param platform - The target platform
|
|
46
|
+
* @returns A formatted string with platform-appropriate labels
|
|
47
|
+
*/
|
|
48
|
+
declare function formatWithLabels(hotkey: Hotkey | (string & {}), platform?: 'mac' | 'windows' | 'linux'): string;
|
|
49
|
+
/**
|
|
50
|
+
* Options for formatting a single key for debugging display.
|
|
51
|
+
*/
|
|
52
|
+
interface FormatKeyDebuggingOptions {
|
|
53
|
+
/** The target platform. Defaults to auto-detection. */
|
|
54
|
+
platform?: 'mac' | 'windows' | 'linux';
|
|
55
|
+
/**
|
|
56
|
+
* Whether the input value comes from `event.key` or `event.code`.
|
|
57
|
+
*
|
|
58
|
+
* - `'key'` (default): Applies rich platform-aware formatting (modifier
|
|
59
|
+
* labels, special-key symbols, etc.).
|
|
60
|
+
* - `'code'`: Returns the value unchanged — physical key codes like
|
|
61
|
+
* `"MetaLeft"` or `"KeyA"` are already descriptive for debugging.
|
|
62
|
+
*/
|
|
63
|
+
source?: 'key' | 'code';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Formats a single key name for debugging/devtools display.
|
|
67
|
+
*
|
|
68
|
+
* Unlike `formatForDisplay` which formats full hotkey strings for end-user UIs,
|
|
69
|
+
* this function formats individual key names (from `event.key`) with rich
|
|
70
|
+
* platform-aware labels suitable for debugging tools and developer-facing displays.
|
|
71
|
+
*
|
|
72
|
+
* Features:
|
|
73
|
+
* - Modifier keys show their platform role (e.g., "Mod (Cmd)" for Meta on Mac)
|
|
74
|
+
* - On macOS, modifier keys are prefixed with their symbol (e.g., "⌘ Mod (Cmd)")
|
|
75
|
+
* - Special keys use display symbols (ArrowUp -> "↑", Escape -> "Esc")
|
|
76
|
+
* - Regular keys pass through unchanged
|
|
77
|
+
*
|
|
78
|
+
* @param key - A single key name (e.g., "Meta", "Shift", "ArrowUp", "A")
|
|
79
|
+
* @param options - Formatting options
|
|
80
|
+
* @returns A formatted label suitable for debugging display
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* // On macOS:
|
|
85
|
+
* formatKeyForDebuggingDisplay('Meta') // '⌘ Mod (Cmd)'
|
|
86
|
+
* formatKeyForDebuggingDisplay('Control') // '⌃ Ctrl'
|
|
87
|
+
* formatKeyForDebuggingDisplay('Alt') // '⌥ Opt'
|
|
88
|
+
* formatKeyForDebuggingDisplay('Shift') // '⇧ Shift'
|
|
89
|
+
*
|
|
90
|
+
* // On Windows:
|
|
91
|
+
* formatKeyForDebuggingDisplay('Control') // 'Mod (Ctrl)'
|
|
92
|
+
* formatKeyForDebuggingDisplay('Meta') // 'Win'
|
|
93
|
+
*
|
|
94
|
+
* // Special keys (all platforms):
|
|
95
|
+
* formatKeyForDebuggingDisplay('ArrowUp') // '↑'
|
|
96
|
+
* formatKeyForDebuggingDisplay('Escape') // 'Esc'
|
|
97
|
+
* formatKeyForDebuggingDisplay('Space') // '␣'
|
|
98
|
+
*
|
|
99
|
+
* // Regular keys pass through:
|
|
100
|
+
* formatKeyForDebuggingDisplay('A') // 'A'
|
|
101
|
+
*
|
|
102
|
+
* // With source: 'code', values pass through unchanged:
|
|
103
|
+
* formatKeyForDebuggingDisplay('MetaLeft', { source: 'code' }) // 'MetaLeft'
|
|
104
|
+
* formatKeyForDebuggingDisplay('KeyA', { source: 'code' }) // 'KeyA'
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
declare function formatKeyForDebuggingDisplay(key: string, options?: FormatKeyDebuggingOptions): string;
|
|
108
|
+
//#endregion
|
|
109
|
+
export { FormatKeyDebuggingOptions, formatForDisplay, formatHotkey, formatKeyForDebuggingDisplay, formatWithLabels };
|
|
110
|
+
//# sourceMappingURL=format.d.ts.map
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { KEY_DISPLAY_SYMBOLS, MAC_MODIFIER_SYMBOLS, MODIFIER_ORDER, STANDARD_MODIFIER_LABELS, detectPlatform } from "./constants.js";
|
|
2
|
+
import { parseHotkey } from "./parse.js";
|
|
3
|
+
|
|
4
|
+
//#region src/format.ts
|
|
5
|
+
/**
|
|
6
|
+
* Converts a ParsedHotkey back to a hotkey string.
|
|
7
|
+
*
|
|
8
|
+
* @param parsed - The parsed hotkey object
|
|
9
|
+
* @returns A hotkey string in canonical form
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* formatHotkey({ key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] })
|
|
14
|
+
* // Returns: 'Control+Shift+S'
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function formatHotkey(parsed) {
|
|
18
|
+
const parts = [];
|
|
19
|
+
for (const modifier of MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(modifier);
|
|
20
|
+
parts.push(parsed.key);
|
|
21
|
+
return parts.join("+");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Formats a hotkey for display in a user interface.
|
|
25
|
+
*
|
|
26
|
+
* On macOS, uses symbols (⌘⇧S).
|
|
27
|
+
* On Windows/Linux, uses text (Ctrl+Shift+S).
|
|
28
|
+
*
|
|
29
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
30
|
+
* @param options - Formatting options
|
|
31
|
+
* @returns A formatted string suitable for display
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'mac' })
|
|
36
|
+
* // Returns: '⇧⌘S'
|
|
37
|
+
*
|
|
38
|
+
* formatForDisplay('Mod+Shift+S', { platform: 'windows' })
|
|
39
|
+
* // Returns: 'Ctrl+Shift+S'
|
|
40
|
+
*
|
|
41
|
+
* formatForDisplay('Escape')
|
|
42
|
+
* // Returns: 'Esc' (on all platforms)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function formatForDisplay(hotkey, options = {}) {
|
|
46
|
+
const platform = options.platform ?? detectPlatform();
|
|
47
|
+
const parsed = typeof hotkey === "string" ? parseHotkey(hotkey, platform) : hotkey;
|
|
48
|
+
if (platform === "mac") return formatForMac(parsed);
|
|
49
|
+
return formatForStandard(parsed);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Formats a hotkey for macOS display using symbols.
|
|
53
|
+
*/
|
|
54
|
+
function formatForMac(parsed) {
|
|
55
|
+
const parts = [];
|
|
56
|
+
for (const modifier of MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(MAC_MODIFIER_SYMBOLS[modifier]);
|
|
57
|
+
const keyDisplay = KEY_DISPLAY_SYMBOLS[parsed.key] ?? parsed.key;
|
|
58
|
+
parts.push(keyDisplay);
|
|
59
|
+
return parts.join("");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Formats a hotkey for Windows/Linux display using text labels.
|
|
63
|
+
*/
|
|
64
|
+
function formatForStandard(parsed) {
|
|
65
|
+
const parts = [];
|
|
66
|
+
for (const modifier of MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(STANDARD_MODIFIER_LABELS[modifier]);
|
|
67
|
+
const keyDisplay = KEY_DISPLAY_SYMBOLS[parsed.key] ?? parsed.key;
|
|
68
|
+
parts.push(keyDisplay);
|
|
69
|
+
return parts.join("+");
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Formats a hotkey using platform-agnostic labels.
|
|
73
|
+
* Uses 'Cmd' on Mac and 'Ctrl' for Control, etc.
|
|
74
|
+
*
|
|
75
|
+
* @param hotkey - The hotkey string or ParsedHotkey to format
|
|
76
|
+
* @param platform - The target platform
|
|
77
|
+
* @returns A formatted string with platform-appropriate labels
|
|
78
|
+
*/
|
|
79
|
+
function formatWithLabels(hotkey, platform = detectPlatform()) {
|
|
80
|
+
const parsed = typeof hotkey === "string" ? parseHotkey(hotkey, platform) : hotkey;
|
|
81
|
+
const parts = [];
|
|
82
|
+
const labels = {
|
|
83
|
+
Control: "Ctrl",
|
|
84
|
+
Alt: platform === "mac" ? "Option" : "Alt",
|
|
85
|
+
Shift: "Shift",
|
|
86
|
+
Meta: platform === "mac" ? "Cmd" : "Win"
|
|
87
|
+
};
|
|
88
|
+
for (const modifier of MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(labels[modifier] ?? modifier);
|
|
89
|
+
parts.push(parsed.key);
|
|
90
|
+
return parts.join("+");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Maps canonical modifier names to debugging-friendly labels per platform.
|
|
94
|
+
*/
|
|
95
|
+
const MODIFIER_DEBUG_LABELS = {
|
|
96
|
+
mac: {
|
|
97
|
+
Meta: "Mod (Cmd)",
|
|
98
|
+
Control: "Ctrl",
|
|
99
|
+
Alt: "Opt",
|
|
100
|
+
Shift: "Shift"
|
|
101
|
+
},
|
|
102
|
+
windows: {
|
|
103
|
+
Control: "Mod (Ctrl)",
|
|
104
|
+
Meta: "Win",
|
|
105
|
+
Alt: "Alt",
|
|
106
|
+
Shift: "Shift"
|
|
107
|
+
},
|
|
108
|
+
linux: {
|
|
109
|
+
Control: "Mod (Ctrl)",
|
|
110
|
+
Meta: "Super",
|
|
111
|
+
Alt: "Alt",
|
|
112
|
+
Shift: "Shift"
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Formats a single key name for debugging/devtools display.
|
|
117
|
+
*
|
|
118
|
+
* Unlike `formatForDisplay` which formats full hotkey strings for end-user UIs,
|
|
119
|
+
* this function formats individual key names (from `event.key`) with rich
|
|
120
|
+
* platform-aware labels suitable for debugging tools and developer-facing displays.
|
|
121
|
+
*
|
|
122
|
+
* Features:
|
|
123
|
+
* - Modifier keys show their platform role (e.g., "Mod (Cmd)" for Meta on Mac)
|
|
124
|
+
* - On macOS, modifier keys are prefixed with their symbol (e.g., "⌘ Mod (Cmd)")
|
|
125
|
+
* - Special keys use display symbols (ArrowUp -> "↑", Escape -> "Esc")
|
|
126
|
+
* - Regular keys pass through unchanged
|
|
127
|
+
*
|
|
128
|
+
* @param key - A single key name (e.g., "Meta", "Shift", "ArrowUp", "A")
|
|
129
|
+
* @param options - Formatting options
|
|
130
|
+
* @returns A formatted label suitable for debugging display
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* // On macOS:
|
|
135
|
+
* formatKeyForDebuggingDisplay('Meta') // '⌘ Mod (Cmd)'
|
|
136
|
+
* formatKeyForDebuggingDisplay('Control') // '⌃ Ctrl'
|
|
137
|
+
* formatKeyForDebuggingDisplay('Alt') // '⌥ Opt'
|
|
138
|
+
* formatKeyForDebuggingDisplay('Shift') // '⇧ Shift'
|
|
139
|
+
*
|
|
140
|
+
* // On Windows:
|
|
141
|
+
* formatKeyForDebuggingDisplay('Control') // 'Mod (Ctrl)'
|
|
142
|
+
* formatKeyForDebuggingDisplay('Meta') // 'Win'
|
|
143
|
+
*
|
|
144
|
+
* // Special keys (all platforms):
|
|
145
|
+
* formatKeyForDebuggingDisplay('ArrowUp') // '↑'
|
|
146
|
+
* formatKeyForDebuggingDisplay('Escape') // 'Esc'
|
|
147
|
+
* formatKeyForDebuggingDisplay('Space') // '␣'
|
|
148
|
+
*
|
|
149
|
+
* // Regular keys pass through:
|
|
150
|
+
* formatKeyForDebuggingDisplay('A') // 'A'
|
|
151
|
+
*
|
|
152
|
+
* // With source: 'code', values pass through unchanged:
|
|
153
|
+
* formatKeyForDebuggingDisplay('MetaLeft', { source: 'code' }) // 'MetaLeft'
|
|
154
|
+
* formatKeyForDebuggingDisplay('KeyA', { source: 'code' }) // 'KeyA'
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
function formatKeyForDebuggingDisplay(key, options = {}) {
|
|
158
|
+
if (options.source === "code") return key;
|
|
159
|
+
const platform = options.platform ?? detectPlatform();
|
|
160
|
+
const modLabel = MODIFIER_DEBUG_LABELS[platform]?.[key];
|
|
161
|
+
if (modLabel) {
|
|
162
|
+
if (platform === "mac") {
|
|
163
|
+
const symbol = MAC_MODIFIER_SYMBOLS[key];
|
|
164
|
+
if (symbol) return `${symbol} ${modLabel}`;
|
|
165
|
+
}
|
|
166
|
+
return modLabel;
|
|
167
|
+
}
|
|
168
|
+
const symbol = KEY_DISPLAY_SYMBOLS[key];
|
|
169
|
+
if (symbol) return symbol;
|
|
170
|
+
return key;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
export { formatForDisplay, formatHotkey, formatKeyForDebuggingDisplay, formatWithLabels };
|
|
175
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","names":[],"sources":["../src/format.ts"],"sourcesContent":["import {\n KEY_DISPLAY_SYMBOLS,\n MAC_MODIFIER_SYMBOLS,\n MODIFIER_ORDER,\n STANDARD_MODIFIER_LABELS,\n detectPlatform,\n} from './constants'\nimport { parseHotkey } from './parse'\nimport type { FormatDisplayOptions, Hotkey, ParsedHotkey } from './hotkey'\n\n/**\n * Converts a ParsedHotkey back to a hotkey string.\n *\n * @param parsed - The parsed hotkey object\n * @returns A hotkey string in canonical form\n *\n * @example\n * ```ts\n * formatHotkey({ key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] })\n * // Returns: 'Control+Shift+S'\n * ```\n */\nexport function formatHotkey(parsed: ParsedHotkey): string {\n const parts: Array<string> = []\n\n // Add modifiers in canonical order\n for (const modifier of MODIFIER_ORDER) {\n if (parsed.modifiers.includes(modifier)) {\n parts.push(modifier)\n }\n }\n\n // Add the key\n parts.push(parsed.key)\n\n return parts.join('+')\n}\n\n/**\n * Formats a hotkey for display in a user interface.\n *\n * On macOS, uses symbols (⌘⇧S).\n * On Windows/Linux, uses text (Ctrl+Shift+S).\n *\n * @param hotkey - The hotkey string or ParsedHotkey to format\n * @param options - Formatting options\n * @returns A formatted string suitable for display\n *\n * @example\n * ```ts\n * formatForDisplay('Mod+Shift+S', { platform: 'mac' })\n * // Returns: '⇧⌘S'\n *\n * formatForDisplay('Mod+Shift+S', { platform: 'windows' })\n * // Returns: 'Ctrl+Shift+S'\n *\n * formatForDisplay('Escape')\n * // Returns: 'Esc' (on all platforms)\n * ```\n */\nexport function formatForDisplay(\n hotkey: Hotkey | (string & {}) | ParsedHotkey,\n options: FormatDisplayOptions = {},\n): string {\n const platform = options.platform ?? detectPlatform()\n const parsed =\n typeof hotkey === 'string' ? parseHotkey(hotkey, platform) : hotkey\n\n if (platform === 'mac') {\n return formatForMac(parsed)\n }\n\n return formatForStandard(parsed)\n}\n\n/**\n * Formats a hotkey for macOS display using symbols.\n */\nfunction formatForMac(parsed: ParsedHotkey): string {\n const parts: Array<string> = []\n\n // Add modifiers in macOS order (typically Control, Option, Shift, Command)\n // But we'll use our canonical order and just use symbols\n for (const modifier of MODIFIER_ORDER) {\n if (parsed.modifiers.includes(modifier)) {\n parts.push(MAC_MODIFIER_SYMBOLS[modifier])\n }\n }\n\n // Add the key (use symbol if available, otherwise the key itself)\n const keyDisplay = KEY_DISPLAY_SYMBOLS[parsed.key] ?? parsed.key\n parts.push(keyDisplay)\n\n // On Mac, modifiers are typically concatenated without separators\n return parts.join('')\n}\n\n/**\n * Formats a hotkey for Windows/Linux display using text labels.\n */\nfunction formatForStandard(parsed: ParsedHotkey): string {\n const parts: Array<string> = []\n\n // Add modifiers in canonical order\n for (const modifier of MODIFIER_ORDER) {\n if (parsed.modifiers.includes(modifier)) {\n parts.push(STANDARD_MODIFIER_LABELS[modifier])\n }\n }\n\n // Add the key (use symbol/short form if available)\n const keyDisplay = KEY_DISPLAY_SYMBOLS[parsed.key] ?? parsed.key\n parts.push(keyDisplay)\n\n // On Windows/Linux, use + as separator\n return parts.join('+')\n}\n\n/**\n * Formats a hotkey using platform-agnostic labels.\n * Uses 'Cmd' on Mac and 'Ctrl' for Control, etc.\n *\n * @param hotkey - The hotkey string or ParsedHotkey to format\n * @param platform - The target platform\n * @returns A formatted string with platform-appropriate labels\n */\nexport function formatWithLabels(\n hotkey: Hotkey | (string & {}),\n platform: 'mac' | 'windows' | 'linux' = detectPlatform(),\n): string {\n const parsed =\n typeof hotkey === 'string' ? parseHotkey(hotkey, platform) : hotkey\n const parts: Array<string> = []\n\n // Custom labels for more readable output\n const labels: Record<string, string> = {\n Control: 'Ctrl',\n Alt: platform === 'mac' ? 'Option' : 'Alt',\n Shift: 'Shift',\n Meta: platform === 'mac' ? 'Cmd' : 'Win',\n }\n\n for (const modifier of MODIFIER_ORDER) {\n if (parsed.modifiers.includes(modifier)) {\n parts.push(labels[modifier] ?? modifier)\n }\n }\n\n // Add the key\n parts.push(parsed.key)\n\n return parts.join('+')\n}\n\n// =============================================================================\n// Debugging Display Labels\n// =============================================================================\n\n/**\n * Maps canonical modifier names to debugging-friendly labels per platform.\n */\nconst MODIFIER_DEBUG_LABELS: Record<string, Record<string, string>> = {\n mac: { Meta: 'Mod (Cmd)', Control: 'Ctrl', Alt: 'Opt', Shift: 'Shift' },\n windows: { Control: 'Mod (Ctrl)', Meta: 'Win', Alt: 'Alt', Shift: 'Shift' },\n linux: { Control: 'Mod (Ctrl)', Meta: 'Super', Alt: 'Alt', Shift: 'Shift' },\n}\n\n/**\n * Options for formatting a single key for debugging display.\n */\nexport interface FormatKeyDebuggingOptions {\n /** The target platform. Defaults to auto-detection. */\n platform?: 'mac' | 'windows' | 'linux'\n /**\n * Whether the input value comes from `event.key` or `event.code`.\n *\n * - `'key'` (default): Applies rich platform-aware formatting (modifier\n * labels, special-key symbols, etc.).\n * - `'code'`: Returns the value unchanged — physical key codes like\n * `\"MetaLeft\"` or `\"KeyA\"` are already descriptive for debugging.\n */\n source?: 'key' | 'code'\n}\n\n/**\n * Formats a single key name for debugging/devtools display.\n *\n * Unlike `formatForDisplay` which formats full hotkey strings for end-user UIs,\n * this function formats individual key names (from `event.key`) with rich\n * platform-aware labels suitable for debugging tools and developer-facing displays.\n *\n * Features:\n * - Modifier keys show their platform role (e.g., \"Mod (Cmd)\" for Meta on Mac)\n * - On macOS, modifier keys are prefixed with their symbol (e.g., \"⌘ Mod (Cmd)\")\n * - Special keys use display symbols (ArrowUp -> \"↑\", Escape -> \"Esc\")\n * - Regular keys pass through unchanged\n *\n * @param key - A single key name (e.g., \"Meta\", \"Shift\", \"ArrowUp\", \"A\")\n * @param options - Formatting options\n * @returns A formatted label suitable for debugging display\n *\n * @example\n * ```ts\n * // On macOS:\n * formatKeyForDebuggingDisplay('Meta') // '⌘ Mod (Cmd)'\n * formatKeyForDebuggingDisplay('Control') // '⌃ Ctrl'\n * formatKeyForDebuggingDisplay('Alt') // '⌥ Opt'\n * formatKeyForDebuggingDisplay('Shift') // '⇧ Shift'\n *\n * // On Windows:\n * formatKeyForDebuggingDisplay('Control') // 'Mod (Ctrl)'\n * formatKeyForDebuggingDisplay('Meta') // 'Win'\n *\n * // Special keys (all platforms):\n * formatKeyForDebuggingDisplay('ArrowUp') // '↑'\n * formatKeyForDebuggingDisplay('Escape') // 'Esc'\n * formatKeyForDebuggingDisplay('Space') // '␣'\n *\n * // Regular keys pass through:\n * formatKeyForDebuggingDisplay('A') // 'A'\n *\n * // With source: 'code', values pass through unchanged:\n * formatKeyForDebuggingDisplay('MetaLeft', { source: 'code' }) // 'MetaLeft'\n * formatKeyForDebuggingDisplay('KeyA', { source: 'code' }) // 'KeyA'\n * ```\n */\nexport function formatKeyForDebuggingDisplay(\n key: string,\n options: FormatKeyDebuggingOptions = {},\n): string {\n // For event.code values, pass through unchanged — they're already\n // descriptive for debugging (e.g. \"MetaLeft\", \"KeyA\", \"ShiftRight\").\n if (options.source === 'code') {\n return key\n }\n\n const platform = options.platform ?? detectPlatform()\n\n // Check if it's a modifier key\n const modLabel = MODIFIER_DEBUG_LABELS[platform]?.[key]\n if (modLabel) {\n // On Mac, prefix modifier labels with their symbol\n if (platform === 'mac') {\n const symbol =\n MAC_MODIFIER_SYMBOLS[key as keyof typeof MAC_MODIFIER_SYMBOLS]\n if (symbol) {\n return `${symbol} ${modLabel}`\n }\n }\n return modLabel\n }\n\n // Check if it's a special key with a display symbol\n const symbol = KEY_DISPLAY_SYMBOLS[key]\n if (symbol) {\n return symbol\n }\n\n // Regular key — pass through\n return key\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,SAAgB,aAAa,QAA8B;CACzD,MAAM,QAAuB,EAAE;AAG/B,MAAK,MAAM,YAAY,eACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,SAAS;AAKxB,OAAM,KAAK,OAAO,IAAI;AAEtB,QAAO,MAAM,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;AAyBxB,SAAgB,iBACd,QACA,UAAgC,EAAE,EAC1B;CACR,MAAM,WAAW,QAAQ,YAAY,gBAAgB;CACrD,MAAM,SACJ,OAAO,WAAW,WAAW,YAAY,QAAQ,SAAS,GAAG;AAE/D,KAAI,aAAa,MACf,QAAO,aAAa,OAAO;AAG7B,QAAO,kBAAkB,OAAO;;;;;AAMlC,SAAS,aAAa,QAA8B;CAClD,MAAM,QAAuB,EAAE;AAI/B,MAAK,MAAM,YAAY,eACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,qBAAqB,UAAU;CAK9C,MAAM,aAAa,oBAAoB,OAAO,QAAQ,OAAO;AAC7D,OAAM,KAAK,WAAW;AAGtB,QAAO,MAAM,KAAK,GAAG;;;;;AAMvB,SAAS,kBAAkB,QAA8B;CACvD,MAAM,QAAuB,EAAE;AAG/B,MAAK,MAAM,YAAY,eACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,yBAAyB,UAAU;CAKlD,MAAM,aAAa,oBAAoB,OAAO,QAAQ,OAAO;AAC7D,OAAM,KAAK,WAAW;AAGtB,QAAO,MAAM,KAAK,IAAI;;;;;;;;;;AAWxB,SAAgB,iBACd,QACA,WAAwC,gBAAgB,EAChD;CACR,MAAM,SACJ,OAAO,WAAW,WAAW,YAAY,QAAQ,SAAS,GAAG;CAC/D,MAAM,QAAuB,EAAE;CAG/B,MAAM,SAAiC;EACrC,SAAS;EACT,KAAK,aAAa,QAAQ,WAAW;EACrC,OAAO;EACP,MAAM,aAAa,QAAQ,QAAQ;EACpC;AAED,MAAK,MAAM,YAAY,eACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,OAAO,aAAa,SAAS;AAK5C,OAAM,KAAK,OAAO,IAAI;AAEtB,QAAO,MAAM,KAAK,IAAI;;;;;AAUxB,MAAM,wBAAgE;CACpE,KAAK;EAAE,MAAM;EAAa,SAAS;EAAQ,KAAK;EAAO,OAAO;EAAS;CACvE,SAAS;EAAE,SAAS;EAAc,MAAM;EAAO,KAAK;EAAO,OAAO;EAAS;CAC3E,OAAO;EAAE,SAAS;EAAc,MAAM;EAAS,KAAK;EAAO,OAAO;EAAS;CAC5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DD,SAAgB,6BACd,KACA,UAAqC,EAAE,EAC/B;AAGR,KAAI,QAAQ,WAAW,OACrB,QAAO;CAGT,MAAM,WAAW,QAAQ,YAAY,gBAAgB;CAGrD,MAAM,WAAW,sBAAsB,YAAY;AACnD,KAAI,UAAU;AAEZ,MAAI,aAAa,OAAO;GACtB,MAAM,SACJ,qBAAqB;AACvB,OAAI,OACF,QAAO,GAAG,OAAO,GAAG;;AAGxB,SAAO;;CAIT,MAAM,SAAS,oBAAoB;AACnC,KAAI,OACF,QAAO;AAIT,QAAO"}
|