rx-hotkeys 4.2.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,7 @@ rx-hotkeys is a powerful and flexible TypeScript library for managing keyboard s
16
16
  * **Strict Global Shortcuts**: Option to register global shortcuts that *only* fire when no other context is active.
17
17
  * **Type-Safe Key Definitions**: Uses an exported `Keys` object based on standard `KeyboardEvent.key` values for a superior developer experience and fewer errors.
18
18
  * **Sequence Timeouts**: Optional timeout between key presses in a sequence to prevent accidental triggers.
19
+ * **Form, Editor & IME Guards**: Automatically suppresses accidental shortcut triggers while typing in `<input>`, `<textarea>`, `<select>`, rich-text editors (`contentEditable`), or during IME composition (`isComposing`). Easily opt-in or customize per shortcut.
19
20
  * **Debug Mode**: Optional, detailed console logging for easier development and troubleshooting.
20
21
 
21
22
  ## Installation
@@ -382,6 +383,10 @@ A hook to get direct access to the `Hotkeys` manager instance.
382
383
  * `target?: HTMLElement`: The DOM element to attach the listener to. Defaults to `document`.
383
384
  * `event?: "keydown" | "keyup"`: The keyboard event to listen for. Defaults to `"keydown"`.
384
385
  * `options?: AddEventListenerOptions`: Optional. Advanced options to pass directly to the underlying `addEventListener` call. Use this to control behaviors like `capture`, `passive`, or `once`.
386
+ * `enableOnFormTags?: boolean | Array<"input" | "textarea" | "select" | string>`: Whether the shortcut triggers inside form elements (`<input>`, `<textarea>`, `<select>`). Defaults to `false` (suppressed to prevent accidental triggers). Set to `true` or an array of tags (e.g. `['input']`) to allow.
387
+ * `enableOnContentEditable?: boolean`: Whether the shortcut triggers inside rich-text editors (`contentEditable`). Defaults to `false`. Set to `true` to allow.
388
+ * `ignoreComposing?: boolean`: Whether shortcuts are suppressed during IME composition (Chinese/Japanese/Korean input methods). Defaults to `true`.
389
+ * `filter?: (event: KeyboardEvent) => boolean`: Optional custom predicate function to determine if the event should be processed. Return `false` to suppress without calling `preventDefault()`.
385
390
 
386
391
 
387
392
  #### `KeyCombinationConfig`
@@ -1,10 +1,11 @@
1
1
  import { Observable, Subject } from "rxjs";
