ngx-keys 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,9 +1,27 @@
1
- import * as _angular_core from '@angular/core';
2
- import { DestroyRef, OnDestroy } from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
+ import { DestroyRef, OnDestroy, InjectionToken, Provider, OnInit } from '@angular/core';
3
3
  import { Observable } from 'rxjs';
4
4
 
5
5
  type KeyboardShortcutActiveUntil = Observable<unknown> | DestroyRef | 'destruct';
6
6
  type KeyStep = string[];
7
+ /**
8
+ * Function signature for keyboard shortcut actions.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const saveAction: Action = () => {
13
+ * console.log('Saving...');
14
+ * };
15
+ *
16
+ * this.keyboardService.register({
17
+ * id: 'save',
18
+ * keys: ['ctrl', 's'],
19
+ * action: saveAction,
20
+ * description: 'Save document'
21
+ * });
22
+ * ```
23
+ */
24
+ type Action = () => void;
7
25
  interface KeyboardShortcut {
8
26
  id: string;
9
27
  /**
@@ -22,7 +40,7 @@ interface KeyboardShortcut {
22
40
  macKeys?: string[];
23
41
  steps?: KeyStep[];
24
42
  macSteps?: KeyStep[];
25
- action: () => void;
43
+ action: Action;
26
44
  description: string;
27
45
  activeUntil?: KeyboardShortcutActiveUntil;
28
46
  /**
@@ -46,6 +64,38 @@ interface KeyboardShortcut {
46
64
  * ```
47
65
  */
48
66
  filter?: KeyboardShortcutFilter;
67
+ /**
68
+ * Optional timeout (in milliseconds) for multi-step sequences.
69
+ * After this duration of inactivity between steps, the sequence state will reset.
70
+ *
71
+ * @default undefined (no timeout - sequence remains active indefinitely)
72
+ *
73
+ * @remarks
74
+ * For accessibility, the default behavior (no timeout) is recommended.
75
+ * Multi-step sequences remain active until completed or the window/document loses focus.
76
+ * Only specify a timeout for specialized use cases like preventing stuck UI states.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // No timeout (default) - waits indefinitely between steps
81
+ * {
82
+ * id: 'save-file',
83
+ * steps: [['ctrl', 'k'], ['s']],
84
+ * action: () => this.save(),
85
+ * description: 'Save file'
86
+ * }
87
+ *
88
+ * // 5 second timeout - resets if user pauses too long between steps
89
+ * {
90
+ * id: 'quick-action',
91
+ * steps: [['ctrl', 'k'], ['q']],
92
+ * action: () => this.quickAction(),
93
+ * description: 'Quick action',
94
+ * sequenceTimeout: 5000
95
+ * }
96
+ * ```
97
+ */
98
+ sequenceTimeout?: number;
49
99
  }
