ngx-keys 1.2.0 → 1.3.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 +450 -15
- package/fesm2022/ngx-keys.mjs +624 -60
- package/fesm2022/ngx-keys.mjs.map +1 -1
- package/index.d.ts +293 -13
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
import * as
|
|
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:
|
|
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$:
|
|
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$:
|
|
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
|
-
/**
|
|
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:
|
|
374
|
-
static ɵprov:
|
|
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
|
-
|
|
436
|
-
|
|
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 };
|