2
- import { type StandardKey } from "./keys.js";
3
- export declare enum ShortcutTypes {
4
- Combination = "combination",
5
- Sequence = "sequence"
6
- }
7
- interface ShortcutConfigBase {
2
+ import { type StandardKey } from "./keys.ts";
3
+ export declare const ShortcutTypes: Readonly<{
4
+ readonly Combination: "combination";
5
+ readonly Sequence: "sequence";
6
+ }>;
7
+ export type ShortcutTypes = typeof ShortcutTypes[keyof typeof ShortcutTypes];
8
+ export interface ShortcutConfigBase {
8
9
  id: string;
9
10
  context?: string | null;
10
11
  preventDefault?: boolean;
@@ -39,6 +40,35 @@ interface ShortcutConfigBase {
39
40
  * @default undefined
40
41
  */
41
42
  options?: AddEventListenerOptions;
43
+ /**
44
+ * Controls whether the shortcut is enabled inside form elements (`<input>`, `<textarea>`, `<select>`).
45
+ * - `false` (default): Suppresses shortcuts while typing in form elements to prevent accidental triggers.
46
+ * - `true`: Enables the shortcut in all form elements.
47
+ * - `string[]`: Enables the shortcut only on specific tag names (e.g. `['input']` or `['textarea']`).
48
+ * @default false
49
+ */
50
+ enableOnFormTags?: boolean | Array<"input" | "textarea" | "select" | string>;
51
+ /**
52
+ * Controls whether the shortcut is enabled inside rich-text editors (`contentEditable` elements).
53
+ * - `false` (default): Suppresses shortcuts while editing rich-text content.
54
+ * - `true`: Enables the shortcut in `contentEditable` elements.
55
+ * @default false
56
+ */
57
+ enableOnContentEditable?: boolean;
58
+ /**
59
+ * Controls whether shortcuts are ignored during IME (Input Method Editor) composition,
60
+ * such as Chinese, Japanese, or Korean text input.
61
+ * - `true` (default): Suppresses shortcuts while IME composition is active (`event.isComposing` or `keyCode === 229`).
62
+ * - `false`: Allows shortcuts even during IME composition.
63
+ * @default true
64
+ */
65
+ ignoreComposing?: boolean;
66
+ /**
67
+ * Optional custom predicate function to decide whether a `KeyboardEvent` should be handled.
68
+ * Returning `false` will suppress the shortcut without triggering `preventDefault()`.
69
+ * @default undefined
70
+ */
71
+ filter?: (event: KeyboardEvent) => boolean;
42
72
  }
43
73
  /**
44
74
  * Defines a single key trigger, which can be a StandardKey (for simple presses like "Escape")
@@ -123,21 +153,7 @@ export interface ActiveShortcut {
123
153
  * Supports contexts to enable/disable shortcuts based on application state.
124
154
  */
125
155
  export declare class Hotkeys {
126
- private static readonly KEYDOWN_EVENT;
127
- private static readonly KEYUP_EVENT;
128
- private static readonly LOG_PREFIX;
129
- private static readonly NO_OVERRIDE;
130
- private eventStreams;
131
- private activeShortcuts;
132
- private debugMode;
133
- private contextStack$;
134
- private overrideContext$;
135
- /**
136
- * An Observable that emits the new active context name (or null) whenever it changes.
137
- * The active context is the override context if one is set, otherwise it's the context
138
- * from the top of the stack.
139
- */
140
- private readonly activeContext$;
156
+ #private;
141
157
  /**
142
158
  * Creates an instance of Hotkeys.
143
159
  * @param initialContext - Optional initial context name. This forms the base of the context stack.
@@ -145,24 +161,6 @@ export declare class Hotkeys {
145
161
  * @throws Error if not in a browser environment (i.e., `document` or `performance` is undefined).
146
162
  */
147
163
  constructor(initialContext?: string | null, debugMode?: boolean);
148
- /**
149
- * Helper method to determine the active context based on override and stack.
150
- */
151
- private _resolveActiveContext;
152
- private _normalizeAndParseTriggers;
153
- private _normalizeSequence;
154
- /**
155
- * [PRIVATE] Generates a unique key for the stream cache based on event type and options.
156
- */
157
- private _getStreamCacheKey;
158
- /**
159
- * Gets or creates a shared event stream for a given event type, target, and options.
160
- * @param eventType The type of event ("keydown" or "keyup").
161
- * @param target The DOM element to attach the listener to.
162
- * @param options The AddEventListenerOptions.
163
- * @returns A shared Observable for the specified event.
164
- */
165
- private _getEventStream;
166
164
  /**
167
165
  * Sets a temporary, high-priority override context that takes precedence over the context stack.
168
166
  * @param contextName The override context to activate (can be a string or `null`).
@@ -217,33 +215,6 @@ export declare class Hotkeys {
217
215
  * ```
218
216
  */
219
217
  get onContextChange$(): Observable<string | null>;
220
- /**
221
- * Compares two sequences of StandardKey arrays to see if they are identical.
222
- * @param seq1 - The first sequence array.
223
- * @param seq2 - The second sequence array.
224
- * @returns True if the sequences are identical, false otherwise.
225
- */
226
- private _areSequencesIdentical;
227
- /**
228
- * Checks if a given KeyCombinationConfig matches a given KeyboardEvent.
229
- * This is used internally for priority checking.
230
- * @param shortcutConfig The KeyCombinationConfig to check.
231
- * @param event The KeyboardEvent to match against.
232
- * @returns True if the shortcutConfig matches the event, false otherwise.
233
- */
234
- private _shortcutMatchesEvent;
235
- private filterByContext;
236
- private _registerShortcut;
237
- /**
238
- * Parses a single key trigger definition (either shorthand StandardKey or an object with modifiers)
239
- * into its constituent parts: main key and modifier states.
240
- * @param keyInput - The KeyCombinationTrigger to parse.
241
- * @param shortcutId - The ID of the shortcut this key trigger belongs to (for logging).
242
- * @returns An object containing configuredMainKey and modifier states, or null if parsing fails.
243
- */
244
- private _parseKeyTrigger;
245
- private _parseCombinationString;
246
- private _parseSequenceString;
247
218
  /**
248
219
  * Registers a key combination shortcut (e.g., Ctrl+S, Shift+Enter, or a single key like Escape)
249
220
  * and returns an Observable that emits the `KeyboardEvent` when the combination is triggered.
@@ -1 +1 @@
1
- {"version":3,"file":"hotkeys.d.ts","sourceRoot":"","sources":["../../src/core/hotkeys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hotkeys.d.ts","sourceRoot":"","sources":["../../src/core/hotkeys.ts"],"names":[],"mappings":"AAAA,OAAO,EACgC,UAAU,EAC2B,OAAO,EAClF,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,KAAK,WAAW,EAAoB,MAAM,WAAW,CAAC;AAI/D,eAAO,MAAM,aAAa;0BACT,aAAa;uBAChB,UAAU;EACb,CAAC;AACZ,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAe7E,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;IAC7E;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAChC;;;;;;;;;OASG;IACH,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,WAAW,GAAG,MAAM,CAAC;AAEzB;;;GAGG;AACH,UAAU,aAAa;IACnB,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC5D;;;;;;;;;;;;;;;;OAgBG;IACH,IAAI,EAAE,qBAAqB,GAAG,qBAAqB,EAAE,CAAC;CACzD;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IACzD;;;;;;;;OAQG;IACH,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IACjC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,KAAK,cAAc,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CACpC;AAkDD;;;;GAIG;AACH,qBAAa,OAAO;;IAyBhB;;;;;OAKG;IACH,YAAY,cAAc,GAAE,MAAM,GAAG,IAAW,EAAE,SAAS,GAAE,OAAe,EA6B3E;IA8FD;;;;OAIG;IACI,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,IAAI,CAiBxD;IAED;;;;OAIG;IACI,UAAU,IAAI,MAAM,GAAG,IAAI,CAGjC;IAED;;;OAGG;IACI,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAMvC;IAED;;;OAGG;IACI,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAOpD;IAED;;;OAGG;IACI,YAAY,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS,CAkB/C;IAED;;;;OAIG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAUzC;IAED;;;;OAIG;IACI,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEtC;IAED;;;;;;;;;;;;;OAaG;IACH,IAAW,gBAAgB,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAEvD;IA0QD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACI,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,UAAU,CAAC,aAAa,CAAC,CA+F7E;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACI,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,UAAU,CAAC,aAAa,CAAC,CAqIvE;IAED;;;;;;OAMG;IACI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAWjC;IAED;;;;;;OAMG;IACI,kBAAkB,IAAI;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAC,EAAE,CAW9G;IAED;;;;;OAKG;IACI,OAAO,IAAI,IAAI,CASrB;CACJ"}