@tanstack/hotkeys 0.7.1 → 0.9.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.
Files changed (158) hide show
  1. package/README.md +15 -1
  2. package/dist/{manager.utils.js → _event-target.cjs} +5 -41
  3. package/dist/_event-target.cjs.map +1 -0
  4. package/dist/{manager.utils.cjs → _event-target.js} +3 -47
  5. package/dist/_event-target.js.map +1 -0
  6. package/dist/_keyboard-event.cjs +83 -0
  7. package/dist/_keyboard-event.cjs.map +1 -0
  8. package/dist/_keyboard-event.js +76 -0
  9. package/dist/_keyboard-event.js.map +1 -0
  10. package/dist/_match.cjs +49 -0
  11. package/dist/_match.cjs.map +1 -0
  12. package/dist/_match.js +49 -0
  13. package/dist/_match.js.map +1 -0
  14. package/dist/_named-keys.cjs +68 -0
  15. package/dist/_named-keys.cjs.map +1 -0
  16. package/dist/_named-keys.d.cts +8 -0
  17. package/dist/_named-keys.d.ts +8 -0
  18. package/dist/_named-keys.js +66 -0
  19. package/dist/_named-keys.js.map +1 -0
  20. package/dist/_recorder-chord.cjs +44 -0
  21. package/dist/_recorder-chord.cjs.map +1 -0
  22. package/dist/_recorder-chord.js +43 -0
  23. package/dist/_recorder-chord.js.map +1 -0
  24. package/dist/_recording-guard.cjs +59 -0
  25. package/dist/_recording-guard.cjs.map +1 -0
  26. package/dist/_recording-guard.js +56 -0
  27. package/dist/_recording-guard.js.map +1 -0
  28. package/dist/_registration.cjs +54 -0
  29. package/dist/_registration.cjs.map +1 -0
  30. package/dist/_registration.js +50 -0
  31. package/dist/_registration.js.map +1 -0
  32. package/dist/conflicts.cjs +55 -0
  33. package/dist/conflicts.cjs.map +1 -0
  34. package/dist/conflicts.d.cts +39 -0
  35. package/dist/conflicts.d.ts +39 -0
  36. package/dist/conflicts.js +55 -0
  37. package/dist/conflicts.js.map +1 -0
  38. package/dist/constants.cjs +46 -171
  39. package/dist/constants.cjs.map +1 -1
  40. package/dist/constants.d.cts +4 -129
  41. package/dist/constants.d.ts +4 -129
  42. package/dist/constants.js +48 -164
  43. package/dist/constants.js.map +1 -1
  44. package/dist/display-labels.cjs +119 -0
  45. package/dist/display-labels.cjs.map +1 -0
  46. package/dist/display-labels.d.cts +93 -0
  47. package/dist/display-labels.d.ts +93 -0
  48. package/dist/display-labels.js +113 -0
  49. package/dist/display-labels.js.map +1 -0
  50. package/dist/format.cjs +30 -36
  51. package/dist/format.cjs.map +1 -1
  52. package/dist/format.d.cts +46 -7
  53. package/dist/format.d.ts +46 -7
  54. package/dist/format.js +31 -37
  55. package/dist/format.js.map +1 -1
  56. package/dist/hint.cjs +24 -0
  57. package/dist/hint.cjs.map +1 -0
  58. package/dist/hint.d.cts +23 -0
  59. package/dist/hint.d.ts +23 -0
  60. package/dist/hint.js +24 -0
  61. package/dist/hint.js.map +1 -0
  62. package/dist/hotkey-manager.cjs +53 -22
  63. package/dist/hotkey-manager.cjs.map +1 -1
  64. package/dist/hotkey-manager.d.cts +6 -2
  65. package/dist/hotkey-manager.d.ts +6 -2
  66. package/dist/hotkey-manager.js +49 -18
  67. package/dist/hotkey-manager.js.map +1 -1
  68. package/dist/hotkey-recorder.cjs +67 -11
  69. package/dist/hotkey-recorder.cjs.map +1 -1
  70. package/dist/hotkey-recorder.d.cts +6 -3
  71. package/dist/hotkey-recorder.d.ts +6 -3
  72. package/dist/hotkey-recorder.js +66 -10
  73. package/dist/hotkey-recorder.js.map +1 -1
  74. package/dist/hotkey-sequence-recorder.cjs +85 -22
  75. package/dist/hotkey-sequence-recorder.cjs.map +1 -1
  76. package/dist/hotkey-sequence-recorder.d.cts +9 -2
  77. package/dist/hotkey-sequence-recorder.d.ts +9 -2
  78. package/dist/hotkey-sequence-recorder.js +84 -21
  79. package/dist/hotkey-sequence-recorder.js.map +1 -1
  80. package/dist/{hotkey.d.ts → hotkey.types.d.cts} +55 -120
  81. package/dist/{hotkey.d.cts → hotkey.types.d.ts} +55 -120
  82. package/dist/index.cjs +18 -10
  83. package/dist/index.d.cts +14 -9
  84. package/dist/index.d.ts +14 -9
  85. package/dist/index.js +10 -6
  86. package/dist/key-state-tracker.cjs +24 -24
  87. package/dist/key-state-tracker.cjs.map +1 -1
  88. package/dist/key-state-tracker.js +24 -24
  89. package/dist/key-state-tracker.js.map +1 -1
  90. package/dist/key.types.d.cts +82 -0
  91. package/dist/key.types.d.ts +82 -0
  92. package/dist/match.cjs +21 -30
  93. package/dist/match.cjs.map +1 -1
  94. package/dist/match.d.cts +19 -3
  95. package/dist/match.d.ts +19 -3
  96. package/dist/match.js +19 -29
  97. package/dist/match.js.map +1 -1
  98. package/dist/parse.cjs +43 -26
  99. package/dist/parse.cjs.map +1 -1
  100. package/dist/parse.d.cts +10 -4
  101. package/dist/parse.d.ts +10 -4
  102. package/dist/parse.js +35 -19
  103. package/dist/parse.js.map +1 -1
  104. package/dist/platform.cjs +55 -0
  105. package/dist/platform.cjs.map +1 -0
  106. package/dist/platform.d.cts +44 -0
  107. package/dist/platform.d.ts +44 -0
  108. package/dist/platform.js +53 -0
  109. package/dist/platform.js.map +1 -0
  110. package/dist/recorder-options.d.cts +34 -0
  111. package/dist/recorder-options.d.ts +34 -0
  112. package/dist/sequence-manager.cjs +54 -28
  113. package/dist/sequence-manager.cjs.map +1 -1
  114. package/dist/sequence-manager.d.cts +18 -3
  115. package/dist/sequence-manager.d.ts +18 -3
  116. package/dist/sequence-manager.js +49 -23
  117. package/dist/sequence-manager.js.map +1 -1
  118. package/dist/validate.cjs +6 -10
  119. package/dist/validate.cjs.map +1 -1
  120. package/dist/validate.d.cts +13 -2
  121. package/dist/validate.d.ts +13 -2
  122. package/dist/validate.js +7 -11
  123. package/dist/validate.js.map +1 -1
  124. package/package.json +2 -2
  125. package/src/{manager.utils.ts → _event-target.ts} +0 -74
  126. package/src/_keyboard-event.ts +101 -0
  127. package/src/_match.ts +96 -0
  128. package/src/_named-keys.ts +62 -0
  129. package/src/_recorder-chord.ts +76 -0
  130. package/src/_recording-guard.ts +63 -0
  131. package/src/_registration.ts +79 -0
  132. package/src/conflicts.ts +125 -0
  133. package/src/constants.ts +48 -196
  134. package/src/display-labels.ts +123 -0
  135. package/src/format.ts +111 -52
  136. package/src/hint.ts +42 -0
  137. package/src/hotkey-manager.ts +95 -40
  138. package/src/hotkey-recorder.ts +92 -16
  139. package/src/hotkey-sequence-recorder.ts +110 -28
  140. package/src/{hotkey.ts → hotkey.types.ts} +57 -224
  141. package/src/index.ts +11 -5
  142. package/src/key-state-tracker.ts +36 -24
  143. package/src/key.types.ts +268 -0
  144. package/src/match.ts +41 -90
  145. package/src/parse.ts +67 -26
  146. package/src/platform.ts +66 -0
  147. package/src/recorder-options.ts +34 -0
  148. package/src/sequence-manager.ts +77 -42
  149. package/src/validate.ts +29 -21
  150. package/dist/manager.utils.cjs.map +0 -1
  151. package/dist/manager.utils.d.cts +0 -13
  152. package/dist/manager.utils.d.ts +0 -13
  153. package/dist/manager.utils.js.map +0 -1
  154. package/dist/recorder-chord.cjs +0 -18
  155. package/dist/recorder-chord.cjs.map +0 -1
  156. package/dist/recorder-chord.js +0 -18
  157. package/dist/recorder-chord.js.map +0 -1
  158. package/src/recorder-chord.ts +0 -25