50
100
  interface KeyboardShortcutGroup {
51
101
  id: string;
@@ -114,9 +164,9 @@ interface KeyboardShortcutUI {
114
164
  }
115
165
 
116
166
  declare class KeyboardShortcuts implements OnDestroy {
117
- private static readonly MODIFIER_KEYS;
118
167
  private readonly document;
119
168
  private readonly window;
169
+ private readonly config;
120
170
  private readonly shortcuts;
121
171
  private readonly groups;
122
172
  private readonly activeShortcuts;
@@ -129,7 +179,7 @@ declare class KeyboardShortcuts implements OnDestroy {
129
179
  */
130
180
  private readonly globalFilters;
131
181
  private readonly state;
132
- readonly shortcuts$: _angular_core.Signal<{
182
+ readonly shortcuts$: i0.Signal<{
133
183
  active: KeyboardShortcut[];
134
184
  inactive: KeyboardShortcut[];
135
185
  all: KeyboardShortcut[];
@@ -138,7 +188,7 @@ declare class KeyboardShortcuts implements OnDestroy {
138
188
  inactive: string[];
139
189
  };
140
190
  }>;
141
- readonly shortcutsUI$: _angular_core.Signal<{
191
+ readonly shortcutsUI$: i0.Signal<{
142
192
  active: KeyboardShortcutUI[];
143
193
  inactive: KeyboardShortcutUI[];
144
194
  all: KeyboardShortcutUI[];
@@ -148,8 +198,6 @@ declare class KeyboardShortcuts implements OnDestroy {
148
198
  private readonly blurListener;
149
199
  private readonly visibilityListener;
150
200
  private isListening;
151
- /** Default timeout (ms) for completing a multi-step sequence */
152
- protected sequenceTimeout: number;
153
201
  /** Runtime state for multi-step sequences */
154
202
  private pendingSequence;
155
203
  constructor();
@@ -307,6 +355,67 @@ declare class KeyboardShortcuts implements OnDestroy {
307
355
  * @returns `true` if filter exists, `false` otherwise
308
356
  */
309
357
  hasFilter(name: string): boolean;
358
+ /**
359
+ * Remove the filter from a specific group
360
+ * @param groupId - The group ID
361
+ * @throws KeyboardShortcutError if group doesn't exist
362
+ */
363
+ removeGroupFilter(groupId: string): void;
364
+ /**
365
+ * Remove the filter from a specific shortcut
366
+ * @param shortcutId - The shortcut ID
367
+ * @throws KeyboardShortcutError if shortcut doesn't exist
368
+ */
369
+ removeShortcutFilter(shortcutId: string): void;
370
+ /**
371
+ * Remove all filters from all groups
372
+ */
373
+ clearAllGroupFilters(): void;
374
+ /**
375
+ * Remove all filters from all shortcuts
376
+ */
377
+ clearAllShortcutFilters(): void;
378
+ /**
379
+ * Check if a group has a filter
380
+ * @param groupId - The group ID
381
+ * @returns True if the group has a filter
382
+ */
383
+ hasGroupFilter(groupId: string): boolean;
384
+ /**
385
+ * Check if a shortcut has a filter
386
+ * @param shortcutId - The shortcut ID
387
+ * @returns True if the shortcut has a filter
388
+ */
389
+ hasShortcutFilter(shortcutId: string): boolean;
390
+ /**
391
+ * Register multiple shortcuts in a single batch update
392
+ * @param shortcuts - Array of shortcuts to register
393
+ */
394
+ registerMany(shortcuts: KeyboardShortcut[]): void;
395
+ /**
396
+ * Unregister multiple shortcuts in a single batch update
397
+ * @param ids - Array of shortcut IDs to unregister
398
+ */
399
+ unregisterMany(ids: string[]): void;
400
+ /**
401
+ * Unregister multiple groups in a single batch update
402
+ * @param ids - Array of group IDs to unregister
403
+ */
404
+ unregisterGroups(ids: string[]): void;
405
+ /**
406
+ * Clear all shortcuts and groups (nuclear reset)
407
+ */
408
+ clearAll(): void;
409
+ /**
410
+ * Get all shortcuts belonging to a specific group
411
+ * @param groupId - The group ID
412
+ * @returns Array of shortcuts in the group
413
+ */
414
+ getGroupShortcuts(groupId: string): KeyboardShortcut[];
415
+ /**
416
+ * Normalize a key to lowercase for consistent comparison
417
+ */
418
+ private normalizeKey;
310
419
  /**
311
420
  * Find the group that contains a specific shortcut.
312
421
  *
@@ -359,8 +468,14 @@ declare class KeyboardShortcuts implements OnDestroy {
359
468
  * Accepts either a Set<string> (preferred) or an array for backwards compatibility.
360
469
  * Uses Set-based comparison: sizes must match and every element in target must exist in pressed.
361
470
  */
471
+ /**
472
+ * @deprecated Use KeyMatcher.keysMatch() instead
473
+ */
362
474
  protected keysMatch(pressedKeys: Set<string> | string[], targetKeys: string[]): boolean;
363
- /** Compare two multi-step sequences for equality */
475
+ /**
476
+ * Compare two multi-step sequences for equality
477
+ * @deprecated Use KeyMatcher.stepsMatch() instead
478
+ */
364
479
  protected stepsMatch(a: string[][], b: string[][]): boolean;
365
480
  /** Safely clear any pending multi-step sequence */
366
481
  private clearPendingSequence;
@@ -370,8 +485,8 @@ declare class KeyboardShortcuts implements OnDestroy {
370
485
  * Evaluate group filters once per event and return the set of blocked group IDs.
371
486
  */
372
487
  protected precomputeBlockedGroups(event: KeyboardEvent): Set<string>;
373
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<KeyboardShortcuts, never>;
374
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<KeyboardShortcuts>;
488
+ static ɵfac: i0.ɵɵFactoryDeclaration<KeyboardShortcuts, never>;
489
+ static ɵprov: i0.ɵɵInjectableDeclaration<KeyboardShortcuts>;
375
490
  }
376
491
 
377
492
  /**
@@ -432,5 +547,170 @@ declare class KeyboardShortcutsErrorFactory {
432
547
  static cannotUnregisterGroup(id: string): KeyboardShortcutError;
433
548
  }
434
549
 
435
- export { KeyboardShortcutError, KeyboardShortcuts, KeyboardShortcutsErrorFactory, KeyboardShortcutsErrors };
436
- export type { KeyStep, KeyboardShortcut, KeyboardShortcutActiveUntil, KeyboardShortcutFilter, KeyboardShortcutGroup, KeyboardShortcutGroupOptions, KeyboardShortcutUI, KeyboardShortcutsErrorType };
550
+ /**
551
+ * Configuration options for the KeyboardShortcuts service.
552
+ */
553
+ interface KeyboardShortcutsConfig {
554
+ }
555
+ /**
556
+ * Injection token for providing KeyboardShortcuts configuration.
557
+ *
558
+ * @example
559
+ * ```typescript
560
+ * providers: [
561
+ * provideKeyboardShortcutsConfig({ sequenceTimeoutMs: Infinity })
562
+ * ]
563
+ * ```
564
+ */
565
+ declare const KEYBOARD_SHORTCUTS_CONFIG: InjectionToken<KeyboardShortcutsConfig>;
566
+ /**
567
+ * Provides KeyboardShortcuts configuration using Angular's modern provider pattern.
568
+ *
569
+ * @param config - Configuration options for KeyboardShortcuts service
570
+ * @returns Provider array for use in Angular dependency injection
571
+ *
572
+ * @example
573
+ * ```typescript
574
+ * bootstrapApplication(AppComponent, {
575
+ * providers: [
576
+ * provideKeyboardShortcutsConfig({ sequenceTimeoutMs: Infinity })
577
+ * ]
578
+ * });
579
+ * ```
580
+ */
581
+ declare function provideKeyboardShortcutsConfig(config: KeyboardShortcutsConfig): Provider[];
582
+
583
+ /**
584
+ * Directive for registering keyboard shortcuts directly on elements in templates.
585
+ *
586
+ * This directive automatically:
587
+ * - Registers the shortcut when the directive initializes
588
+ * - Triggers the host element's click event (default) or executes a custom action
589
+ * - Unregisters the shortcut when the component is destroyed
590
+ *
591
+ * @example
592
+ * Basic usage with click trigger:
593
+ * ```html
594
+ * <button ngxKeys
595
+ * keys="ctrl,s"
596
+ * description="Save document"
597
+ * (click)="save()">
598
+ * Save
599
+ * </button>
600
+ * ```
601
+ *
602
+ * @example
603
+ * With custom action:
604
+ * ```html
605
+ * <button ngxKeys
606
+ * keys="ctrl,s"
607
+ * description="Save document"
608
+ * [action]="customSaveAction">
609
+ * Save
610
+ * </button>
611
+ * ```
612
+ *
613
+ * @example
614
+ * Multi-step shortcuts:
615
+ * ```html
616
+ * <button ngxKeys
617
+ * [steps]="[['ctrl', 'k'], ['ctrl', 's']]"
618
+ * description="Format document"
619
+ * (click)="format()">
620
+ * Format
621
+ * </button>
622
+ * ```
623
+ *
624
+ * @example
625
+ * Mac-specific keys:
626
+ * ```html
627
+ * <button ngxKeys
628
+ * keys="ctrl,s"
629
+ * macKeys="cmd,s"
630
+ * description="Save document"
631
+ * (click)="save()">
632
+ * Save
633
+ * </button>
634
+ * ```
635
+ *
636
+ * @example
637
+ * On non-interactive elements:
638
+ * ```html
639
+ * <div ngxKeys
640
+ * keys="?"
641
+ * description="Show help"
642
+ * [action]="showHelp">
643
+ * Help content
644
+ * </div>
645
+ * ```
646
+ */
647
+ declare class KeyboardShortcutDirective implements OnInit, OnDestroy {
648
+ private readonly keyboardShortcuts;
649
+ private readonly elementRef;
650
+ /**
651
+ * Comma-separated string of keys for the shortcut (e.g., "ctrl,s" or "alt,shift,k")
652
+ * Use either `keys` for single-step shortcuts or `steps` for multi-step shortcuts.
653
+ */
654
+ keys?: string;
655
+ /**
656
+ * Comma-separated string of keys for Mac users (e.g., "cmd,s")
657
+ * If not provided, `keys` will be used for all platforms.
658
+ */
659
+ macKeys?: string;
660
+ /**
661
+ * Multi-step shortcut as an array of key arrays.
662
+ * Each inner array represents one step in the sequence.
663
+ * Example: [['ctrl', 'k'], ['ctrl', 's']] for Ctrl+K followed by Ctrl+S
664
+ */
665
+ steps?: KeyStep[];
666
+ /**
667
+ * Multi-step shortcut for Mac users.
668
+ * Example: [['cmd', 'k'], ['cmd', 's']]
669
+ */
670
+ macSteps?: KeyStep[];
671
+ /**
672
+ * Description of what the shortcut does (displayed in help/documentation)
673
+ */
674
+ description: string;
675
+ /**
676
+ * Optional custom action to execute when the shortcut is triggered.
677
+ * If not provided, the directive will trigger a click event on the host element.
678
+ */
679
+ action?: Action;
680
+ /**
681
+ * Optional custom ID for the shortcut. If not provided, a unique ID will be generated.
682
+ * Useful for programmatically referencing the shortcut or for debugging.
683
+ */
684
+ shortcutId?: string;
685
+ /**
686
+ * Event emitted when the keyboard shortcut is triggered.
687
+ * This fires in addition to the action or click trigger.
688
+ */
689
+ readonly triggered: i0.OutputEmitterRef<void>;
690
+ /**
691
+ * Adds a data attribute to the host element for styling or testing purposes
692
+ */
693
+ get dataAttribute(): string;
694
+ private generatedId;
695
+ private isRegistered;
696
+ ngOnInit(): void;
697
+ ngOnDestroy(): void;
698
+ /**
699
+ * Parse comma-separated key string into an array
700
+ * Example: "ctrl,s" -> ["ctrl", "s"]
701
+ */
702
+ private parseKeys;
703
+ /**
704
+ * Generate a unique ID for the shortcut based on the element and keys
705
+ */
706
+ private generateUniqueId;
707
+ /**
708
+ * Validate that required inputs are provided correctly
709
+ */
710
+ private validateInputs;
711
+ static ɵfac: i0.ɵɵFactoryDeclaration<KeyboardShortcutDirective, never>;
712
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KeyboardShortcutDirective, "[ngxKeys]", never, { "keys": { "alias": "keys"; "required": false; }; "macKeys": { "alias": "macKeys"; "required": false; }; "steps": { "alias": "steps"; "required": false; }; "macSteps": { "alias": "macSteps"; "required": false; }; "description": { "alias": "description"; "required": true; }; "action": { "alias": "action"; "required": false; }; "shortcutId": { "alias": "shortcutId"; "required": false; }; }, { "triggered": "triggered"; }, never, never, true, never>;
713
+ }
714
+
715
+ export { KEYBOARD_SHORTCUTS_CONFIG, KeyboardShortcutDirective, KeyboardShortcutError, KeyboardShortcuts, KeyboardShortcutsErrorFactory, KeyboardShortcutsErrors, provideKeyboardShortcutsConfig };
716
+ export type { Action, KeyStep, KeyboardShortcut, KeyboardShortcutActiveUntil, KeyboardShortcutFilter, KeyboardShortcutGroup, KeyboardShortcutGroupOptions, KeyboardShortcutUI, KeyboardShortcutsConfig, KeyboardShortcutsErrorType };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-keys",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "A reactive Angular library for managing keyboard shortcuts with signals-based UI integration",
5
5
  "keywords": [
6
6
  "angular",