@tanstack/hotkeys 0.9.0 → 0.10.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 (148) hide show
  1. package/dist/_event-target.js +1 -2
  2. package/dist/_keyboard-event.js +1 -2
  3. package/dist/_match.js +1 -2
  4. package/dist/_named-keys.d.ts +3 -5
  5. package/dist/_named-keys.js +1 -2
  6. package/dist/_recorder-chord.js +1 -2
  7. package/dist/_recording-guard.js +1 -2
  8. package/dist/_registration.js +1 -2
  9. package/dist/conflicts.d.ts +4 -7
  10. package/dist/conflicts.js +1 -2
  11. package/dist/constants.d.ts +14 -17
  12. package/dist/constants.js +8 -9
  13. package/dist/display-labels.d.ts +7 -10
  14. package/dist/display-labels.js +1 -2
  15. package/dist/format.d.ts +9 -12
  16. package/dist/format.js +9 -7
  17. package/dist/hint.d.ts +3 -6
  18. package/dist/hint.js +1 -2
  19. package/dist/hotkey-manager.d.ts +8 -10
  20. package/dist/hotkey-manager.js +21 -3
  21. package/dist/hotkey-recorder.d.ts +4 -7
  22. package/dist/hotkey-recorder.js +9 -6
  23. package/dist/hotkey-sequence-recorder.d.ts +5 -8
  24. package/dist/hotkey-sequence-recorder.js +6 -7
  25. package/dist/hotkey.types.d.ts +15 -18
  26. package/dist/key-state-tracker.d.ts +4 -7
  27. package/dist/key-state-tracker.js +6 -3
  28. package/dist/key.types.d.ts +17 -20
  29. package/dist/match.d.ts +8 -11
  30. package/dist/match.js +1 -2
  31. package/dist/parse.d.ts +11 -14
  32. package/dist/parse.js +5 -4
  33. package/dist/platform.d.ts +3 -6
  34. package/dist/platform.js +1 -2
  35. package/dist/recorder-options.d.ts +6 -9
  36. package/dist/sequence-manager.d.ts +11 -14
  37. package/dist/sequence-manager.js +12 -7
  38. package/dist/validate.d.ts +5 -8
  39. package/dist/validate.js +1 -2
  40. package/package.json +8 -13
  41. package/dist/_event-target.cjs +0 -73
  42. package/dist/_event-target.cjs.map +0 -1
  43. package/dist/_event-target.js.map +0 -1
  44. package/dist/_keyboard-event.cjs +0 -83
  45. package/dist/_keyboard-event.cjs.map +0 -1
  46. package/dist/_keyboard-event.js.map +0 -1
  47. package/dist/_match.cjs +0 -49
  48. package/dist/_match.cjs.map +0 -1
  49. package/dist/_match.js.map +0 -1
  50. package/dist/_named-keys.cjs +0 -68
  51. package/dist/_named-keys.cjs.map +0 -1
  52. package/dist/_named-keys.d.cts +0 -8
  53. package/dist/_named-keys.js.map +0 -1
  54. package/dist/_recorder-chord.cjs +0 -44
  55. package/dist/_recorder-chord.cjs.map +0 -1
  56. package/dist/_recorder-chord.js.map +0 -1
  57. package/dist/_recording-guard.cjs +0 -59
  58. package/dist/_recording-guard.cjs.map +0 -1
  59. package/dist/_recording-guard.js.map +0 -1
  60. package/dist/_registration.cjs +0 -54
  61. package/dist/_registration.cjs.map +0 -1
  62. package/dist/_registration.js.map +0 -1
  63. package/dist/conflicts.cjs +0 -55
  64. package/dist/conflicts.cjs.map +0 -1
  65. package/dist/conflicts.d.cts +0 -39
  66. package/dist/conflicts.js.map +0 -1
  67. package/dist/constants.cjs +0 -410
  68. package/dist/constants.cjs.map +0 -1
  69. package/dist/constants.d.cts +0 -165
  70. package/dist/constants.js.map +0 -1
  71. package/dist/display-labels.cjs +0 -119
  72. package/dist/display-labels.cjs.map +0 -1
  73. package/dist/display-labels.d.cts +0 -93
  74. package/dist/display-labels.js.map +0 -1
  75. package/dist/format.cjs +0 -85
  76. package/dist/format.cjs.map +0 -1
  77. package/dist/format.d.cts +0 -99
  78. package/dist/format.js.map +0 -1
  79. package/dist/hint.cjs +0 -24
  80. package/dist/hint.cjs.map +0 -1
  81. package/dist/hint.d.cts +0 -23
  82. package/dist/hint.js.map +0 -1
  83. package/dist/hotkey-manager.cjs +0 -414
  84. package/dist/hotkey-manager.cjs.map +0 -1
  85. package/dist/hotkey-manager.d.cts +0 -234
  86. package/dist/hotkey-manager.js.map +0 -1
  87. package/dist/hotkey-recorder.cjs +0 -235
  88. package/dist/hotkey-recorder.cjs.map +0 -1
  89. package/dist/hotkey-recorder.d.cts +0 -119
  90. package/dist/hotkey-recorder.js.map +0 -1
  91. package/dist/hotkey-sequence-recorder.cjs +0 -255
  92. package/dist/hotkey-sequence-recorder.cjs.map +0 -1
  93. package/dist/hotkey-sequence-recorder.d.cts +0 -86
  94. package/dist/hotkey-sequence-recorder.js.map +0 -1
  95. package/dist/hotkey.types.d.cts +0 -236
  96. package/dist/index.cjs +0 -71
  97. package/dist/index.d.cts +0 -18
  98. package/dist/key-state-tracker.cjs +0 -197
  99. package/dist/key-state-tracker.cjs.map +0 -1
  100. package/dist/key-state-tracker.d.cts +0 -107
  101. package/dist/key-state-tracker.js.map +0 -1
  102. package/dist/key.types.d.cts +0 -82
  103. package/dist/match.cjs +0 -144
  104. package/dist/match.cjs.map +0 -1
  105. package/dist/match.d.cts +0 -101
  106. package/dist/match.js.map +0 -1
  107. package/dist/parse.cjs +0 -245
  108. package/dist/parse.cjs.map +0 -1
  109. package/dist/parse.d.cts +0 -134
  110. package/dist/parse.js.map +0 -1
  111. package/dist/platform.cjs +0 -55
  112. package/dist/platform.cjs.map +0 -1
  113. package/dist/platform.d.cts +0 -44
  114. package/dist/platform.js.map +0 -1
  115. package/dist/recorder-options.d.cts +0 -34
  116. package/dist/sequence-manager.cjs +0 -441
  117. package/dist/sequence-manager.cjs.map +0 -1
  118. package/dist/sequence-manager.d.cts +0 -172
  119. package/dist/sequence-manager.js.map +0 -1
  120. package/dist/validate.cjs +0 -112
  121. package/dist/validate.cjs.map +0 -1
  122. package/dist/validate.d.cts +0 -67
  123. package/dist/validate.js.map +0 -1
  124. package/src/_event-target.ts +0 -157
  125. package/src/_keyboard-event.ts +0 -101
  126. package/src/_match.ts +0 -96
  127. package/src/_named-keys.ts +0 -62
  128. package/src/_recorder-chord.ts +0 -76
  129. package/src/_recording-guard.ts +0 -63
  130. package/src/_registration.ts +0 -79
  131. package/src/conflicts.ts +0 -125
  132. package/src/constants.ts +0 -455
  133. package/src/display-labels.ts +0 -123
  134. package/src/format.ts +0 -201
  135. package/src/hint.ts +0 -42
  136. package/src/hotkey-manager.ts +0 -814
  137. package/src/hotkey-recorder.ts +0 -348
  138. package/src/hotkey-sequence-recorder.ts +0 -410
  139. package/src/hotkey.types.ts +0 -269
  140. package/src/index.ts +0 -17
  141. package/src/key-state-tracker.ts +0 -261
  142. package/src/key.types.ts +0 -268
  143. package/src/match.ts +0 -210
  144. package/src/parse.ts +0 -369
  145. package/src/platform.ts +0 -66
  146. package/src/recorder-options.ts +0 -34
  147. package/src/sequence-manager.ts +0 -769
  148. package/src/validate.ts +0 -179
@@ -1,14 +1,13 @@
1
1
  import { Hotkey, HotkeyCallback, ParsedHotkey } from "./hotkey.types.js";
2
2
  import { HotkeyOptions } from "./hotkey-manager.js";
3
3
  import { Store } from "@tanstack/store";
4
-
5
4
  //#region src/sequence-manager.d.ts
6
- type Target = HTMLElement | Document | Window;
5
+ export type Target = HTMLElement | Document | Window;
7
6
  /**
8
7
  * Options for hotkey sequence matching.
9
8
  * Extends HotkeyOptions but excludes requireReset (not applicable to sequences).
10
9
  */