@@ -0,0 +1,93 @@
1
+ import { CanonicalModifier } from "./key.types.cjs";
2
+
3
+ //#region src/display-labels.d.ts
4
+ /**
5
+ * Modifier key symbols for macOS display.
6
+ *
7
+ * Used by formatting functions to display hotkeys with macOS-style symbols
8
+ * (e.g., ⌘ for Command, ⌃ for Control) instead of text labels. This provides
9
+ * a native macOS look and feel in hotkey displays.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * MAC_MODIFIER_SYMBOLS['Meta'] // '⌘'
14
+ * MAC_MODIFIER_SYMBOLS['Control'] // '⌃'
15
+ * MAC_MODIFIER_SYMBOLS['Alt'] // '⌥'
16
+ * MAC_MODIFIER_SYMBOLS['Shift'] // '⇧'
17
+ * ```
18
+ */
19
+ declare const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier | 'Mod', string>;
20
+ /**
21
+ * Modifier key labels for macOS display.
22
+ *
23
+ * Used by formatting functions to display hotkeys with macOS-style text labels
24
+ * (e.g., 'Control' for Control, 'Option' for Alt, 'Cmd' for Meta) instead of symbols.
25
+ * This provides a familiar macOS look and feel in hotkey displays.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * MAC_MODIFIER_LABELS['Control'] // 'control'
30
+ * MAC_MODIFIER_LABELS['Alt'] // 'option'
31
+ * MAC_MODIFIER_LABELS['Shift'] // 'shift'
32
+ * MAC_MODIFIER_LABELS['Meta'] // 'cmd'
33
+ * ```
34
+ */
35
+ declare const MAC_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
36
+ /**
37
+ * Modifier key labels for Windows/Linux display.
38
+ *
39
+ * Used by formatting functions to display hotkeys with standard text labels
40
+ * (e.g., 'Ctrl' for Control, 'Win' for Meta/Windows key) instead of symbols.
41
+ * This provides a familiar Windows/Linux look and feel in hotkey displays.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * STANDARD_MODIFIER_LABELS['Control'] // 'Ctrl'
46
+ * STANDARD_MODIFIER_LABELS['Meta'] // 'Win'
47
+ * STANDARD_MODIFIER_LABELS['Alt'] // 'Alt'
48
+ * STANDARD_MODIFIER_LABELS['Shift'] // 'Shift'
49
+ * ```
50
+ */
51
+ declare const WINDOWS_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
52
+ declare const LINUX_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
53
+ declare const PUNCTUATION_KEY_DISPLAY_LABELS: {
54
+ readonly '`': "Backquote";
55
+ readonly '\\': "Backslash";
56
+ readonly '[': "Left Bracket";
57
+ readonly ']': "Right Bracket";
58
+ readonly ',': "Comma";
59
+ readonly '=': "Equal";
60
+ readonly '-': "Minus";
61
+ readonly '.': "Period";
62
+ readonly ';': "Semicolon";
63
+ };
64
+ /**
65
+ * Special key symbols for display formatting.
66
+ *
67
+ * Maps certain keys to their visual symbols for better readability in hotkey displays.
68
+ * Used by formatting functions to show symbols like ↑ for ArrowUp or ↵ for Enter
69
+ * instead of text labels.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * KEY_DISPLAY_SYMBOLS['ArrowUp'] // '↑'
74
+ * KEY_DISPLAY_SYMBOLS['Enter'] // '↵'
75
+ * KEY_DISPLAY_SYMBOLS['Escape'] // 'Esc'
76
+ * KEY_DISPLAY_SYMBOLS['Space'] // '␣'
77
+ * ```
78
+ */
79
+ declare const KEY_DISPLAY_SYMBOLS: {
80
+ readonly ArrowUp: "↑";
81
+ readonly ArrowDown: "↓";
82
+ readonly ArrowLeft: "←";
83
+ readonly ArrowRight: "→";
84
+ readonly Enter: "↵";
85
+ readonly Escape: "Esc";
86
+ readonly Backspace: "⌫";
87
+ readonly Delete: "⌦";
88
+ readonly Tab: "⇥";
89
+ readonly Space: "␣";
90
+ };
91
+ //#endregion
92
+ export { KEY_DISPLAY_SYMBOLS, LINUX_MODIFIER_LABELS, MAC_MODIFIER_LABELS, MAC_MODIFIER_SYMBOLS, PUNCTUATION_KEY_DISPLAY_LABELS, WINDOWS_MODIFIER_LABELS };
93
+ //# sourceMappingURL=display-labels.d.cts.map
@@ -0,0 +1,93 @@
1
+ import { CanonicalModifier } from "./key.types.js";
2
+
3
+ //#region src/display-labels.d.ts
4
+ /**
5
+ * Modifier key symbols for macOS display.
6
+ *
7
+ * Used by formatting functions to display hotkeys with macOS-style symbols
8
+ * (e.g., ⌘ for Command, ⌃ for Control) instead of text labels. This provides
9
+ * a native macOS look and feel in hotkey displays.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * MAC_MODIFIER_SYMBOLS['Meta'] // '⌘'
14
+ * MAC_MODIFIER_SYMBOLS['Control'] // '⌃'
15
+ * MAC_MODIFIER_SYMBOLS['Alt'] // '⌥'
16
+ * MAC_MODIFIER_SYMBOLS['Shift'] // '⇧'
17
+ * ```
18
+ */
19
+ declare const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier | 'Mod', string>;
20
+ /**
21
+ * Modifier key labels for macOS display.
22
+ *
23
+ * Used by formatting functions to display hotkeys with macOS-style text labels
24
+ * (e.g., 'Control' for Control, 'Option' for Alt, 'Cmd' for Meta) instead of symbols.
25
+ * This provides a familiar macOS look and feel in hotkey displays.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * MAC_MODIFIER_LABELS['Control'] // 'control'
30
+ * MAC_MODIFIER_LABELS['Alt'] // 'option'
31
+ * MAC_MODIFIER_LABELS['Shift'] // 'shift'
32
+ * MAC_MODIFIER_LABELS['Meta'] // 'cmd'
33
+ * ```
34
+ */
35
+ declare const MAC_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
36
+ /**
37
+ * Modifier key labels for Windows/Linux display.
38
+ *
39
+ * Used by formatting functions to display hotkeys with standard text labels
40
+ * (e.g., 'Ctrl' for Control, 'Win' for Meta/Windows key) instead of symbols.
41
+ * This provides a familiar Windows/Linux look and feel in hotkey displays.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * STANDARD_MODIFIER_LABELS['Control'] // 'Ctrl'
46
+ * STANDARD_MODIFIER_LABELS['Meta'] // 'Win'
47
+ * STANDARD_MODIFIER_LABELS['Alt'] // 'Alt'
48
+ * STANDARD_MODIFIER_LABELS['Shift'] // 'Shift'
49
+ * ```
50
+ */
51
+ declare const WINDOWS_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
52
+ declare const LINUX_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string>;
53
+ declare const PUNCTUATION_KEY_DISPLAY_LABELS: {
54
+ readonly '`': "Backquote";
55
+ readonly '\\': "Backslash";
56
+ readonly '[': "Left Bracket";
57
+ readonly ']': "Right Bracket";
58
+ readonly ',': "Comma";
59
+ readonly '=': "Equal";
60
+ readonly '-': "Minus";
61
+ readonly '.': "Period";
62
+ readonly ';': "Semicolon";
63
+ };
64
+ /**
65
+ * Special key symbols for display formatting.
66
+ *
67
+ * Maps certain keys to their visual symbols for better readability in hotkey displays.
68
+ * Used by formatting functions to show symbols like ↑ for ArrowUp or ↵ for Enter
69
+ * instead of text labels.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * KEY_DISPLAY_SYMBOLS['ArrowUp'] // '↑'
74
+ * KEY_DISPLAY_SYMBOLS['Enter'] // '↵'
75
+ * KEY_DISPLAY_SYMBOLS['Escape'] // 'Esc'
76
+ * KEY_DISPLAY_SYMBOLS['Space'] // '␣'
77
+ * ```
78
+ */
79
+ declare const KEY_DISPLAY_SYMBOLS: {
80
+ readonly ArrowUp: "↑";
81
+ readonly ArrowDown: "↓";
82
+ readonly ArrowLeft: "←";
83
+ readonly ArrowRight: "→";
84
+ readonly Enter: "↵";
85
+ readonly Escape: "Esc";
86
+ readonly Backspace: "⌫";
87
+ readonly Delete: "⌦";
88
+ readonly Tab: "⇥";
89
+ readonly Space: "␣";
90
+ };
91
+ //#endregion
92
+ export { KEY_DISPLAY_SYMBOLS, LINUX_MODIFIER_LABELS, MAC_MODIFIER_LABELS, MAC_MODIFIER_SYMBOLS, PUNCTUATION_KEY_DISPLAY_LABELS, WINDOWS_MODIFIER_LABELS };
93
+ //# sourceMappingURL=display-labels.d.ts.map
@@ -0,0 +1,113 @@
1
+ //#region src/display-labels.ts
2
+ /**
3
+ * Modifier key symbols for macOS display.
4
+ *
5
+ * Used by formatting functions to display hotkeys with macOS-style symbols
6
+ * (e.g., ⌘ for Command, ⌃ for Control) instead of text labels. This provides
7
+ * a native macOS look and feel in hotkey displays.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * MAC_MODIFIER_SYMBOLS['Meta'] // '⌘'
12
+ * MAC_MODIFIER_SYMBOLS['Control'] // '⌃'
13
+ * MAC_MODIFIER_SYMBOLS['Alt'] // '⌥'
14
+ * MAC_MODIFIER_SYMBOLS['Shift'] // '⇧'
15
+ * ```
16
+ */
17
+ const MAC_MODIFIER_SYMBOLS = {
18
+ Control: "⌃",
19
+ Alt: "⌥",
20
+ Shift: "⇧",
21
+ Meta: "⌘",
22
+ Mod: "⌘"
23
+ };
24
+ /**
25
+ * Modifier key labels for macOS display.
26
+ *
27
+ * Used by formatting functions to display hotkeys with macOS-style text labels
28
+ * (e.g., 'Control' for Control, 'Option' for Alt, 'Cmd' for Meta) instead of symbols.
29
+ * This provides a familiar macOS look and feel in hotkey displays.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * MAC_MODIFIER_LABELS['Control'] // 'control'
34
+ * MAC_MODIFIER_LABELS['Alt'] // 'option'
35
+ * MAC_MODIFIER_LABELS['Shift'] // 'shift'
36
+ * MAC_MODIFIER_LABELS['Meta'] // 'cmd'
37
+ * ```
38
+ */
39
+ const MAC_MODIFIER_LABELS = {
40
+ Control: "Control",
41
+ Alt: "Option",
42
+ Shift: "Shift",
43
+ Meta: "Cmd",
44
+ Mod: "Cmd"
45
+ };
46
+ /**
47
+ * Modifier key labels for Windows/Linux display.
48
+ *
49
+ * Used by formatting functions to display hotkeys with standard text labels
50
+ * (e.g., 'Ctrl' for Control, 'Win' for Meta/Windows key) instead of symbols.
51
+ * This provides a familiar Windows/Linux look and feel in hotkey displays.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * STANDARD_MODIFIER_LABELS['Control'] // 'Ctrl'
56
+ * STANDARD_MODIFIER_LABELS['Meta'] // 'Win'
57
+ * STANDARD_MODIFIER_LABELS['Alt'] // 'Alt'
58
+ * STANDARD_MODIFIER_LABELS['Shift'] // 'Shift'
59
+ * ```
60
+ */
61
+ const WINDOWS_MODIFIER_LABELS = {
62
+ Control: "Ctrl",
63
+ Alt: "Alt",
64
+ Shift: "Shift",
65
+ Meta: "Win",
66
+ Mod: "Ctrl"
67
+ };
68
+ const LINUX_MODIFIER_LABELS = {
69
+ ...WINDOWS_MODIFIER_LABELS,
70
+ Meta: "Super"
71
+ };
72
+ const PUNCTUATION_KEY_DISPLAY_LABELS = {
73
+ "`": "Backquote",
74
+ "\\": "Backslash",
75
+ "[": "Left Bracket",
76
+ "]": "Right Bracket",
77
+ ",": "Comma",
78
+ "=": "Equal",
79
+ "-": "Minus",
80
+ ".": "Period",
81
+ ";": "Semicolon"
82
+ };
83
+ /**
84
+ * Special key symbols for display formatting.
85
+ *
86
+ * Maps certain keys to their visual symbols for better readability in hotkey displays.
87
+ * Used by formatting functions to show symbols like ↑ for ArrowUp or ↵ for Enter
88
+ * instead of text labels.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * KEY_DISPLAY_SYMBOLS['ArrowUp'] // '↑'
93
+ * KEY_DISPLAY_SYMBOLS['Enter'] // '↵'
94
+ * KEY_DISPLAY_SYMBOLS['Escape'] // 'Esc'
95
+ * KEY_DISPLAY_SYMBOLS['Space'] // '␣'
96
+ * ```
97
+ */
98
+ const KEY_DISPLAY_SYMBOLS = {
99
+ ArrowUp: "↑",
100
+ ArrowDown: "↓",
101
+ ArrowLeft: "←",
102
+ ArrowRight: "→",
103
+ Enter: "↵",
104
+ Escape: "Esc",
105
+ Backspace: "⌫",
106
+ Delete: "⌦",
107
+ Tab: "⇥",
108
+ Space: "␣"
109
+ };
110
+
111
+ //#endregion
112
+ export { KEY_DISPLAY_SYMBOLS, LINUX_MODIFIER_LABELS, MAC_MODIFIER_LABELS, MAC_MODIFIER_SYMBOLS, PUNCTUATION_KEY_DISPLAY_LABELS, WINDOWS_MODIFIER_LABELS };
113
+ //# sourceMappingURL=display-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-labels.js","names":[],"sources":["../src/display-labels.ts"],"sourcesContent":["import type { CanonicalModifier } from './key.types'\n\n// =============================================================================\n// Display Symbols\n// =============================================================================\n\n/**\n * Modifier key symbols for macOS display.\n *\n * Used by formatting functions to display hotkeys with macOS-style symbols\n * (e.g., ⌘ for Command, ⌃ for Control) instead of text labels. This provides\n * a native macOS look and feel in hotkey displays.\n *\n * @example\n * ```ts\n * MAC_MODIFIER_SYMBOLS['Meta'] // '⌘'\n * MAC_MODIFIER_SYMBOLS['Control'] // '⌃'\n * MAC_MODIFIER_SYMBOLS['Alt'] // '⌥'\n * MAC_MODIFIER_SYMBOLS['Shift'] // '⇧'\n * ```\n */\nexport const MAC_MODIFIER_SYMBOLS: Record<CanonicalModifier | 'Mod', string> = {\n Control: '⌃',\n Alt: '⌥',\n Shift: '⇧',\n Meta: '⌘',\n Mod: '⌘',\n}\n\n/**\n * Modifier key labels for macOS display.\n *\n * Used by formatting functions to display hotkeys with macOS-style text labels\n * (e.g., 'Control' for Control, 'Option' for Alt, 'Cmd' for Meta) instead of symbols.\n * This provides a familiar macOS look and feel in hotkey displays.\n *\n * @example\n * ```ts\n * MAC_MODIFIER_LABELS['Control'] // 'control'\n * MAC_MODIFIER_LABELS['Alt'] // 'option'\n * MAC_MODIFIER_LABELS['Shift'] // 'shift'\n * MAC_MODIFIER_LABELS['Meta'] // 'cmd'\n * ```\n */\nexport const MAC_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string> = {\n Control: 'Control',\n Alt: 'Option',\n Shift: 'Shift',\n Meta: 'Cmd',\n Mod: 'Cmd',\n}\n\n/**\n * Modifier key labels for Windows/Linux display.\n *\n * Used by formatting functions to display hotkeys with standard text labels\n * (e.g., 'Ctrl' for Control, 'Win' for Meta/Windows key) instead of symbols.\n * This provides a familiar Windows/Linux look and feel in hotkey displays.\n *\n * @example\n * ```ts\n * STANDARD_MODIFIER_LABELS['Control'] // 'Ctrl'\n * STANDARD_MODIFIER_LABELS['Meta'] // 'Win'\n * STANDARD_MODIFIER_LABELS['Alt'] // 'Alt'\n * STANDARD_MODIFIER_LABELS['Shift'] // 'Shift'\n * ```\n */\nexport const WINDOWS_MODIFIER_LABELS: Record<\n CanonicalModifier | 'Mod',\n string\n> = {\n Control: 'Ctrl',\n Alt: 'Alt',\n Shift: 'Shift',\n Meta: 'Win',\n Mod: 'Ctrl',\n}\n\nexport const LINUX_MODIFIER_LABELS: Record<CanonicalModifier | 'Mod', string> =\n {\n ...WINDOWS_MODIFIER_LABELS,\n Meta: 'Super',\n }\n\nexport const PUNCTUATION_KEY_DISPLAY_LABELS = {\n '`': 'Backquote',\n '\\\\': 'Backslash',\n '[': 'Left Bracket',\n ']': 'Right Bracket',\n ',': 'Comma',\n '=': 'Equal',\n '-': 'Minus',\n '.': 'Period',\n ';': 'Semicolon',\n} as const satisfies Record<string, string>\n\n/**\n * Special key symbols for display formatting.\n *\n * Maps certain keys to their visual symbols for better readability in hotkey displays.\n * Used by formatting functions to show symbols like ↑ for ArrowUp or ↵ for Enter\n * instead of text labels.\n *\n * @example\n * ```ts\n * KEY_DISPLAY_SYMBOLS['ArrowUp'] // '↑'\n * KEY_DISPLAY_SYMBOLS['Enter'] // '↵'\n * KEY_DISPLAY_SYMBOLS['Escape'] // 'Esc'\n * KEY_DISPLAY_SYMBOLS['Space'] // '␣'\n * ```\n */\nexport const KEY_DISPLAY_SYMBOLS = {\n ArrowUp: '↑',\n ArrowDown: '↓',\n ArrowLeft: '←',\n ArrowRight: '→',\n Enter: '↵',\n Escape: 'Esc',\n Backspace: '⌫',\n Delete: '⌦',\n Tab: '⇥',\n Space: '␣',\n} as const satisfies Record<string, string>\n"],"mappings":";;;;;;;;;;;;;;;;AAqBA,MAAa,uBAAkE;CAC7E,SAAS;CACT,KAAK;CACL,OAAO;CACP,MAAM;CACN,KAAK;CACN;;;;;;;;;;;;;;;;AAiBD,MAAa,sBAAiE;CAC5E,SAAS;CACT,KAAK;CACL,OAAO;CACP,MAAM;CACN,KAAK;CACN;;;;;;;;;;;;;;;;AAiBD,MAAa,0BAGT;CACF,SAAS;CACT,KAAK;CACL,OAAO;CACP,MAAM;CACN,KAAK;CACN;AAED,MAAa,wBACX;CACE,GAAG;CACH,MAAM;CACP;AAEH,MAAa,iCAAiC;CAC5C,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;;;;;;;;;;;;;;;;AAiBD,MAAa,sBAAsB;CACjC,SAAS;CACT,WAAW;CACX,WAAW;CACX,YAAY;CACZ,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,OAAO;CACR"}
package/dist/format.cjs CHANGED
@@ -1,9 +1,13 @@
1
1
  const require_constants = require('./constants.cjs');
2
+ const require_display_labels = require('./display-labels.cjs');
3
+ const require_platform = require('./platform.cjs');
4
+ const require__keyboard_event = require('./_keyboard-event.cjs');
2
5
  const require_parse = require('./parse.cjs');
3
6
 
4
7
  //#region src/format.ts
5
8
  /**
6
- * Converts a hotkey sequence array to a display string.
9
+ * Joins stored sequence steps with spaces, preserving physical code tokens.
10
+ * For user-facing labels, call formatForDisplay on each step instead.
7
11
  *
8
12
  * @param sequence - Array of hotkey strings that form the sequence
9
13
  * @returns A space-separated string (e.g. ['G','G'] → 'G G')
@@ -30,48 +34,38 @@ function formatHotkeySequence(sequence) {
30
34
  * ```
31
35
  */
32
36
  function formatHotkey(parsed) {
37
+ if (parsed.code === void 0) require__keyboard_event.assertLogicalKey(parsed.key);
33
38
  const parts = [];
34
39
  for (const modifier of require_constants.MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(modifier);
35
- parts.push(parsed.key);
40
+ parts.push(parsed.code !== void 0 ? `[${parsed.code}]` : parsed.key);
36
41
  return parts.join("+");
37
42
  }
38
- /**
39
- * Formats a hotkey for display in a user interface.
40
- *
41
- * On macOS, uses symbols (⌘⇧S) in the same modifier order as {@link normalizeHotkeyFromParsed}.
42
- * On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.
43
- * The separator can be customized with `separatorToken`.
44
- *
45
- * @param hotkey - The hotkey string or ParsedHotkey to format
46
- * @param options - Formatting options
47
- * @returns A formatted string suitable for display
48
- *
49
- * @example
50
- * ```ts
51
- * formatForDisplay('Mod+Shift+S', { platform: 'mac' })
52
- * // Returns: '⌘ ⇧ S' (symbols separated by spaces on macOS)
53
- *
54
- * formatForDisplay('Mod+Shift+S', { platform: 'windows' })
55
- * // Returns: 'Ctrl+Shift+S'
56
- *
57
- * formatForDisplay('Escape')
58
- * // Returns: 'Esc' (on all platforms)
59
- * ```
60
- */
61
43
  function formatForDisplay(hotkey, options = {}) {
62
- const platform = options.platform ?? require_constants.detectPlatform();
63
- const useSymbols = options.useSymbols ?? true;
64
- const separatorToken = options.separatorToken ?? (platform === "mac" && useSymbols ? " " : "+");
65
- return require_parse.normalizeRegisterableHotkey(hotkey, platform).split("+").map((segment) => {
44
+ const platform = options.platform ?? require_platform.detectPlatform();
45
+ const symbols = options.useSymbols ?? true;
46
+ const modifierSymbols = typeof symbols === "boolean" ? symbols : symbols.modifiers ?? true;
47
+ const keySymbols = typeof symbols === "boolean" ? symbols : symbols.keys ?? true;
48
+ const separator = options.separatorToken ?? (platform === "mac" && modifierSymbols ? " " : "+");
49
+ const parts = require__keyboard_event.splitHotkeyParts(typeof hotkey === "object" && "modifiers" in hotkey ? require_parse.normalizeHotkeyFromParsed(hotkey, platform) : require_parse.normalizeRegisterableHotkey(hotkey, platform)).map((segment) => {
66
50
  if (require_parse.isModifierKey(segment)) {
67
- const modifierToken = require_constants.MODIFIER_ALIASES[segment] ?? require_constants.MODIFIER_ALIASES[segment.toLowerCase()];
68
- return platform === "mac" ? useSymbols ? require_constants.MAC_MODIFIER_SYMBOLS[modifierToken] : require_constants.MAC_MODIFIER_LABELS[modifierToken] : platform === "windows" ? require_constants.WINDOWS_MODIFIER_LABELS[modifierToken] : require_constants.LINUX_MODIFIER_LABELS[modifierToken];
69
- } else {
70
- const keyDisplaySymbol = useSymbols && require_constants.KEY_DISPLAY_SYMBOLS[segment];
71
- if (keyDisplaySymbol) return keyDisplaySymbol;
72
- return !useSymbols && require_constants.PUNCTUATION_KEY_DISPLAY_LABELS[segment] || segment;
51
+ const modifier = require_constants.MODIFIER_ALIASES[segment] ?? require_constants.MODIFIER_ALIASES[segment.toLowerCase()];
52
+ return platform === "mac" ? modifierSymbols ? require_display_labels.MAC_MODIFIER_SYMBOLS[modifier] : require_display_labels.MAC_MODIFIER_LABELS[modifier] : platform === "windows" ? require_display_labels.WINDOWS_MODIFIER_LABELS[modifier] : require_display_labels.LINUX_MODIFIER_LABELS[modifier];
73
53
  }
74
- }).join(separatorToken);
54
+ const code = /^\[([A-Za-z][A-Za-z0-9]*)\]$/.exec(segment)?.[1];
55
+ const label = options.keyLabels?.[code ?? segment];
56
+ if (label !== void 0) return label;
57
+ const numpad = code?.startsWith("Numpad") ?? false;
58
+ let displayKey = code ?? segment;
59
+ const mappedKey = code ? options.layoutMap?.get(code) : void 0;
60
+ if (mappedKey) displayKey = require_constants.normalizeKeyName(mappedKey);
61
+ else if (code) if (/^Key[A-Z]$/.test(code)) displayKey = code.slice(3);
62
+ else if (/^Digit[0-9]$/.test(code)) displayKey = code.slice(5);
63
+ else if (numpad) displayKey = code.slice(6);
64
+ else displayKey = require_constants.PUNCTUATION_CODE_MAP[code] ?? code;
65
+ const display = (keySymbols ? require_display_labels.KEY_DISPLAY_SYMBOLS : require_display_labels.PUNCTUATION_KEY_DISPLAY_LABELS)[displayKey] ?? displayKey;
66
+ return numpad ? `Numpad ${display.replace(/([a-z])([A-Z])/g, "$1 $2")}` : display;
67
+ });
68
+ return options.parts ? parts : parts.join(separator);
75
69
  }
76
70
  /**
77
71
  * @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.
@@ -1 +1 @@
1
- {"version":3,"file":"format.cjs","names":["MODIFIER_ORDER","detectPlatform","normalizeRegisterableHotkey","isModifierKey","MODIFIER_ALIASES","MAC_MODIFIER_SYMBOLS","MAC_MODIFIER_LABELS","WINDOWS_MODIFIER_LABELS","LINUX_MODIFIER_LABELS","KEY_DISPLAY_SYMBOLS","PUNCTUATION_KEY_DISPLAY_LABELS"],"sources":["../src/format.ts"],"sourcesContent":["import {\n KEY_DISPLAY_SYMBOLS,\n LINUX_MODIFIER_LABELS,\n MAC_MODIFIER_LABELS,\n MAC_MODIFIER_SYMBOLS,\n MODIFIER_ALIASES,\n MODIFIER_ORDER,\n PUNCTUATION_KEY_DISPLAY_LABELS,\n WINDOWS_MODIFIER_LABELS,\n detectPlatform,\n} from './constants'\nimport {\n isModifierKey,\n normalizeHotkeyFromParsed,\n normalizeRegisterableHotkey,\n} from './parse'\nimport type {\n CanonicalModifier,\n FormatDisplayOptions,\n Hotkey,\n ParsedHotkey,\n RegisterableHotkey,\n} from './hotkey'\n\n/**\n * Converts a hotkey sequence array to a display string.\n *\n * @param sequence - Array of hotkey strings that form the sequence\n * @returns A space-separated string (e.g. ['G','G'] → 'G G')\n *\n * @example\n * ```ts\n * formatHotkeySequence(['G', 'G']) // 'G G'\n * formatHotkeySequence(['D', 'I', 'W']) // 'D I W'\n * ```\n */\nexport function formatHotkeySequence(sequence: Array<Hotkey>): string {\n return sequence.join(' ')\n}\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) in the same modifier order as {@link normalizeHotkeyFromParsed}.\n * On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.\n * The separator can be customized with `separatorToken`.\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' (symbols separated by spaces on macOS)\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: RegisterableHotkey | (string & {}),\n options: FormatDisplayOptions = {},\n): string {\n const platform = options.platform ?? detectPlatform()\n const useSymbols = options.useSymbols ?? true\n const separatorToken =\n options.separatorToken ?? (platform === 'mac' && useSymbols ? ' ' : '+')\n const normalizedHotkey = normalizeRegisterableHotkey(\n hotkey as RegisterableHotkey,\n platform,\n )\n return normalizedHotkey\n .split('+')\n .map((segment) => {\n if (isModifierKey(segment)) {\n const modifierToken = (MODIFIER_ALIASES[segment] ??\n MODIFIER_ALIASES[segment.toLowerCase()]) as CanonicalModifier | 'Mod'\n return platform === 'mac'\n ? useSymbols\n ? MAC_MODIFIER_SYMBOLS[modifierToken]\n : MAC_MODIFIER_LABELS[modifierToken]\n : platform === 'windows'\n ? WINDOWS_MODIFIER_LABELS[modifierToken]\n : LINUX_MODIFIER_LABELS[modifierToken]\n } else {\n const keyDisplaySymbol =\n useSymbols &&\n KEY_DISPLAY_SYMBOLS[segment as keyof typeof KEY_DISPLAY_SYMBOLS]\n if (keyDisplaySymbol) return keyDisplaySymbol\n\n const punctuationKeyDisplayLabel =\n !useSymbols &&\n PUNCTUATION_KEY_DISPLAY_LABELS[\n segment as keyof typeof PUNCTUATION_KEY_DISPLAY_LABELS\n ]\n return punctuationKeyDisplayLabel || segment\n }\n })\n .join(separatorToken)\n}\n\n/**\n * @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.\n */\nexport function formatWithLabels(\n hotkey: RegisterableHotkey,\n options: Omit<FormatDisplayOptions, 'useSymbols'> = {},\n): string {\n return formatForDisplay(hotkey, { ...options, useSymbols: false })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAoCA,SAAgB,qBAAqB,UAAiC;AACpE,QAAO,SAAS,KAAK,IAAI;;;;;;;;;;;;;;AAe3B,SAAgB,aAAa,QAA8B;CACzD,MAAM,QAAuB,EAAE;AAG/B,MAAK,MAAM,YAAYA,iCACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,SAAS;AAKxB,OAAM,KAAK,OAAO,IAAI;AAEtB,QAAO,MAAM,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;AA0BxB,SAAgB,iBACd,QACA,UAAgC,EAAE,EAC1B;CACR,MAAM,WAAW,QAAQ,YAAYC,kCAAgB;CACrD,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,iBACJ,QAAQ,mBAAmB,aAAa,SAAS,aAAa,MAAM;AAKtE,QAJyBC,0CACvB,QACA,SACD,CAEE,MAAM,IAAI,CACV,KAAK,YAAY;AAChB,MAAIC,4BAAc,QAAQ,EAAE;GAC1B,MAAM,gBAAiBC,mCAAiB,YACtCA,mCAAiB,QAAQ,aAAa;AACxC,UAAO,aAAa,QAChB,aACEC,uCAAqB,iBACrBC,sCAAoB,iBACtB,aAAa,YACXC,0CAAwB,iBACxBC,wCAAsB;SACvB;GACL,MAAM,mBACJ,cACAC,sCAAoB;AACtB,OAAI,iBAAkB,QAAO;AAO7B,UAJE,CAAC,cACDC,iDACE,YAEiC;;GAEvC,CACD,KAAK,eAAe;;;;;AAMzB,SAAgB,iBACd,QACA,UAAoD,EAAE,EAC9C;AACR,QAAO,iBAAiB,QAAQ;EAAE,GAAG;EAAS,YAAY;EAAO,CAAC"}
1
+ {"version":3,"file":"format.cjs","names":["MODIFIER_ORDER","detectPlatform","splitHotkeyParts","normalizeHotkeyFromParsed","normalizeRegisterableHotkey","isModifierKey","MODIFIER_ALIASES","MAC_MODIFIER_SYMBOLS","MAC_MODIFIER_LABELS","WINDOWS_MODIFIER_LABELS","LINUX_MODIFIER_LABELS","normalizeKeyName","PUNCTUATION_CODE_MAP","KEY_DISPLAY_SYMBOLS","PUNCTUATION_KEY_DISPLAY_LABELS"],"sources":["../src/format.ts"],"sourcesContent":["import {\n KEY_DISPLAY_SYMBOLS,\n LINUX_MODIFIER_LABELS,\n MAC_MODIFIER_LABELS,\n MAC_MODIFIER_SYMBOLS,\n PUNCTUATION_KEY_DISPLAY_LABELS,\n WINDOWS_MODIFIER_LABELS,\n} from './display-labels'\nimport {\n MODIFIER_ALIASES,\n MODIFIER_ORDER,\n PUNCTUATION_CODE_MAP,\n normalizeKeyName,\n} from './constants'\nimport { detectPlatform } from './platform'\nimport { assertLogicalKey, splitHotkeyParts } from './_keyboard-event'\nimport {\n isModifierKey,\n normalizeHotkeyFromParsed,\n normalizeRegisterableHotkey,\n} from './parse'\nimport type { CanonicalModifier } from './key.types'\nimport type { Hotkey, ParsedHotkey, RegisterableHotkey } from './hotkey.types'\n\n/**\n * Joins stored sequence steps with spaces, preserving physical code tokens.\n * For user-facing labels, call formatForDisplay on each step instead.\n *\n * @param sequence - Array of hotkey strings that form the sequence\n * @returns A space-separated string (e.g. ['G','G'] → 'G G')\n *\n * @example\n * ```ts\n * formatHotkeySequence(['G', 'G']) // 'G G'\n * formatHotkeySequence(['D', 'I', 'W']) // 'D I W'\n * ```\n */\nexport function formatHotkeySequence(sequence: Array<Hotkey>): string {\n return sequence.join(' ')\n}\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 if (parsed.code === undefined) assertLogicalKey(parsed.key)\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.code !== undefined ? `[${parsed.code}]` : parsed.key)\n\n return parts.join('+')\n}\n\nexport type DisplayHotkey = RegisterableHotkey | ParsedHotkey | (string & {})\n\n/**\n * Formats a hotkey for display in a user interface.\n *\n * On macOS, uses symbols (⌘⇧S) in the same modifier order as {@link normalizeHotkeyFromParsed}.\n * On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.\n * The separator can be customized with `separatorToken`.\n * Physical codes use conventional display labels: `[KeyS]` becomes `S` and\n * `[Digit2]` becomes `2`. These labels do not infer the active keyboard layout\n * or change matching. Supply a resolved `layoutMap` for layout-aware labels;\n * `keyLabels` overrides both layout entries and fallback labels.\n *\n * @param hotkey - A logical or physical string, raw binding, or ParsedHotkey\n * @param options - Formatting options\n * @returns Display text, or individual key labels when parts is true\n *\n * @example\n * ```ts\n * formatForDisplay('Mod+Shift+S', { platform: 'mac' })\n * // Returns: '⌘ ⇧ S' (symbols separated by spaces on macOS)\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: DisplayHotkey,\n options: FormatDisplayOptions & { parts: true },\n): Array<string>\nexport function formatForDisplay(\n hotkey: DisplayHotkey,\n options?: FormatDisplayOptions & { parts?: false },\n): string\nexport function formatForDisplay(\n hotkey: DisplayHotkey,\n options: FormatDisplayOptions,\n): string | Array<string>\nexport function formatForDisplay(\n hotkey: DisplayHotkey,\n options: FormatDisplayOptions = {},\n): string | Array<string> {\n const platform = options.platform ?? detectPlatform()\n const symbols = options.useSymbols ?? true\n const modifierSymbols =\n typeof symbols === 'boolean' ? symbols : (symbols.modifiers ?? true)\n const keySymbols =\n typeof symbols === 'boolean' ? symbols : (symbols.keys ?? true)\n const separator =\n options.separatorToken ??\n (platform === 'mac' && modifierSymbols ? ' ' : '+')\n const normalized =\n typeof hotkey === 'object' && 'modifiers' in hotkey\n ? normalizeHotkeyFromParsed(hotkey, platform)\n : normalizeRegisterableHotkey(hotkey as RegisterableHotkey, platform)\n const parts = splitHotkeyParts(normalized).map((segment) => {\n if (isModifierKey(segment)) {\n const modifier = (MODIFIER_ALIASES[segment] ??\n MODIFIER_ALIASES[segment.toLowerCase()]) as CanonicalModifier | 'Mod'\n return platform === 'mac'\n ? modifierSymbols\n ? MAC_MODIFIER_SYMBOLS[modifier]\n : MAC_MODIFIER_LABELS[modifier]\n : platform === 'windows'\n ? WINDOWS_MODIFIER_LABELS[modifier]\n : LINUX_MODIFIER_LABELS[modifier]\n }\n const code = /^\\[([A-Za-z][A-Za-z0-9]*)\\]$/.exec(segment)?.[1]\n const label = options.keyLabels?.[code ?? segment]\n if (label !== undefined) return label\n // Shorten conventional position labels for display only; stored identity is unchanged.\n const numpad = code?.startsWith('Numpad') ?? false\n let displayKey = code ?? segment\n const mappedKey = code ? options.layoutMap?.get(code) : undefined\n if (mappedKey) {\n // Layout entries are logical labels; normalize their case and whitespace names.\n displayKey = normalizeKeyName(mappedKey)\n } else if (code) {\n if (/^Key[A-Z]$/.test(code)) displayKey = code.slice(3)\n else if (/^Digit[0-9]$/.test(code)) displayKey = code.slice(5)\n else if (numpad) displayKey = code.slice(6)\n else displayKey = PUNCTUATION_CODE_MAP[code] ?? code\n }\n const labels = keySymbols\n ? KEY_DISPLAY_SYMBOLS\n : PUNCTUATION_KEY_DISPLAY_LABELS\n const display =\n (labels as Partial<Record<string, string>>)[displayKey] ?? displayKey\n // Retain numpad identity while making longer names such as MemoryAdd readable.\n return numpad\n ? `Numpad ${display.replace(/([a-z])([A-Z])/g, '$1 $2')}`\n : display\n })\n return options.parts ? parts : parts.join(separator)\n}\n\n/**\n * @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.\n */\nexport function formatWithLabels(\n hotkey: RegisterableHotkey,\n options: Omit<FormatDisplayOptions, 'useSymbols' | 'parts'> = {},\n): string {\n return formatForDisplay(hotkey, { ...options, useSymbols: false })\n}\n\n/**\n * Options for formatting hotkeys for display.\n */\nexport interface FormatDisplayOptions {\n /** The target platform. Defaults to auto-detection. */\n platform?: 'mac' | 'windows' | 'linux'\n /** Whether to use symbols for the display. Defaults to true. */\n useSymbols?: boolean | { modifiers?: boolean; keys?: boolean }\n /** Return individual key labels instead of a joined string. Default: false. */\n parts?: boolean\n /**\n * An already-resolved code-to-key map, such as KeyboardLayoutMap or Map.\n * Used only for physical bindings. Mapped keys receive normal display formatting;\n * missing or empty entries use conventional fallback labels. The caller owns\n * loading and refreshing the map; this formatter never calls browser APIs.\n */\n layoutMap?: { get: (code: string) => string | undefined }\n /** Final display overrides for logical keys or physical codes; take precedence over layoutMap. Never changes matching. */\n keyLabels?: Readonly<Record<string, string>>\n /** Override the separator between display tokens. Defaults to platform-specific formatting when null/undefined. */\n separatorToken?: string | null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,qBAAqB,UAAiC;AACpE,QAAO,SAAS,KAAK,IAAI;;;;;;;;;;;;;;AAe3B,SAAgB,aAAa,QAA8B;AACzD,KAAI,OAAO,SAAS,OAAW,0CAAiB,OAAO,IAAI;CAC3D,MAAM,QAAuB,EAAE;AAG/B,MAAK,MAAM,YAAYA,iCACrB,KAAI,OAAO,UAAU,SAAS,SAAS,CACrC,OAAM,KAAK,SAAS;AAKxB,OAAM,KAAK,OAAO,SAAS,SAAY,IAAI,OAAO,KAAK,KAAK,OAAO,IAAI;AAEvE,QAAO,MAAM,KAAK,IAAI;;AA4CxB,SAAgB,iBACd,QACA,UAAgC,EAAE,EACV;CACxB,MAAM,WAAW,QAAQ,YAAYC,iCAAgB;CACrD,MAAM,UAAU,QAAQ,cAAc;CACtC,MAAM,kBACJ,OAAO,YAAY,YAAY,UAAW,QAAQ,aAAa;CACjE,MAAM,aACJ,OAAO,YAAY,YAAY,UAAW,QAAQ,QAAQ;CAC5D,MAAM,YACJ,QAAQ,mBACP,aAAa,SAAS,kBAAkB,MAAM;CAKjD,MAAM,QAAQC,yCAHZ,OAAO,WAAW,YAAY,eAAe,SACzCC,wCAA0B,QAAQ,SAAS,GAC3CC,0CAA4B,QAA8B,SAAS,CAC/B,CAAC,KAAK,YAAY;AAC1D,MAAIC,4BAAc,QAAQ,EAAE;GAC1B,MAAM,WAAYC,mCAAiB,YACjCA,mCAAiB,QAAQ,aAAa;AACxC,UAAO,aAAa,QAChB,kBACEC,4CAAqB,YACrBC,2CAAoB,YACtB,aAAa,YACXC,+CAAwB,YACxBC,6CAAsB;;EAE9B,MAAM,OAAO,+BAA+B,KAAK,QAAQ,GAAG;EAC5D,MAAM,QAAQ,QAAQ,YAAY,QAAQ;AAC1C,MAAI,UAAU,OAAW,QAAO;EAEhC,MAAM,SAAS,MAAM,WAAW,SAAS,IAAI;EAC7C,IAAI,aAAa,QAAQ;EACzB,MAAM,YAAY,OAAO,QAAQ,WAAW,IAAI,KAAK,GAAG;AACxD,MAAI,UAEF,cAAaC,mCAAiB,UAAU;WAC/B,KACT,KAAI,aAAa,KAAK,KAAK,CAAE,cAAa,KAAK,MAAM,EAAE;WAC9C,eAAe,KAAK,KAAK,CAAE,cAAa,KAAK,MAAM,EAAE;WACrD,OAAQ,cAAa,KAAK,MAAM,EAAE;MACtC,cAAaC,uCAAqB,SAAS;EAKlD,MAAM,WAHS,aACXC,6CACAC,uDAE0C,eAAe;AAE7D,SAAO,SACH,UAAU,QAAQ,QAAQ,mBAAmB,QAAQ,KACrD;GACJ;AACF,QAAO,QAAQ,QAAQ,QAAQ,MAAM,KAAK,UAAU;;;;;AAMtD,SAAgB,iBACd,QACA,UAA8D,EAAE,EACxD;AACR,QAAO,iBAAiB,QAAQ;EAAE,GAAG;EAAS,YAAY;EAAO,CAAC"}
package/dist/format.d.cts CHANGED
@@ -1,8 +1,9 @@
1
- import { FormatDisplayOptions, Hotkey, ParsedHotkey, RegisterableHotkey } from "./hotkey.cjs";
1
+ import { Hotkey, ParsedHotkey, RegisterableHotkey } from "./hotkey.types.cjs";
2
2
 
3
3
  //#region src/format.d.ts
4
4
  /**
5
- * Converts a hotkey sequence array to a display string.
5
+ * Joins stored sequence steps with spaces, preserving physical code tokens.
6
+ * For user-facing labels, call formatForDisplay on each step instead.
6
7
  *
7
8
  * @param sequence - Array of hotkey strings that form the sequence
8
9
  * @returns A space-separated string (e.g. ['G','G'] → 'G G')
@@ -27,16 +28,21 @@ declare function formatHotkeySequence(sequence: Array<Hotkey>): string;
27
28
  * ```
28
29
  */
29
30
  declare function formatHotkey(parsed: ParsedHotkey): string;
31
+ type DisplayHotkey = RegisterableHotkey | ParsedHotkey | (string & {});
30
32
  /**
31
33
  * Formats a hotkey for display in a user interface.
32
34
  *
33
35
  * On macOS, uses symbols (⌘⇧S) in the same modifier order as {@link normalizeHotkeyFromParsed}.
34
36
  * On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.
35
37
  * The separator can be customized with `separatorToken`.
38
+ * Physical codes use conventional display labels: `[KeyS]` becomes `S` and
39
+ * `[Digit2]` becomes `2`. These labels do not infer the active keyboard layout
40
+ * or change matching. Supply a resolved `layoutMap` for layout-aware labels;
41
+ * `keyLabels` overrides both layout entries and fallback labels.
36
42
  *
37
- * @param hotkey - The hotkey string or ParsedHotkey to format
43
+ * @param hotkey - A logical or physical string, raw binding, or ParsedHotkey
38
44
  * @param options - Formatting options
39
- * @returns A formatted string suitable for display
45
+ * @returns Display text, or individual key labels when parts is true
40
46
  *
41
47
  * @example
42
48
  * ```ts
@@ -50,11 +56,44 @@ declare function formatHotkey(parsed: ParsedHotkey): string;
50
56
  * // Returns: 'Esc' (on all platforms)
51
57
  * ```
52
58
  */
53
- declare function formatForDisplay(hotkey: RegisterableHotkey | (string & {}), options?: FormatDisplayOptions): string;
59
+ declare function formatForDisplay(hotkey: DisplayHotkey, options: FormatDisplayOptions & {
60
+ parts: true;
61
+ }): Array<string>;
62
+ declare function formatForDisplay(hotkey: DisplayHotkey, options?: FormatDisplayOptions & {
63
+ parts?: false;
64
+ }): string;
65
+ declare function formatForDisplay(hotkey: DisplayHotkey, options: FormatDisplayOptions): string | Array<string>;
54
66
  /**
55
67
  * @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.
56
68
  */
57
- declare function formatWithLabels(hotkey: RegisterableHotkey, options?: Omit<FormatDisplayOptions, 'useSymbols'>): string;
69
+ declare function formatWithLabels(hotkey: RegisterableHotkey, options?: Omit<FormatDisplayOptions, 'useSymbols' | 'parts'>): string;
70
+ /**
71
+ * Options for formatting hotkeys for display.
72
+ */
73
+ interface FormatDisplayOptions {
74
+ /** The target platform. Defaults to auto-detection. */
75
+ platform?: 'mac' | 'windows' | 'linux';
76
+ /** Whether to use symbols for the display. Defaults to true. */
77
+ useSymbols?: boolean | {
78
+ modifiers?: boolean;
79
+ keys?: boolean;
80
+ };
81
+ /** Return individual key labels instead of a joined string. Default: false. */
82
+ parts?: boolean;
83
+ /**
84
+ * An already-resolved code-to-key map, such as KeyboardLayoutMap or Map.
85
+ * Used only for physical bindings. Mapped keys receive normal display formatting;
86
+ * missing or empty entries use conventional fallback labels. The caller owns
87
+ * loading and refreshing the map; this formatter never calls browser APIs.
88
+ */
89
+ layoutMap?: {
90
+ get: (code: string) => string | undefined;
91
+ };
92
+ /** Final display overrides for logical keys or physical codes; take precedence over layoutMap. Never changes matching. */
93
+ keyLabels?: Readonly<Record<string, string>>;
94
+ /** Override the separator between display tokens. Defaults to platform-specific formatting when null/undefined. */
95
+ separatorToken?: string | null;
96
+ }
58
97
  //#endregion
59
- export { formatForDisplay, formatHotkey, formatHotkeySequence, formatWithLabels };
98
+ export { DisplayHotkey, FormatDisplayOptions, formatForDisplay, formatHotkey, formatHotkeySequence, formatWithLabels };
60
99
  //# sourceMappingURL=format.d.cts.map
package/dist/format.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { FormatDisplayOptions, Hotkey, ParsedHotkey, RegisterableHotkey } from "./hotkey.js";
1
+ import { Hotkey, ParsedHotkey, RegisterableHotkey } from "./hotkey.types.js";
2
2
 
3
3
  //#region src/format.d.ts
4
4
  /**
5
- * Converts a hotkey sequence array to a display string.
5
+ * Joins stored sequence steps with spaces, preserving physical code tokens.
6
+ * For user-facing labels, call formatForDisplay on each step instead.
6
7
  *
7
8
  * @param sequence - Array of hotkey strings that form the sequence
8
9
  * @returns A space-separated string (e.g. ['G','G'] → 'G G')
@@ -27,16 +28,21 @@ declare function formatHotkeySequence(sequence: Array<Hotkey>): string;
27
28
  * ```
28
29
  */
29
30
  declare function formatHotkey(parsed: ParsedHotkey): string;
31
+ type DisplayHotkey = RegisterableHotkey | ParsedHotkey | (string & {});
30
32
  /**
31
33
  * Formats a hotkey for display in a user interface.
32
34
  *
33
35
  * On macOS, uses symbols (⌘⇧S) in the same modifier order as {@link normalizeHotkeyFromParsed}.
34
36
  * On Windows/Linux, uses text (Ctrl+Shift+S) with `+` separators.
35
37
  * The separator can be customized with `separatorToken`.
38
+ * Physical codes use conventional display labels: `[KeyS]` becomes `S` and
39
+ * `[Digit2]` becomes `2`. These labels do not infer the active keyboard layout
40
+ * or change matching. Supply a resolved `layoutMap` for layout-aware labels;
41
+ * `keyLabels` overrides both layout entries and fallback labels.
36
42
  *
37
- * @param hotkey - The hotkey string or ParsedHotkey to format
43
+ * @param hotkey - A logical or physical string, raw binding, or ParsedHotkey
38
44
  * @param options - Formatting options
39
- * @returns A formatted string suitable for display
45
+ * @returns Display text, or individual key labels when parts is true
40
46
  *
41
47
  * @example
42
48
  * ```ts
@@ -50,11 +56,44 @@ declare function formatHotkey(parsed: ParsedHotkey): string;
50
56
  * // Returns: 'Esc' (on all platforms)
51
57
  * ```
52
58
  */
53
- declare function formatForDisplay(hotkey: RegisterableHotkey | (string & {}), options?: FormatDisplayOptions): string;
59
+ declare function formatForDisplay(hotkey: DisplayHotkey, options: FormatDisplayOptions & {
60
+ parts: true;
61
+ }): Array<string>;
62
+ declare function formatForDisplay(hotkey: DisplayHotkey, options?: FormatDisplayOptions & {
63
+ parts?: false;
64
+ }): string;
65
+ declare function formatForDisplay(hotkey: DisplayHotkey, options: FormatDisplayOptions): string | Array<string>;
54
66
  /**
55
67
  * @deprecated Use {@link formatForDisplay} instead with `useSymbols: false` option.
56
68
  */
57
- declare function formatWithLabels(hotkey: RegisterableHotkey, options?: Omit<FormatDisplayOptions, 'useSymbols'>): string;
69
+ declare function formatWithLabels(hotkey: RegisterableHotkey, options?: Omit<FormatDisplayOptions, 'useSymbols' | 'parts'>): string;
70
+ /**
71
+ * Options for formatting hotkeys for display.
72
+ */
73
+ interface FormatDisplayOptions {
74
+ /** The target platform. Defaults to auto-detection. */
75
+ platform?: 'mac' | 'windows' | 'linux';
76
+ /** Whether to use symbols for the display. Defaults to true. */
77
+ useSymbols?: boolean | {
78
+ modifiers?: boolean;
79
+ keys?: boolean;
80
+ };
81
+ /** Return individual key labels instead of a joined string. Default: false. */
82
+ parts?: boolean;
83
+ /**
84
+ * An already-resolved code-to-key map, such as KeyboardLayoutMap or Map.
85
+ * Used only for physical bindings. Mapped keys receive normal display formatting;
86
+ * missing or empty entries use conventional fallback labels. The caller owns
87
+ * loading and refreshing the map; this formatter never calls browser APIs.
88
+ */
89
+ layoutMap?: {
90
+ get: (code: string) => string | undefined;
91
+ };
92
+ /** Final display overrides for logical keys or physical codes; take precedence over layoutMap. Never changes matching. */
93
+ keyLabels?: Readonly<Record<string, string>>;
94
+ /** Override the separator between display tokens. Defaults to platform-specific formatting when null/undefined. */
95
+ separatorToken?: string | null;
96
+ }
58
97
  //#endregion
59
- export { formatForDisplay, formatHotkey, formatHotkeySequence, formatWithLabels };
98
+ export { DisplayHotkey, FormatDisplayOptions, formatForDisplay, formatHotkey, formatHotkeySequence, formatWithLabels };
60
99
  //# sourceMappingURL=format.d.ts.map