11
- interface SequenceOptions extends Omit<HotkeyOptions, 'requireReset'> {
10
+ export interface SequenceOptions extends Omit<HotkeyOptions, 'requireReset'> {
12
11
  /** Timeout between keys in milliseconds. Default: 1000 */
13
12
  timeout?: number;
14
13
  }
@@ -28,17 +27,17 @@ interface SequenceOptions extends Omit<HotkeyOptions, 'requireReset'> {
28
27
  * const chainedShift: HotkeySequence = ['Shift+R', 'Shift+T']
29
28
  * ```
30
29
  */
31
- type HotkeySequence = Array<Hotkey>;
30
+ export type HotkeySequence = Array<Hotkey>;
32
31
  /**
33
32
  * Default timeout between keys in a sequence (in milliseconds).
34
33
  * Exported for consumers that display sequence state (e.g. devtools).
35
34
  */
36
- declare const DEFAULT_SEQUENCE_TIMEOUT = 1000;
35
+ export declare const DEFAULT_SEQUENCE_TIMEOUT = 1000;
37
36
  /**
38
37
  * View of a sequence registration for devtools display.
39
38
  * Progress fields reflect an in-progress match (between first key and completion or timeout).
40
39
  */
41
- interface SequenceRegistrationView {
40
+ export interface SequenceRegistrationView {
42
41
  id: string;
43
42
  sequence: HotkeySequence;
44
43
  options: SequenceOptions;
@@ -54,7 +53,7 @@ interface SequenceRegistrationView {
54
53
  /**
55
54
  * Internal representation of a sequence registration.
56
55
  */
57
- interface SequenceRegistration {
56
+ export interface SequenceRegistration {
58
57
  id: string;
59
58
  sequence: HotkeySequence;
60
59
  parsedSequence: Array<ParsedHotkey>;
@@ -79,14 +78,14 @@ interface SequenceRegistration {
79
78
  * handle.unregister()
80
79
  * ```
81
80
  */
82
- interface SequenceRegistrationHandle {
81
+ export interface SequenceRegistrationHandle {
83
82
  readonly id: string;
84
83
  readonly isActive: boolean;
85
84
  callback: HotkeyCallback;
86
85
  setOptions: (options: Partial<SequenceOptions>) => void;
87
86
  unregister: () => void;
88
87
  }
89
- declare class SequenceManager {
88
+ export declare class SequenceManager {
90
89
  #private;
91
90
  /**
92
91
  * The TanStack Store containing sequence registration views for devtools.
@@ -136,7 +135,7 @@ declare class SequenceManager {
136
135
  * Gets the singleton SequenceManager instance.
137
136
  * Convenience function for accessing the manager.
138
137
  */
139
- declare function getSequenceManager(): SequenceManager;
138
+ export declare function getSequenceManager(): SequenceManager;
140
139
  /**
141
140
  * Creates a simple sequence matcher for one-off use.
142
141
  *
@@ -159,7 +158,7 @@ declare function getSequenceManager(): SequenceManager;
159
158
  * })
160
159
  * ```
161
160
  */
162
- declare function createSequenceMatcher(sequence: HotkeySequence, options?: {
161
+ export declare function createSequenceMatcher(sequence: HotkeySequence, options?: {
163
162
  timeout?: number;
164
163
  platform?: 'mac' | 'windows' | 'linux';
165
164
  }): {
@@ -167,6 +166,4 @@ declare function createSequenceMatcher(sequence: HotkeySequence, options?: {
167
166
  reset: () => void;
168
167
  getProgress: () => number;
169
168
  };
170
- //#endregion
171
- export { DEFAULT_SEQUENCE_TIMEOUT, HotkeySequence, SequenceManager, SequenceOptions, SequenceRegistration, SequenceRegistrationHandle, SequenceRegistrationView, Target, createSequenceMatcher, getSequenceManager };
172
- //# sourceMappingURL=sequence-manager.d.ts.map
169
+ //#endregion
@@ -67,12 +67,16 @@ function toRegistrationView(reg) {
67
67
  }
68
68
  var SequenceManager = class SequenceManager {
69
69
  static #instance = null;
70
+ /**
71
+ * The TanStack Store containing sequence registration views for devtools.
72
+ * Subscribe to this to observe registration changes.
73
+ */
74
+ registrations = new Store(/* @__PURE__ */ new Map());
70
75
  #registrations = /* @__PURE__ */ new Map();
71
76
  #targetListeners = /* @__PURE__ */ new Map();
72
77
  #targetRegistrations = /* @__PURE__ */ new Map();
73
78
  #platform;
74
79
  constructor() {
75
- this.registrations = new Store(/* @__PURE__ */ new Map());
76
80
  this.#platform = detectPlatform();
77
81
  }
78
82
  /**
@@ -417,10 +421,12 @@ function createSequenceMatcher(sequence, options = {}) {
417
421
  currentIndex = 0;
418
422
  return true;
419
423
  }
420
- } else if (currentIndex > 0) if (matchesKeyboardEvent(event, parsedSequence[0], platform)) {
421
- currentIndex = 1;
422
- lastKeyTime = now;
423
- } else currentIndex = 0;
424
+ } else if (currentIndex > 0) {
425
+ if (matchesKeyboardEvent(event, parsedSequence[0], platform)) {
426
+ currentIndex = 1;
427
+ lastKeyTime = now;
428
+ } else currentIndex = 0;
429
+ }
424
430
  return false;
425
431
  },
426
432
  reset() {
@@ -434,5 +440,4 @@ function createSequenceMatcher(sequence, options = {}) {
434
440
  }
435
441
 
436
442
  //#endregion
437
- export { DEFAULT_SEQUENCE_TIMEOUT, SequenceManager, createSequenceMatcher, getSequenceManager };
438
- //# sourceMappingURL=sequence-manager.js.map
443
+ export { DEFAULT_SEQUENCE_TIMEOUT, SequenceManager, createSequenceMatcher, getSequenceManager };
@@ -1,5 +1,4 @@
1
1
  import { Hotkey } from "./hotkey.types.js";
2
-
3
2
  //#region src/validate.d.ts
4
3
  /**
5
4
  * Validates a hotkey string and returns any warnings or errors.
@@ -21,7 +20,7 @@ import { Hotkey } from "./hotkey.types.js";
21
20
  * // { valid: false, warnings: [], errors: ['Hotkey cannot be empty'] }
22
21
  * ```
23
22
  */
24
- declare function validateHotkey(hotkey: Hotkey | (string & {})): ValidationResult;
23
+ export declare function validateHotkey(hotkey: Hotkey | (string & {})): ValidationResult;
25
24
  /**
26
25
  * Validates a hotkey and throws an error if invalid.
27
26
  * Useful for development-time validation.
@@ -35,7 +34,7 @@ declare function validateHotkey(hotkey: Hotkey | (string & {})): ValidationResul
35
34
  * assertValidHotkey('') // Throws Error: Invalid hotkey: Hotkey cannot be empty
36
35
  * ```
37
36
  */
38
- declare function assertValidHotkey(hotkey: Hotkey | (string & {})): void;
37
+ export declare function assertValidHotkey(hotkey: Hotkey | (string & {})): void;
39
38
  /**
40
39
  * Validates a hotkey and logs warnings to the console.
41
40
  * Useful for development-time feedback.
@@ -50,11 +49,11 @@ declare function assertValidHotkey(hotkey: Hotkey | (string & {})): void;
50
49
  * // Returns: true
51
50
  * ```
52
51
  */
53
- declare function checkHotkey(hotkey: Hotkey | (string & {})): boolean;
52
+ export declare function checkHotkey(hotkey: Hotkey | (string & {})): boolean;
54
53
  /**
55
54
  * Result of validating a hotkey string.
56
55
  */
57
- interface ValidationResult {
56
+ export interface ValidationResult {
58
57
  /** Whether the hotkey is valid (can still have warnings) */
59
58
  valid: boolean;
60
59
  /** Warning messages about potential issues */
@@ -62,6 +61,4 @@ interface ValidationResult {
62
61
  /** Error messages about invalid syntax */
63
62
  errors: Array<string>;
64
63
  }
65
- //#endregion
66
- export { ValidationResult, assertValidHotkey, checkHotkey, validateHotkey };
67
- //# sourceMappingURL=validate.d.ts.map
64
+ //#endregion
package/dist/validate.js CHANGED
@@ -106,5 +106,4 @@ function checkHotkey(hotkey) {
106
106
  }
107
107
 
108
108
  //#endregion
109
- export { assertValidHotkey, checkHotkey, validateHotkey };
110
- //# sourceMappingURL=validate.js.map
109
+ export { assertValidHotkey, checkHotkey, validateHotkey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/hotkeys",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Type-safe, framework-agnostic keyboard hotkey management for the browser",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -24,26 +24,20 @@
24
24
  "typescript"
25
25
  ],
26
26
  "type": "module",
27
- "main": "./dist/index.cjs",
28
- "module": "./dist/index.js",
29
- "types": "./dist/index.d.cts",
27
+ "types": "./dist/index.d.ts",
30
28
  "exports": {
31
- ".": {
32
- "import": "./dist/index.js",
33
- "require": "./dist/index.cjs"
34
- },
29
+ ".": "./dist/index.js",
35
30
  "./package.json": "./package.json"
36
31
  },
37
32
  "sideEffects": false,
38
33
  "engines": {
39
- "node": ">=18"
34
+ "node": ">=20"
40
35
  },
41
36
  "files": [
42
- "dist/",
43
- "src"
37
+ "dist"
44
38
  ],
45
39
  "dependencies": {
46
- "@tanstack/store": "^0.11.0"
40
+ "@tanstack/store": "^0.11.1"
47
41
  },
48
42
  "scripts": {
49
43
  "clean": "premove ./build ./dist",
@@ -53,6 +47,7 @@
53
47
  "test:lib": "vitest",
54
48
  "test:lib:dev": "pnpm test:lib --watch",
55
49
  "test:types": "tsc",
56
- "build": "tsdown"
50
+ "build": "tsdown",
51
+ "test:build": "publint --strict && node ../../scripts/verify-package.ts"
57
52
  }
58
53
  }
@@ -1,73 +0,0 @@
1
-
2
- //#region src/_event-target.ts
3
- /**
4
- * Checks if an element is an input-like element that should be ignored for hotkeys.
5
- *
6
- * This includes:
7
- * - HTMLInputElement (all input types except button, submit, reset)
8
- * - HTMLTextAreaElement
9
- * - HTMLSelectElement
10
- * - Elements with contentEditable enabled
11
- *
12
- * Button-type inputs (button, submit, reset) are excluded so hotkeys like
13
- * Mod+S and Escape fire when the user has tabbed to a form button.
14
- */
15
- function isInputElement(element) {
16
- if (!element) return false;
17
- if (element instanceof HTMLInputElement) {
18
- const type = element.type.toLowerCase();
19
- if (type === "button" || type === "submit" || type === "reset") return false;
20
- return true;
21
- }
22
- if (element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) return true;
23
- if (element instanceof HTMLElement && element.isContentEditable) return true;
24
- return false;
25
- }
26
- /**
27
- * Returns the focused element for the document associated with where hotkey
28
- * listeners are attached (listener root). Use this instead of the global
29
- * `document.activeElement` so registrations scoped to an iframe (or another
30
- * document) read focus from the correct tree.
31
- */
32
- function getActiveElementForListenerTarget(target) {
33
- if (typeof document === "undefined") return null;
34
- if (typeof Document !== "undefined" && target instanceof Document || typeof Node !== "undefined" && target.nodeType === Node.DOCUMENT_NODE) return target.activeElement;
35
- if (typeof HTMLElement !== "undefined" && target instanceof HTMLElement) return target.ownerDocument.activeElement ?? null;
36
- return target.document.activeElement ?? null;
37
- }
38
- /**
39
- * Returns whether an event should be ignored because it originated from an
40
- * input-like element other than the registration target.
41
- *
42
- * This checks:
43
- * - the currently focused element for the listener target
44
- * - the event's composed path (for shadow DOM)
45
- * - the event target as a final fallback
46
- */
47
- function shouldIgnoreInputEvent(event, listenerTarget, registrationTarget) {
48
- const focused = getActiveElementForListenerTarget(listenerTarget);
49
- if (focused && isInputElement(focused) && focused !== registrationTarget) return true;
50
- if (event.composedPath().some((element) => isInputElement(element) && element !== registrationTarget)) return true;
51
- return isInputElement(event.target) && event.target !== registrationTarget;
52
- }
53
- /**
54
- * Checks if an event is for the given target (originated from or bubbled to it).
55
- *
56
- * For document/window targets, also accepts document.documentElement as currentTarget
57
- * to handle Brave and other browsers where currentTarget may be documentElement
58
- * instead of document when listeners are attached to document.
59
- */
60
- function isEventForTarget(event, target) {
61
- if (target === document || target === window) return event.currentTarget === target || event.currentTarget === document.documentElement;
62
- if (target === window) return event.currentTarget === window || event.currentTarget === document || event.currentTarget === document.documentElement;
63
- if (target instanceof HTMLElement) {
64
- if (event.currentTarget === target) return true;
65
- if (event.target instanceof Node && target.contains(event.target)) return true;
66
- }
67
- return false;
68
- }
69
-
70
- //#endregion
71
- exports.isEventForTarget = isEventForTarget;
72
- exports.shouldIgnoreInputEvent = shouldIgnoreInputEvent;
73
- //# sourceMappingURL=_event-target.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_event-target.cjs","names":[],"sources":["../src/_event-target.ts"],"sourcesContent":["/**\n * Checks if an element is an input-like element that should be ignored for hotkeys.\n *\n * This includes:\n * - HTMLInputElement (all input types except button, submit, reset)\n * - HTMLTextAreaElement\n * - HTMLSelectElement\n * - Elements with contentEditable enabled\n *\n * Button-type inputs (button, submit, reset) are excluded so hotkeys like\n * Mod+S and Escape fire when the user has tabbed to a form button.\n */\nexport function isInputElement(element: EventTarget | null): boolean {\n if (!element) {\n return false\n }\n\n if (element instanceof HTMLInputElement) {\n const type = element.type.toLowerCase()\n if (type === 'button' || type === 'submit' || type === 'reset') {\n return false\n }\n return true\n }\n\n if (\n element instanceof HTMLTextAreaElement ||\n element instanceof HTMLSelectElement\n ) {\n return true\n }\n\n // Check for contenteditable elements (includes \"true\", \"\", \"plaintext-only\",\n // and inherited contenteditable from ancestor elements)\n if (element instanceof HTMLElement && element.isContentEditable) {\n return true\n }\n\n return false\n}\n\n/**\n * Returns the focused element for the document associated with where hotkey\n * listeners are attached (listener root). Use this instead of the global\n * `document.activeElement` so registrations scoped to an iframe (or another\n * document) read focus from the correct tree.\n */\nexport function getActiveElementForListenerTarget(\n target: HTMLElement | Document | Window,\n): Element | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n // Document first (nodeType covers environments where `document instanceof Document` is false)\n if (\n (typeof Document !== 'undefined' && target instanceof Document) ||\n (typeof Node !== 'undefined' &&\n (target as Node).nodeType === Node.DOCUMENT_NODE)\n ) {\n return (target as Document).activeElement\n }\n\n if (typeof HTMLElement !== 'undefined' && target instanceof HTMLElement) {\n return target.ownerDocument.activeElement ?? null\n }\n\n // Window (global or iframe): avoid relying on `instanceof Window` alone (test DOM quirks)\n return (target as Window).document.activeElement ?? null\n}\n\n/**\n * Returns whether an event should be ignored because it originated from an\n * input-like element other than the registration target.\n *\n * This checks:\n * - the currently focused element for the listener target\n * - the event's composed path (for shadow DOM)\n * - the event target as a final fallback\n */\nexport function shouldIgnoreInputEvent(\n event: KeyboardEvent,\n listenerTarget: HTMLElement | Document | Window,\n registrationTarget: HTMLElement | Document | Window,\n): boolean {\n const focused = getActiveElementForListenerTarget(listenerTarget)\n if (focused && isInputElement(focused) && focused !== registrationTarget) {\n return true\n }\n\n if (\n event\n .composedPath()\n .some(\n (element) => isInputElement(element) && element !== registrationTarget,\n )\n ) {\n return true\n }\n\n return isInputElement(event.target) && event.target !== registrationTarget\n}\n\n/**\n * Checks if an event is for the given target (originated from or bubbled to it).\n *\n * For document/window targets, also accepts document.documentElement as currentTarget\n * to handle Brave and other browsers where currentTarget may be documentElement\n * instead of document when listeners are attached to document.\n */\nexport function isEventForTarget(\n event: KeyboardEvent,\n target: HTMLElement | Document | Window,\n): boolean {\n // For Document and Window, verify that our handler was indeed called for this target.\n //\n // Browser compatibility note:\n // Per the DOM spec, event.currentTarget should equal the element the listener was\n // attached to. However, some Chromium-based browsers (notably Brave) exhibit\n // non-standard behavior where event.currentTarget is set to document.documentElement\n // (<html>) instead of document when a listener is attached to document.\n // This may be related to privacy/fingerprinting protections.\n //\n // To ensure cross-browser compatibility, we accept both the expected target\n // and document.documentElement as valid currentTarget values.\n // See: https://dom.spec.whatwg.org/#dom-event-currenttarget\n if (target === document || target === window) {\n return (\n event.currentTarget === target ||\n event.currentTarget === document.documentElement\n )\n }\n\n // For Window, accept window, document, or document.documentElement (browser quirks)\n if (target === window) {\n return (\n event.currentTarget === window ||\n event.currentTarget === document ||\n event.currentTarget === document.documentElement\n )\n }\n\n // For HTMLElement, check if event originated from or bubbled to the element\n if (target instanceof HTMLElement) {\n // Check if the event's currentTarget is the target (capturing/bubbling)\n if (event.currentTarget === target) {\n return true\n }\n\n // Check if the event's target is a descendant of our target\n if (event.target instanceof Node && target.contains(event.target)) {\n return true\n }\n }\n\n return false\n}\n"],"mappings":";;;;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAsC;AACnE,KAAI,CAAC,QACH,QAAO;AAGT,KAAI,mBAAmB,kBAAkB;EACvC,MAAM,OAAO,QAAQ,KAAK,aAAa;AACvC,MAAI,SAAS,YAAY,SAAS,YAAY,SAAS,QACrD,QAAO;AAET,SAAO;;AAGT,KACE,mBAAmB,uBACnB,mBAAmB,kBAEnB,QAAO;AAKT,KAAI,mBAAmB,eAAe,QAAQ,kBAC5C,QAAO;AAGT,QAAO;;;;;;;;AAST,SAAgB,kCACd,QACgB;AAChB,KAAI,OAAO,aAAa,YACtB,QAAO;AAIT,KACG,OAAO,aAAa,eAAe,kBAAkB,YACrD,OAAO,SAAS,eACd,OAAgB,aAAa,KAAK,cAErC,QAAQ,OAAoB;AAG9B,KAAI,OAAO,gBAAgB,eAAe,kBAAkB,YAC1D,QAAO,OAAO,cAAc,iBAAiB;AAI/C,QAAQ,OAAkB,SAAS,iBAAiB;;;;;;;;;;;AAYtD,SAAgB,uBACd,OACA,gBACA,oBACS;CACT,MAAM,UAAU,kCAAkC,eAAe;AACjE,KAAI,WAAW,eAAe,QAAQ,IAAI,YAAY,mBACpD,QAAO;AAGT,KACE,MACG,cAAc,CACd,MACE,YAAY,eAAe,QAAQ,IAAI,YAAY,mBACrD,CAEH,QAAO;AAGT,QAAO,eAAe,MAAM,OAAO,IAAI,MAAM,WAAW;;;;;;;;;AAU1D,SAAgB,iBACd,OACA,QACS;AAaT,KAAI,WAAW,YAAY,WAAW,OACpC,QACE,MAAM,kBAAkB,UACxB,MAAM,kBAAkB,SAAS;AAKrC,KAAI,WAAW,OACb,QACE,MAAM,kBAAkB,UACxB,MAAM,kBAAkB,YACxB,MAAM,kBAAkB,SAAS;AAKrC,KAAI,kBAAkB,aAAa;AAEjC,MAAI,MAAM,kBAAkB,OAC1B,QAAO;AAIT,MAAI,MAAM,kBAAkB,QAAQ,OAAO,SAAS,MAAM,OAAO,CAC/D,QAAO;;AAIX,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_event-target.js","names":[],"sources":["../src/_event-target.ts"],"sourcesContent":["/**\n * Checks if an element is an input-like element that should be ignored for hotkeys.\n *\n * This includes:\n * - HTMLInputElement (all input types except button, submit, reset)\n * - HTMLTextAreaElement\n * - HTMLSelectElement\n * - Elements with contentEditable enabled\n *\n * Button-type inputs (button, submit, reset) are excluded so hotkeys like\n * Mod+S and Escape fire when the user has tabbed to a form button.\n */\nexport function isInputElement(element: EventTarget | null): boolean {\n if (!element) {\n return false\n }\n\n if (element instanceof HTMLInputElement) {\n const type = element.type.toLowerCase()\n if (type === 'button' || type === 'submit' || type === 'reset') {\n return false\n }\n return true\n }\n\n if (\n element instanceof HTMLTextAreaElement ||\n element instanceof HTMLSelectElement\n ) {\n return true\n }\n\n // Check for contenteditable elements (includes \"true\", \"\", \"plaintext-only\",\n // and inherited contenteditable from ancestor elements)\n if (element instanceof HTMLElement && element.isContentEditable) {\n return true\n }\n\n return false\n}\n\n/**\n * Returns the focused element for the document associated with where hotkey\n * listeners are attached (listener root). Use this instead of the global\n * `document.activeElement` so registrations scoped to an iframe (or another\n * document) read focus from the correct tree.\n */\nexport function getActiveElementForListenerTarget(\n target: HTMLElement | Document | Window,\n): Element | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n // Document first (nodeType covers environments where `document instanceof Document` is false)\n if (\n (typeof Document !== 'undefined' && target instanceof Document) ||\n (typeof Node !== 'undefined' &&\n (target as Node).nodeType === Node.DOCUMENT_NODE)\n ) {\n return (target as Document).activeElement\n }\n\n if (typeof HTMLElement !== 'undefined' && target instanceof HTMLElement) {\n return target.ownerDocument.activeElement ?? null\n }\n\n // Window (global or iframe): avoid relying on `instanceof Window` alone (test DOM quirks)\n return (target as Window).document.activeElement ?? null\n}\n\n/**\n * Returns whether an event should be ignored because it originated from an\n * input-like element other than the registration target.\n *\n * This checks:\n * - the currently focused element for the listener target\n * - the event's composed path (for shadow DOM)\n * - the event target as a final fallback\n */\nexport function shouldIgnoreInputEvent(\n event: KeyboardEvent,\n listenerTarget: HTMLElement | Document | Window,\n registrationTarget: HTMLElement | Document | Window,\n): boolean {\n const focused = getActiveElementForListenerTarget(listenerTarget)\n if (focused && isInputElement(focused) && focused !== registrationTarget) {\n return true\n }\n\n if (\n event\n .composedPath()\n .some(\n (element) => isInputElement(element) && element !== registrationTarget,\n )\n ) {\n return true\n }\n\n return isInputElement(event.target) && event.target !== registrationTarget\n}\n\n/**\n * Checks if an event is for the given target (originated from or bubbled to it).\n *\n * For document/window targets, also accepts document.documentElement as currentTarget\n * to handle Brave and other browsers where currentTarget may be documentElement\n * instead of document when listeners are attached to document.\n */\nexport function isEventForTarget(\n event: KeyboardEvent,\n target: HTMLElement | Document | Window,\n): boolean {\n // For Document and Window, verify that our handler was indeed called for this target.\n //\n // Browser compatibility note:\n // Per the DOM spec, event.currentTarget should equal the element the listener was\n // attached to. However, some Chromium-based browsers (notably Brave) exhibit\n // non-standard behavior where event.currentTarget is set to document.documentElement\n // (<html>) instead of document when a listener is attached to document.\n // This may be related to privacy/fingerprinting protections.\n //\n // To ensure cross-browser compatibility, we accept both the expected target\n // and document.documentElement as valid currentTarget values.\n // See: https://dom.spec.whatwg.org/#dom-event-currenttarget\n if (target === document || target === window) {\n return (\n event.currentTarget === target ||\n event.currentTarget === document.documentElement\n )\n }\n\n // For Window, accept window, document, or document.documentElement (browser quirks)\n if (target === window) {\n return (\n event.currentTarget === window ||\n event.currentTarget === document ||\n event.currentTarget === document.documentElement\n )\n }\n\n // For HTMLElement, check if event originated from or bubbled to the element\n if (target instanceof HTMLElement) {\n // Check if the event's currentTarget is the target (capturing/bubbling)\n if (event.currentTarget === target) {\n return true\n }\n\n // Check if the event's target is a descendant of our target\n if (event.target instanceof Node && target.contains(event.target)) {\n return true\n }\n }\n\n return false\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAsC;AACnE,KAAI,CAAC,QACH,QAAO;AAGT,KAAI,mBAAmB,kBAAkB;EACvC,MAAM,OAAO,QAAQ,KAAK,aAAa;AACvC,MAAI,SAAS,YAAY,SAAS,YAAY,SAAS,QACrD,QAAO;AAET,SAAO;;AAGT,KACE,mBAAmB,uBACnB,mBAAmB,kBAEnB,QAAO;AAKT,KAAI,mBAAmB,eAAe,QAAQ,kBAC5C,QAAO;AAGT,QAAO;;;;;;;;AAST,SAAgB,kCACd,QACgB;AAChB,KAAI,OAAO,aAAa,YACtB,QAAO;AAIT,KACG,OAAO,aAAa,eAAe,kBAAkB,YACrD,OAAO,SAAS,eACd,OAAgB,aAAa,KAAK,cAErC,QAAQ,OAAoB;AAG9B,KAAI,OAAO,gBAAgB,eAAe,kBAAkB,YAC1D,QAAO,OAAO,cAAc,iBAAiB;AAI/C,QAAQ,OAAkB,SAAS,iBAAiB;;;;;;;;;;;AAYtD,SAAgB,uBACd,OACA,gBACA,oBACS;CACT,MAAM,UAAU,kCAAkC,eAAe;AACjE,KAAI,WAAW,eAAe,QAAQ,IAAI,YAAY,mBACpD,QAAO;AAGT,KACE,MACG,cAAc,CACd,MACE,YAAY,eAAe,QAAQ,IAAI,YAAY,mBACrD,CAEH,QAAO;AAGT,QAAO,eAAe,MAAM,OAAO,IAAI,MAAM,WAAW;;;;;;;;;AAU1D,SAAgB,iBACd,OACA,QACS;AAaT,KAAI,WAAW,YAAY,WAAW,OACpC,QACE,MAAM,kBAAkB,UACxB,MAAM,kBAAkB,SAAS;AAKrC,KAAI,WAAW,OACb,QACE,MAAM,kBAAkB,UACxB,MAAM,kBAAkB,YACxB,MAAM,kBAAkB,SAAS;AAKrC,KAAI,kBAAkB,aAAa;AAEjC,MAAI,MAAM,kBAAkB,OAC1B,QAAO;AAIT,MAAI,MAAM,kBAAkB,QAAQ,OAAO,SAAS,MAAM,OAAO,CAC/D,QAAO;;AAIX,QAAO"}
@@ -1,83 +0,0 @@
1
- const require_constants = require('./constants.cjs');
2
-
3
- //#region src/_keyboard-event.ts
4
- /** Normalizes Unicode key names and modifier flags while retaining physical code and IME state. */
5
- function normalizeKeyboardEvent(event, platform) {
6
- let altGraph = false;
7
- try {
8
- altGraph = platform !== "mac" && typeof event.getModifierState === "function" && event.getModifierState("AltGraph");
9
- } catch {}
10
- const key = (event.key || "").normalize("NFC");
11
- return {
12
- key: require_constants.normalizeKeyName(key),
13
- code: event.code || "",
14
- ctrl: Boolean(event.ctrlKey),
15
- shift: Boolean(event.shiftKey),
16
- alt: Boolean(event.altKey),
17
- meta: Boolean(event.metaKey),
18
- altGraph,
19
- location: event.location,
20
- isComposing: Boolean(event.isComposing) || key === "Process" || key === "Unidentified"
21
- };
22
- }
23
- /**
24
- * Maps familiar positions to compatibility fallback keys for the logical matcher.
25
- * This assumes conventional positions, not the active layout; never use it to
26
- * turn recorded physical bindings into logical bindings or display labels.
27
- */
28
- function codeToLogicalKey(code) {
29
- if (/^Key[A-Z]$/i.test(code)) return code.slice(3).toUpperCase();
30
- if (/^Digit[0-9]$/i.test(code)) return code.slice(5);
31
- if (/^Numpad[0-9]$/i.test(code)) return code.slice(6);
32
- const punctuation = require_constants.PUNCTUATION_CODE_MAP[code];
33
- if (punctuation) return punctuation;
34
- return {
35
- NumpadAdd: "+",
36
- NumpadSubtract: "-",
37
- NumpadMultiply: "*",
38
- NumpadDivide: "/",
39
- NumpadDecimal: ".",
40
- NumpadEnter: "Enter",
41
- Space: "Space"
42
- }[code];
43
- }
44
- /** Tests for one Unicode code point, including characters represented by a surrogate pair. */
45
- function isPrintableKey(key) {
46
- return key !== "" && Array.from(key).length === 1;
47
- }
48
- /** Splits modifier tokens while retaining a trailing literal plus: `Control++` → `['Control', '+']`. */
49
- function splitHotkeyParts(hotkey) {
50
- if (!hotkey.endsWith("+")) return hotkey.split("+");
51
- const parts = hotkey.slice(0, -1).split("+");
52
- if (parts.at(-1) === "") parts.pop();
53
- parts.push("+");
54
- return parts;
55
- }
56
- /** Identifies ASCII letters whose layout-produced value takes precedence over positional fallbacks. */
57
- function isAsciiLetter(key) {
58
- return /^[A-Za-z]$/.test(key);
59
- }
60
- /** Identifies a single Latin-script character, including accented letters. */
61
- function isLatinLetter(key) {
62
- return /^\p{Script_Extensions=Latin}$/u.test(key);
63
- }
64
- /** Compares letters without case, preserving accents and avoiding expansions such as ß → SS. */
65
- function keysEqual(left, right) {
66
- if (/^\p{Letter}$/u.test(left) && /^\p{Letter}$/u.test(right)) return left.localeCompare(right, void 0, { sensitivity: "accent" }) === 0;
67
- return left === right;
68
- }
69
- /** Rejects reserved physical-token syntax in logical object fields while allowing Unicode characters. */
70
- function assertLogicalKey(key) {
71
- if (/^\[.*\]$/s.test(key.trim())) throw new Error("Logical key must not contain a bracketed physical code. Use the code field instead.");
72
- }
73
-
74
- //#endregion
75
- exports.assertLogicalKey = assertLogicalKey;
76
- exports.codeToLogicalKey = codeToLogicalKey;
77
- exports.isAsciiLetter = isAsciiLetter;
78
- exports.isLatinLetter = isLatinLetter;
79
- exports.isPrintableKey = isPrintableKey;
80
- exports.keysEqual = keysEqual;
81
- exports.normalizeKeyboardEvent = normalizeKeyboardEvent;
82
- exports.splitHotkeyParts = splitHotkeyParts;
83
- //# sourceMappingURL=_keyboard-event.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_keyboard-event.cjs","names":["normalizeKeyName","PUNCTUATION_CODE_MAP"],"sources":["../src/_keyboard-event.ts"],"sourcesContent":["import { PUNCTUATION_CODE_MAP, normalizeKeyName } from './constants'\nimport type { NormalizedKeyboardEvent } from './key.types'\n\n/** Normalizes Unicode key names and modifier flags while retaining physical code and IME state. */\nexport function normalizeKeyboardEvent(\n event: KeyboardEvent,\n platform?: 'mac' | 'windows' | 'linux',\n): NormalizedKeyboardEvent {\n let altGraph = false\n try {\n // WebKit reports AltGraph for Option on some macOS keyboard layouts. Option\n // remains a normal Alt shortcut modifier there, so only use this signal on\n // Windows/Linux where AltGraph synthesizes Control+Alt.\n altGraph =\n platform !== 'mac' &&\n typeof event.getModifierState === 'function' &&\n event.getModifierState('AltGraph')\n } catch {\n // Synthetic events and older browsers may not implement this reliably.\n }\n\n const key = (event.key || '').normalize('NFC')\n return {\n key: normalizeKeyName(key),\n code: event.code || '',\n ctrl: Boolean(event.ctrlKey),\n shift: Boolean(event.shiftKey),\n alt: Boolean(event.altKey),\n meta: Boolean(event.metaKey),\n altGraph,\n location: event.location,\n isComposing:\n Boolean(event.isComposing) || key === 'Process' || key === 'Unidentified',\n }\n}\n\n/**\n * Maps familiar positions to compatibility fallback keys for the logical matcher.\n * This assumes conventional positions, not the active layout; never use it to\n * turn recorded physical bindings into logical bindings or display labels.\n */\nexport function codeToLogicalKey(code: string): string | undefined {\n if (/^Key[A-Z]$/i.test(code)) return code.slice(3).toUpperCase()\n if (/^Digit[0-9]$/i.test(code)) return code.slice(5)\n if (/^Numpad[0-9]$/i.test(code)) return code.slice(6)\n\n const punctuation = PUNCTUATION_CODE_MAP[code]\n if (punctuation) return punctuation\n\n const named: Record<string, string> = {\n NumpadAdd: '+',\n NumpadSubtract: '-',\n NumpadMultiply: '*',\n NumpadDivide: '/',\n NumpadDecimal: '.',\n NumpadEnter: 'Enter',\n Space: 'Space',\n }\n return named[code]\n}\n\n/** Tests for one Unicode code point, including characters represented by a surrogate pair. */\nexport function isPrintableKey(key: string): boolean {\n return key !== '' && Array.from(key).length === 1\n}\n\n/** Splits modifier tokens while retaining a trailing literal plus: `Control++` → `['Control', '+']`. */\nexport function splitHotkeyParts(hotkey: string): Array<string> {\n if (!hotkey.endsWith('+')) return hotkey.split('+')\n const parts = hotkey.slice(0, -1).split('+')\n if (parts.at(-1) === '') parts.pop()\n parts.push('+')\n return parts\n}\n\n/** Identifies ASCII letters whose layout-produced value takes precedence over positional fallbacks. */\nexport function isAsciiLetter(key: string): boolean {\n return /^[A-Za-z]$/.test(key)\n}\n\n/** Identifies a single Latin-script character, including accented letters. */\nexport function isLatinLetter(key: string): boolean {\n return /^\\p{Script_Extensions=Latin}$/u.test(key)\n}\n\n/** Compares letters without case, preserving accents and avoiding expansions such as ß → SS. */\nexport function keysEqual(left: string, right: string): boolean {\n if (/^\\p{Letter}$/u.test(left) && /^\\p{Letter}$/u.test(right)) {\n return left.localeCompare(right, undefined, { sensitivity: 'accent' }) === 0\n }\n return left === right\n}\n\n/** Rejects reserved physical-token syntax in logical object fields while allowing Unicode characters. */\nexport function assertLogicalKey(key: string): void {\n if (/^\\[.*\\]$/s.test(key.trim())) {\n throw new Error(\n 'Logical key must not contain a bracketed physical code. Use the code field instead.',\n )\n }\n}\n"],"mappings":";;;;AAIA,SAAgB,uBACd,OACA,UACyB;CACzB,IAAI,WAAW;AACf,KAAI;AAIF,aACE,aAAa,SACb,OAAO,MAAM,qBAAqB,cAClC,MAAM,iBAAiB,WAAW;SAC9B;CAIR,MAAM,OAAO,MAAM,OAAO,IAAI,UAAU,MAAM;AAC9C,QAAO;EACL,KAAKA,mCAAiB,IAAI;EAC1B,MAAM,MAAM,QAAQ;EACpB,MAAM,QAAQ,MAAM,QAAQ;EAC5B,OAAO,QAAQ,MAAM,SAAS;EAC9B,KAAK,QAAQ,MAAM,OAAO;EAC1B,MAAM,QAAQ,MAAM,QAAQ;EAC5B;EACA,UAAU,MAAM;EAChB,aACE,QAAQ,MAAM,YAAY,IAAI,QAAQ,aAAa,QAAQ;EAC9D;;;;;;;AAQH,SAAgB,iBAAiB,MAAkC;AACjE,KAAI,cAAc,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE,CAAC,aAAa;AAChE,KAAI,gBAAgB,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE;AACpD,KAAI,iBAAiB,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE;CAErD,MAAM,cAAcC,uCAAqB;AACzC,KAAI,YAAa,QAAO;AAWxB,QATsC;EACpC,WAAW;EACX,gBAAgB;EAChB,gBAAgB;EAChB,cAAc;EACd,eAAe;EACf,aAAa;EACb,OAAO;EACR,CACY;;;AAIf,SAAgB,eAAe,KAAsB;AACnD,QAAO,QAAQ,MAAM,MAAM,KAAK,IAAI,CAAC,WAAW;;;AAIlD,SAAgB,iBAAiB,QAA+B;AAC9D,KAAI,CAAC,OAAO,SAAS,IAAI,CAAE,QAAO,OAAO,MAAM,IAAI;CACnD,MAAM,QAAQ,OAAO,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI;AAC5C,KAAI,MAAM,GAAG,GAAG,KAAK,GAAI,OAAM,KAAK;AACpC,OAAM,KAAK,IAAI;AACf,QAAO;;;AAIT,SAAgB,cAAc,KAAsB;AAClD,QAAO,aAAa,KAAK,IAAI;;;AAI/B,SAAgB,cAAc,KAAsB;AAClD,QAAO,iCAAiC,KAAK,IAAI;;;AAInD,SAAgB,UAAU,MAAc,OAAwB;AAC9D,KAAI,gBAAgB,KAAK,KAAK,IAAI,gBAAgB,KAAK,MAAM,CAC3D,QAAO,KAAK,cAAc,OAAO,QAAW,EAAE,aAAa,UAAU,CAAC,KAAK;AAE7E,QAAO,SAAS;;;AAIlB,SAAgB,iBAAiB,KAAmB;AAClD,KAAI,YAAY,KAAK,IAAI,MAAM,CAAC,CAC9B,OAAM,IAAI,MACR,sFACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_keyboard-event.js","names":[],"sources":["../src/_keyboard-event.ts"],"sourcesContent":["import { PUNCTUATION_CODE_MAP, normalizeKeyName } from './constants'\nimport type { NormalizedKeyboardEvent } from './key.types'\n\n/** Normalizes Unicode key names and modifier flags while retaining physical code and IME state. */\nexport function normalizeKeyboardEvent(\n event: KeyboardEvent,\n platform?: 'mac' | 'windows' | 'linux',\n): NormalizedKeyboardEvent {\n let altGraph = false\n try {\n // WebKit reports AltGraph for Option on some macOS keyboard layouts. Option\n // remains a normal Alt shortcut modifier there, so only use this signal on\n // Windows/Linux where AltGraph synthesizes Control+Alt.\n altGraph =\n platform !== 'mac' &&\n typeof event.getModifierState === 'function' &&\n event.getModifierState('AltGraph')\n } catch {\n // Synthetic events and older browsers may not implement this reliably.\n }\n\n const key = (event.key || '').normalize('NFC')\n return {\n key: normalizeKeyName(key),\n code: event.code || '',\n ctrl: Boolean(event.ctrlKey),\n shift: Boolean(event.shiftKey),\n alt: Boolean(event.altKey),\n meta: Boolean(event.metaKey),\n altGraph,\n location: event.location,\n isComposing:\n Boolean(event.isComposing) || key === 'Process' || key === 'Unidentified',\n }\n}\n\n/**\n * Maps familiar positions to compatibility fallback keys for the logical matcher.\n * This assumes conventional positions, not the active layout; never use it to\n * turn recorded physical bindings into logical bindings or display labels.\n */\nexport function codeToLogicalKey(code: string): string | undefined {\n if (/^Key[A-Z]$/i.test(code)) return code.slice(3).toUpperCase()\n if (/^Digit[0-9]$/i.test(code)) return code.slice(5)\n if (/^Numpad[0-9]$/i.test(code)) return code.slice(6)\n\n const punctuation = PUNCTUATION_CODE_MAP[code]\n if (punctuation) return punctuation\n\n const named: Record<string, string> = {\n NumpadAdd: '+',\n NumpadSubtract: '-',\n NumpadMultiply: '*',\n NumpadDivide: '/',\n NumpadDecimal: '.',\n NumpadEnter: 'Enter',\n Space: 'Space',\n }\n return named[code]\n}\n\n/** Tests for one Unicode code point, including characters represented by a surrogate pair. */\nexport function isPrintableKey(key: string): boolean {\n return key !== '' && Array.from(key).length === 1\n}\n\n/** Splits modifier tokens while retaining a trailing literal plus: `Control++` → `['Control', '+']`. */\nexport function splitHotkeyParts(hotkey: string): Array<string> {\n if (!hotkey.endsWith('+')) return hotkey.split('+')\n const parts = hotkey.slice(0, -1).split('+')\n if (parts.at(-1) === '') parts.pop()\n parts.push('+')\n return parts\n}\n\n/** Identifies ASCII letters whose layout-produced value takes precedence over positional fallbacks. */\nexport function isAsciiLetter(key: string): boolean {\n return /^[A-Za-z]$/.test(key)\n}\n\n/** Identifies a single Latin-script character, including accented letters. */\nexport function isLatinLetter(key: string): boolean {\n return /^\\p{Script_Extensions=Latin}$/u.test(key)\n}\n\n/** Compares letters without case, preserving accents and avoiding expansions such as ß → SS. */\nexport function keysEqual(left: string, right: string): boolean {\n if (/^\\p{Letter}$/u.test(left) && /^\\p{Letter}$/u.test(right)) {\n return left.localeCompare(right, undefined, { sensitivity: 'accent' }) === 0\n }\n return left === right\n}\n\n/** Rejects reserved physical-token syntax in logical object fields while allowing Unicode characters. */\nexport function assertLogicalKey(key: string): void {\n if (/^\\[.*\\]$/s.test(key.trim())) {\n throw new Error(\n 'Logical key must not contain a bracketed physical code. Use the code field instead.',\n )\n }\n}\n"],"mappings":";;;;AAIA,SAAgB,uBACd,OACA,UACyB;CACzB,IAAI,WAAW;AACf,KAAI;AAIF,aACE,aAAa,SACb,OAAO,MAAM,qBAAqB,cAClC,MAAM,iBAAiB,WAAW;SAC9B;CAIR,MAAM,OAAO,MAAM,OAAO,IAAI,UAAU,MAAM;AAC9C,QAAO;EACL,KAAK,iBAAiB,IAAI;EAC1B,MAAM,MAAM,QAAQ;EACpB,MAAM,QAAQ,MAAM,QAAQ;EAC5B,OAAO,QAAQ,MAAM,SAAS;EAC9B,KAAK,QAAQ,MAAM,OAAO;EAC1B,MAAM,QAAQ,MAAM,QAAQ;EAC5B;EACA,UAAU,MAAM;EAChB,aACE,QAAQ,MAAM,YAAY,IAAI,QAAQ,aAAa,QAAQ;EAC9D;;;;;;;AAQH,SAAgB,iBAAiB,MAAkC;AACjE,KAAI,cAAc,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE,CAAC,aAAa;AAChE,KAAI,gBAAgB,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE;AACpD,KAAI,iBAAiB,KAAK,KAAK,CAAE,QAAO,KAAK,MAAM,EAAE;CAErD,MAAM,cAAc,qBAAqB;AACzC,KAAI,YAAa,QAAO;AAWxB,QATsC;EACpC,WAAW;EACX,gBAAgB;EAChB,gBAAgB;EAChB,cAAc;EACd,eAAe;EACf,aAAa;EACb,OAAO;EACR,CACY;;;AAIf,SAAgB,eAAe,KAAsB;AACnD,QAAO,QAAQ,MAAM,MAAM,KAAK,IAAI,CAAC,WAAW;;;AAIlD,SAAgB,iBAAiB,QAA+B;AAC9D,KAAI,CAAC,OAAO,SAAS,IAAI,CAAE,QAAO,OAAO,MAAM,IAAI;CACnD,MAAM,QAAQ,OAAO,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI;AAC5C,KAAI,MAAM,GAAG,GAAG,KAAK,GAAI,OAAM,KAAK;AACpC,OAAM,KAAK,IAAI;AACf,QAAO;;;AAIT,SAAgB,cAAc,KAAsB;AAClD,QAAO,aAAa,KAAK,IAAI;;;AAI/B,SAAgB,cAAc,KAAsB;AAClD,QAAO,iCAAiC,KAAK,IAAI;;;AAInD,SAAgB,UAAU,MAAc,OAAwB;AAC9D,KAAI,gBAAgB,KAAK,KAAK,IAAI,gBAAgB,KAAK,MAAM,CAC3D,QAAO,KAAK,cAAc,OAAO,QAAW,EAAE,aAAa,UAAU,CAAC,KAAK;AAE7E,QAAO,SAAS;;;AAIlB,SAAgB,iBAAiB,KAAmB;AAClD,KAAI,YAAY,KAAK,IAAI,MAAM,CAAC,CAC9B,OAAM,IAAI,MACR,sFACD"}
package/dist/_match.cjs DELETED
@@ -1,49 +0,0 @@
1
- const require_platform = require('./platform.cjs');
2
- const require__keyboard_event = require('./_keyboard-event.cjs');
3
- const require_parse = require('./parse.cjs');
4
-
5
- //#region src/_match.ts
6
- /** Matches an event and reports the winning candidate and release identity. */
7
- function matchKeyboardEvent(event, hotkey, platform = require_platform.detectPlatform()) {
8
- const parsed = typeof hotkey === "string" ? require_parse.parseHotkey(hotkey, platform) : hotkey;
9
- const normalized = require__keyboard_event.normalizeKeyboardEvent(event, platform);
10
- const noMatch = {
11
- matched: false,
12
- score: 0
13
- };
14
- if (normalized.isComposing && (parsed.code !== void 0 || require__keyboard_event.isPrintableKey(parsed.key))) return noMatch;
15
- if (normalized.altGraph && (parsed.ctrl || parsed.alt)) return noMatch;
16
- if (parsed.code !== void 0) {
17
- if (!modifiersMatch(normalized, parsed, false)) return noMatch;
18
- return normalized.code === parsed.code ? matched("code", 3) : noMatch;
19
- }
20
- const direct = require__keyboard_event.keysEqual(normalized.key, parsed.key);
21
- const implicitShift = direct && require__keyboard_event.isPrintableKey(normalized.key) && !/^\p{Letter}$/u.test(normalized.key) && !parsed.shift;
22
- if (direct && modifiersMatch(normalized, parsed, implicitShift)) return matched("key", implicitShift ? 2 : 3);
23
- if (require__keyboard_event.isAsciiLetter(normalized.key) || require__keyboard_event.isLatinLetter(normalized.key) && normalized.code.startsWith("Key") && !normalized.alt) return noMatch;
24
- if (!modifiersMatch(normalized, parsed, false)) return noMatch;
25
- const fallbackKey = require__keyboard_event.codeToLogicalKey(normalized.code);
26
- return fallbackKey !== void 0 && require__keyboard_event.keysEqual(fallbackKey, parsed.key) ? matched("fallback", 1) : noMatch;
27
- function matched(source, score) {
28
- return {
29
- matched: true,
30
- score,
31
- source,
32
- identity: {
33
- key: normalized.key,
34
- code: normalized.code
35
- }
36
- };
37
- }
38
- }
39
- /** Compares modifiers, excluding synthetic AltGr flags and optionally allowing Shift used to type a glyph. */
40
- function modifiersMatch(event, parsed, allowImplicitShift) {
41
- const ctrl = event.altGraph ? false : event.ctrl;
42
- const alt = event.altGraph ? false : event.alt;
43
- if (ctrl !== parsed.ctrl || alt !== parsed.alt || event.meta !== parsed.meta) return false;
44
- return event.shift === parsed.shift || allowImplicitShift && event.shift;
45
- }
46
-
47
- //#endregion
48
- exports.matchKeyboardEvent = matchKeyboardEvent;
49
- //# sourceMappingURL=_match.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_match.cjs","names":["detectPlatform","parseHotkey","normalizeKeyboardEvent","isPrintableKey","keysEqual","isAsciiLetter","isLatinLetter","codeToLogicalKey"],"sources":["../src/_match.ts"],"sourcesContent":["import { detectPlatform } from './platform'\nimport {\n codeToLogicalKey,\n isAsciiLetter,\n isLatinLetter,\n isPrintableKey,\n keysEqual,\n normalizeKeyboardEvent,\n} from './_keyboard-event'\nimport { parseHotkey } from './parse'\nimport type { KeyboardEventMatch } from './match'\nimport type { Hotkey, ParsedHotkey } from './hotkey.types'\n\n/** Matches an event and reports the winning candidate and release identity. */\nexport function matchKeyboardEvent(\n event: KeyboardEvent,\n hotkey: Hotkey | ParsedHotkey,\n platform: 'mac' | 'windows' | 'linux' = detectPlatform(),\n): KeyboardEventMatch {\n const parsed =\n typeof hotkey === 'string' ? parseHotkey(hotkey, platform) : hotkey\n const normalized = normalizeKeyboardEvent(event, platform)\n const noMatch: KeyboardEventMatch = { matched: false, score: 0 }\n\n if (\n normalized.isComposing &&\n (parsed.code !== undefined || isPrintableKey(parsed.key))\n )\n return noMatch\n if (normalized.altGraph && (parsed.ctrl || parsed.alt)) return noMatch\n\n if (parsed.code !== undefined) {\n if (!modifiersMatch(normalized, parsed, false)) return noMatch\n return normalized.code === parsed.code ? matched('code', 3) : noMatch\n }\n\n const direct = keysEqual(normalized.key, parsed.key)\n const implicitShift =\n direct &&\n isPrintableKey(normalized.key) &&\n !/^\\p{Letter}$/u.test(normalized.key) &&\n !parsed.shift\n\n if (direct && modifiersMatch(normalized, parsed, implicitShift)) {\n return matched('key', implicitShift ? 2 : 3)\n }\n\n // ASCII alphabetic output is authoritative for Dvorak/Colemak/AZERTY.\n // Native Latin letters are also authoritative on Key* positions; Alt is the\n // exception because macOS Option commonly transforms a shortcut's glyph.\n if (\n isAsciiLetter(normalized.key) ||\n (isLatinLetter(normalized.key) &&\n normalized.code.startsWith('Key') &&\n !normalized.alt)\n ) {\n return noMatch\n }\n\n if (!modifiersMatch(normalized, parsed, false)) return noMatch\n const fallbackKey = codeToLogicalKey(normalized.code)\n return fallbackKey !== undefined && keysEqual(fallbackKey, parsed.key)\n ? matched('fallback', 1)\n : noMatch\n\n // Preserve the triggering code so keyup can reset a shortcut even if its character changes.\n function matched(\n source: 'key' | 'code' | 'fallback',\n score: 1 | 2 | 3,\n ): KeyboardEventMatch {\n return {\n matched: true,\n score,\n source,\n identity: { key: normalized.key, code: normalized.code },\n }\n }\n}\n\n/** Compares modifiers, excluding synthetic AltGr flags and optionally allowing Shift used to type a glyph. */\nfunction modifiersMatch(\n event: ReturnType<typeof normalizeKeyboardEvent>,\n parsed: ParsedHotkey,\n allowImplicitShift: boolean,\n): boolean {\n const ctrl = event.altGraph ? false : event.ctrl\n const alt = event.altGraph ? false : event.alt\n if (\n ctrl !== parsed.ctrl ||\n alt !== parsed.alt ||\n event.meta !== parsed.meta\n ) {\n return false\n }\n return event.shift === parsed.shift || (allowImplicitShift && event.shift)\n}\n"],"mappings":";;;;;;AAcA,SAAgB,mBACd,OACA,QACA,WAAwCA,iCAAgB,EACpC;CACpB,MAAM,SACJ,OAAO,WAAW,WAAWC,0BAAY,QAAQ,SAAS,GAAG;CAC/D,MAAM,aAAaC,+CAAuB,OAAO,SAAS;CAC1D,MAAM,UAA8B;EAAE,SAAS;EAAO,OAAO;EAAG;AAEhE,KACE,WAAW,gBACV,OAAO,SAAS,UAAaC,uCAAe,OAAO,IAAI,EAExD,QAAO;AACT,KAAI,WAAW,aAAa,OAAO,QAAQ,OAAO,KAAM,QAAO;AAE/D,KAAI,OAAO,SAAS,QAAW;AAC7B,MAAI,CAAC,eAAe,YAAY,QAAQ,MAAM,CAAE,QAAO;AACvD,SAAO,WAAW,SAAS,OAAO,OAAO,QAAQ,QAAQ,EAAE,GAAG;;CAGhE,MAAM,SAASC,kCAAU,WAAW,KAAK,OAAO,IAAI;CACpD,MAAM,gBACJ,UACAD,uCAAe,WAAW,IAAI,IAC9B,CAAC,gBAAgB,KAAK,WAAW,IAAI,IACrC,CAAC,OAAO;AAEV,KAAI,UAAU,eAAe,YAAY,QAAQ,cAAc,CAC7D,QAAO,QAAQ,OAAO,gBAAgB,IAAI,EAAE;AAM9C,KACEE,sCAAc,WAAW,IAAI,IAC5BC,sCAAc,WAAW,IAAI,IAC5B,WAAW,KAAK,WAAW,MAAM,IACjC,CAAC,WAAW,IAEd,QAAO;AAGT,KAAI,CAAC,eAAe,YAAY,QAAQ,MAAM,CAAE,QAAO;CACvD,MAAM,cAAcC,yCAAiB,WAAW,KAAK;AACrD,QAAO,gBAAgB,UAAaH,kCAAU,aAAa,OAAO,IAAI,GAClE,QAAQ,YAAY,EAAE,GACtB;CAGJ,SAAS,QACP,QACA,OACoB;AACpB,SAAO;GACL,SAAS;GACT;GACA;GACA,UAAU;IAAE,KAAK,WAAW;IAAK,MAAM,WAAW;IAAM;GACzD;;;;AAKL,SAAS,eACP,OACA,QACA,oBACS;CACT,MAAM,OAAO,MAAM,WAAW,QAAQ,MAAM;CAC5C,MAAM,MAAM,MAAM,WAAW,QAAQ,MAAM;AAC3C,KACE,SAAS,OAAO,QAChB,QAAQ,OAAO,OACf,MAAM,SAAS,OAAO,KAEtB,QAAO;AAET,QAAO,MAAM,UAAU,OAAO,SAAU,sBAAsB,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_match.js","names":[],"sources":["../src/_match.ts"],"sourcesContent":["import { detectPlatform } from './platform'\nimport {\n codeToLogicalKey,\n isAsciiLetter,\n isLatinLetter,\n isPrintableKey,\n keysEqual,\n normalizeKeyboardEvent,\n} from './_keyboard-event'\nimport { parseHotkey } from './parse'\nimport type { KeyboardEventMatch } from './match'\nimport type { Hotkey, ParsedHotkey } from './hotkey.types'\n\n/** Matches an event and reports the winning candidate and release identity. */\nexport function matchKeyboardEvent(\n event: KeyboardEvent,\n hotkey: Hotkey | ParsedHotkey,\n platform: 'mac' | 'windows' | 'linux' = detectPlatform(),\n): KeyboardEventMatch {\n const parsed =\n typeof hotkey === 'string' ? parseHotkey(hotkey, platform) : hotkey\n const normalized = normalizeKeyboardEvent(event, platform)\n const noMatch: KeyboardEventMatch = { matched: false, score: 0 }\n\n if (\n normalized.isComposing &&\n (parsed.code !== undefined || isPrintableKey(parsed.key))\n )\n return noMatch\n if (normalized.altGraph && (parsed.ctrl || parsed.alt)) return noMatch\n\n if (parsed.code !== undefined) {\n if (!modifiersMatch(normalized, parsed, false)) return noMatch\n return normalized.code === parsed.code ? matched('code', 3) : noMatch\n }\n\n const direct = keysEqual(normalized.key, parsed.key)\n const implicitShift =\n direct &&\n isPrintableKey(normalized.key) &&\n !/^\\p{Letter}$/u.test(normalized.key) &&\n !parsed.shift\n\n if (direct && modifiersMatch(normalized, parsed, implicitShift)) {\n return matched('key', implicitShift ? 2 : 3)\n }\n\n // ASCII alphabetic output is authoritative for Dvorak/Colemak/AZERTY.\n // Native Latin letters are also authoritative on Key* positions; Alt is the\n // exception because macOS Option commonly transforms a shortcut's glyph.\n if (\n isAsciiLetter(normalized.key) ||\n (isLatinLetter(normalized.key) &&\n normalized.code.startsWith('Key') &&\n !normalized.alt)\n ) {\n return noMatch\n }\n\n if (!modifiersMatch(normalized, parsed, false)) return noMatch\n const fallbackKey = codeToLogicalKey(normalized.code)\n return fallbackKey !== undefined && keysEqual(fallbackKey, parsed.key)\n ? matched('fallback', 1)\n : noMatch\n\n // Preserve the triggering code so keyup can reset a shortcut even if its character changes.\n function matched(\n source: 'key' | 'code' | 'fallback',\n score: 1 | 2 | 3,\n ): KeyboardEventMatch {\n return {\n matched: true,\n score,\n source,\n identity: { key: normalized.key, code: normalized.code },\n }\n }\n}\n\n/** Compares modifiers, excluding synthetic AltGr flags and optionally allowing Shift used to type a glyph. */\nfunction modifiersMatch(\n event: ReturnType<typeof normalizeKeyboardEvent>,\n parsed: ParsedHotkey,\n allowImplicitShift: boolean,\n): boolean {\n const ctrl = event.altGraph ? false : event.ctrl\n const alt = event.altGraph ? false : event.alt\n if (\n ctrl !== parsed.ctrl ||\n alt !== parsed.alt ||\n event.meta !== parsed.meta\n ) {\n return false\n }\n return event.shift === parsed.shift || (allowImplicitShift && event.shift)\n}\n"],"mappings":";;;;;;AAcA,SAAgB,mBACd,OACA,QACA,WAAwC,gBAAgB,EACpC;CACpB,MAAM,SACJ,OAAO,WAAW,WAAW,YAAY,QAAQ,SAAS,GAAG;CAC/D,MAAM,aAAa,uBAAuB,OAAO,SAAS;CAC1D,MAAM,UAA8B;EAAE,SAAS;EAAO,OAAO;EAAG;AAEhE,KACE,WAAW,gBACV,OAAO,SAAS,UAAa,eAAe,OAAO,IAAI,EAExD,QAAO;AACT,KAAI,WAAW,aAAa,OAAO,QAAQ,OAAO,KAAM,QAAO;AAE/D,KAAI,OAAO,SAAS,QAAW;AAC7B,MAAI,CAAC,eAAe,YAAY,QAAQ,MAAM,CAAE,QAAO;AACvD,SAAO,WAAW,SAAS,OAAO,OAAO,QAAQ,QAAQ,EAAE,GAAG;;CAGhE,MAAM,SAAS,UAAU,WAAW,KAAK,OAAO,IAAI;CACpD,MAAM,gBACJ,UACA,eAAe,WAAW,IAAI,IAC9B,CAAC,gBAAgB,KAAK,WAAW,IAAI,IACrC,CAAC,OAAO;AAEV,KAAI,UAAU,eAAe,YAAY,QAAQ,cAAc,CAC7D,QAAO,QAAQ,OAAO,gBAAgB,IAAI,EAAE;AAM9C,KACE,cAAc,WAAW,IAAI,IAC5B,cAAc,WAAW,IAAI,IAC5B,WAAW,KAAK,WAAW,MAAM,IACjC,CAAC,WAAW,IAEd,QAAO;AAGT,KAAI,CAAC,eAAe,YAAY,QAAQ,MAAM,CAAE,QAAO;CACvD,MAAM,cAAc,iBAAiB,WAAW,KAAK;AACrD,QAAO,gBAAgB,UAAa,UAAU,aAAa,OAAO,IAAI,GAClE,QAAQ,YAAY,EAAE,GACtB;CAGJ,SAAS,QACP,QACA,OACoB;AACpB,SAAO;GACL,SAAS;GACT;GACA;GACA,UAAU;IAAE,KAAK,WAAW;IAAK,MAAM,WAAW;IAAM;GACzD;;;;AAKL,SAAS,eACP,OACA,QACA,oBACS;CACT,MAAM,OAAO,MAAM,WAAW,QAAQ,MAAM;CAC5C,MAAM,MAAM,MAAM,WAAW,QAAQ,MAAM;AAC3C,KACE,SAAS,OAAO,QAChB,QAAQ,OAAO,OACf,MAAM,SAAS,OAAO,KAEtB,QAAO;AAET,QAAO,MAAM,UAAU,OAAO,SAAU,sBAAsB,MAAM"}
@@ -1,68 +0,0 @@
1
-
2
- //#region src/_named-keys.ts
3
- /** Names defined for both KeyboardEvent.key and KeyboardEvent.code, beyond the basic key groups. */
4
- const SHARED_NAMED_KEYS = [
5
- "CapsLock",
6
- "ContextMenu",
7
- "Convert",
8
- "KanaMode",
9
- "NonConvert",
10
- "Help",
11
- "Insert",
12
- "NumLock",
13
- "Fn",
14
- "FnLock",
15
- "PrintScreen",
16
- "ScrollLock",
17
- "Pause",
18
- "BrowserBack",
19
- "BrowserFavorites",
20
- "BrowserForward",
21
- "BrowserHome",
22
- "BrowserRefresh",
23
- "BrowserSearch",
24
- "BrowserStop",
25
- "Eject",
26
- "LaunchMail",
27
- "MediaPlayPause",
28
- "MediaStop",
29
- "MediaTrackNext",
30
- "MediaTrackPrevious",
31
- "Power",
32
- "AudioVolumeDown",
33
- "AudioVolumeMute",
34
- "AudioVolumeUp",
35
- "WakeUp",
36
- "Hyper",
37
- "Super",
38
- "Again",
39
- "Copy",
40
- "Cut",
41
- "Find",
42
- "Open",
43
- "Paste",
44
- "Props",
45
- "Select",
46
- "Undo",
47
- "Hiragana",
48
- "Katakana"
49
- ];
50
- /** Logical counterparts whose physical positions use different names (for example Sleep and Lang1). */
51
- const LOGICAL_ONLY_NAMED_KEYS = [
52
- "Clear",
53
- "Cancel",
54
- "Standby",
55
- "LaunchApplication1",
56
- "LaunchApplication2",
57
- "LaunchMediaPlayer",
58
- "HangulMode",
59
- "HanjaMode",
60
- "Zenkaku",
61
- "Hankaku",
62
- "ZenkakuHankaku"
63
- ];
64
-
65
- //#endregion
66
- exports.LOGICAL_ONLY_NAMED_KEYS = LOGICAL_ONLY_NAMED_KEYS;
67
- exports.SHARED_NAMED_KEYS = SHARED_NAMED_KEYS;
68
- //# sourceMappingURL=_named-keys.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_named-keys.cjs","names":[],"sources":["../src/_named-keys.ts"],"sourcesContent":["/** Names defined for both KeyboardEvent.key and KeyboardEvent.code, beyond the basic key groups. */\nexport const SHARED_NAMED_KEYS = [\n 'CapsLock',\n 'ContextMenu',\n 'Convert',\n 'KanaMode',\n 'NonConvert',\n 'Help',\n 'Insert',\n 'NumLock',\n 'Fn',\n 'FnLock',\n 'PrintScreen',\n 'ScrollLock',\n 'Pause',\n 'BrowserBack',\n 'BrowserFavorites',\n 'BrowserForward',\n 'BrowserHome',\n 'BrowserRefresh',\n 'BrowserSearch',\n 'BrowserStop',\n 'Eject',\n 'LaunchMail',\n 'MediaPlayPause',\n 'MediaStop',\n 'MediaTrackNext',\n 'MediaTrackPrevious',\n 'Power',\n 'AudioVolumeDown',\n 'AudioVolumeMute',\n 'AudioVolumeUp',\n 'WakeUp',\n 'Hyper',\n 'Super',\n 'Again',\n 'Copy',\n 'Cut',\n 'Find',\n 'Open',\n 'Paste',\n 'Props',\n 'Select',\n 'Undo',\n 'Hiragana',\n 'Katakana',\n] as const\n\n/** Logical counterparts whose physical positions use different names (for example Sleep and Lang1). */\nexport const LOGICAL_ONLY_NAMED_KEYS = [\n 'Clear',\n 'Cancel',\n 'Standby',\n 'LaunchApplication1',\n 'LaunchApplication2',\n 'LaunchMediaPlayer',\n 'HangulMode',\n 'HanjaMode',\n 'Zenkaku',\n 'Hankaku',\n 'ZenkakuHankaku',\n] as const\n"],"mappings":";;;AACA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
@@ -1,8 +0,0 @@
1
- //#region src/_named-keys.d.ts
2
- /** Names defined for both KeyboardEvent.key and KeyboardEvent.code, beyond the basic key groups. */
3
- declare const SHARED_NAMED_KEYS: readonly ["CapsLock", "ContextMenu", "Convert", "KanaMode", "NonConvert", "Help", "Insert", "NumLock", "Fn", "FnLock", "PrintScreen", "ScrollLock", "Pause", "BrowserBack", "BrowserFavorites", "BrowserForward", "BrowserHome", "BrowserRefresh", "BrowserSearch", "BrowserStop", "Eject", "LaunchMail", "MediaPlayPause", "MediaStop", "MediaTrackNext", "MediaTrackPrevious", "Power", "AudioVolumeDown", "AudioVolumeMute", "AudioVolumeUp", "WakeUp", "Hyper", "Super", "Again", "Copy", "Cut", "Find", "Open", "Paste", "Props", "Select", "Undo", "Hiragana", "Katakana"];
4
- /** Logical counterparts whose physical positions use different names (for example Sleep and Lang1). */
5
- declare const LOGICAL_ONLY_NAMED_KEYS: readonly ["Clear", "Cancel", "Standby", "LaunchApplication1", "LaunchApplication2", "LaunchMediaPlayer", "HangulMode", "HanjaMode", "Zenkaku", "Hankaku", "ZenkakuHankaku"];
6
- //#endregion
7
- export { LOGICAL_ONLY_NAMED_KEYS, SHARED_NAMED_KEYS };
8
- //# sourceMappingURL=_named-keys.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_named-keys.js","names":[],"sources":["../src/_named-keys.ts"],"sourcesContent":["/** Names defined for both KeyboardEvent.key and KeyboardEvent.code, beyond the basic key groups. */\nexport const SHARED_NAMED_KEYS = [\n 'CapsLock',\n 'ContextMenu',\n 'Convert',\n 'KanaMode',\n 'NonConvert',\n 'Help',\n 'Insert',\n 'NumLock',\n 'Fn',\n 'FnLock',\n 'PrintScreen',\n 'ScrollLock',\n 'Pause',\n 'BrowserBack',\n 'BrowserFavorites',\n 'BrowserForward',\n 'BrowserHome',\n 'BrowserRefresh',\n 'BrowserSearch',\n 'BrowserStop',\n 'Eject',\n 'LaunchMail',\n 'MediaPlayPause',\n 'MediaStop',\n 'MediaTrackNext',\n 'MediaTrackPrevious',\n 'Power',\n 'AudioVolumeDown',\n 'AudioVolumeMute',\n 'AudioVolumeUp',\n 'WakeUp',\n 'Hyper',\n 'Super',\n 'Again',\n 'Copy',\n 'Cut',\n 'Find',\n 'Open',\n 'Paste',\n 'Props',\n 'Select',\n 'Undo',\n 'Hiragana',\n 'Katakana',\n] as const\n\n/** Logical counterparts whose physical positions use different names (for example Sleep and Lang1). */\nexport const LOGICAL_ONLY_NAMED_KEYS = [\n 'Clear',\n 'Cancel',\n 'Standby',\n 'LaunchApplication1',\n 'LaunchApplication2',\n 'LaunchMediaPlayer',\n 'HangulMode',\n 'HanjaMode',\n 'Zenkaku',\n 'Hankaku',\n 'ZenkakuHankaku',\n] as const\n"],"mappings":";;AACA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}