@scania-nl/tegel-angular-extensions 0.0.6 → 0.0.7
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 +41 -5
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/directives/barcode-scanner.directive.mjs +94 -0
- package/index.d.ts +51 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,8 @@ Provides simple wrappers for toast and modal (TBC) functionality using Angular 1
|
|
|
21
21
|
- Drop-in UI integrations for Tegel Angular
|
|
22
22
|
- Signal-based `ToastService` for displaying toasts
|
|
23
23
|
- Customizable toast appearance and behavior
|
|
24
|
-
3. **
|
|
24
|
+
3. **Standalone components and directives**
|
|
25
|
+
4. **Default Nginx config**
|
|
25
26
|
|
|
26
27
|
- Zero boilerplate - no Angular modules required
|
|
27
28
|
- Fully typed and configurable via DI
|
|
@@ -56,6 +57,7 @@ Provides simple wrappers for toast and modal (TBC) functionality using Angular 1
|
|
|
56
57
|
1. [Footer](#footer-component-tae-footer)
|
|
57
58
|
2. [Directives](#-directives)
|
|
58
59
|
1. [Hard Refresh](#hard-refresh-directive-taehardrefresh)
|
|
60
|
+
2. [Barcode Scanner](#barcode-scanner-directive-taebarcodescanner)
|
|
59
61
|
5. [Appendix](#appendix)
|
|
60
62
|
1. [Dockerfile Example](#runtime-config-dockerfile-example)
|
|
61
63
|
6. [License](#-license)
|
|
@@ -488,10 +490,10 @@ This is especially useful for hard-reloading tablet or mobile applications which
|
|
|
488
490
|
|
|
489
491
|
**Inputs:**
|
|
490
492
|
|
|
491
|
-
|
|
|
492
|
-
|
|
|
493
|
-
| clicksRequired | number | 3 | Number of clicks required within the window to trigger a hard refresh. |
|
|
494
|
-
| clickWindowMs | number | 500 | Time window in milliseconds between two subsequent clicks. |
|
|
493
|
+
| Property | Type | Default | Description |
|
|
494
|
+
| ---------------- | -------- | --------- | ---------------------------------------------------------------------- |
|
|
495
|
+
| `clicksRequired` | `number` | `3` | Number of clicks required within the window to trigger a hard refresh. |
|
|
496
|
+
| `clickWindowMs` | `number` | `500` | Time window in milliseconds between two subsequent clicks. |
|
|
495
497
|
|
|
496
498
|
**Example:**
|
|
497
499
|
|
|
@@ -505,6 +507,40 @@ This is especially useful for hard-reloading tablet or mobile applications which
|
|
|
505
507
|
</tds-header-brand-symbol>
|
|
506
508
|
```
|
|
507
509
|
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
### Barcode Scanner Directive (`taeBarcodeScanner`)
|
|
513
|
+
|
|
514
|
+
The `BarcodeScannerDirective` enables global barcode scanning by listening for rapid character input sequences (typically from a hardware scanner) that terminate with a specific key (default is `Enter`).
|
|
515
|
+
|
|
516
|
+
It operates outside of Angular's zone to prevent unnecessary change detection cycles on every keypress and includes built-in filtering to ignore modifier keys like `Shift`, `Ctrl`, or `Alt`, ensuring only the actual barcode data is captured.
|
|
517
|
+
|
|
518
|
+
**Inputs:**
|
|
519
|
+
|
|
520
|
+
| Input | Type | Default | Description |
|
|
521
|
+
| ---------------- | ---------------- | --------- | ------------------------------------------------------------------ |
|
|
522
|
+
| `inputWindowMs` | `number` | `100` | Max time allowed between consecutive keypresses before discarding. |
|
|
523
|
+
| `terminatorKey` | `string` | `'Enter'` | The key that signals the end of a barcode sequence. |
|
|
524
|
+
|
|
525
|
+
**Outputs:**
|
|
526
|
+
|
|
527
|
+
| Output | Type | Description |
|
|
528
|
+
| ---------------- | ---------------- | ------------------------------------------------------------------ |
|
|
529
|
+
| `barcodeScanned` | `string` | **Required**. Emits the full barcode string once completed. |
|
|
530
|
+
|
|
531
|
+
**Example:**
|
|
532
|
+
|
|
533
|
+
```html
|
|
534
|
+
<ng-container
|
|
535
|
+
taeBarcodeScanner
|
|
536
|
+
(barcodeScanned)="handleScan($event)"
|
|
537
|
+
[inputWindowMs]="100"
|
|
538
|
+
terminatorKey="Enter"
|
|
539
|
+
>
|
|
540
|
+
<p>Scanner is active. Please scan a barcode...</p>
|
|
541
|
+
</ng-container>
|
|
542
|
+
```
|
|
543
|
+
|
|
508
544
|
---
|
|
509
545
|
|
|
510
546
|
|
package/esm2022/index.mjs
CHANGED
|
@@ -16,9 +16,10 @@ export { provideStaticConfig } from './lib/env/angular/provide-static-config';
|
|
|
16
16
|
// --------------------------------------------------
|
|
17
17
|
// Directive Module Exports
|
|
18
18
|
// --------------------------------------------------
|
|
19
|
+
export { BarcodeScannerDirective } from './lib/directives/barcode-scanner.directive';
|
|
19
20
|
export { HardRefreshDirective } from './lib/directives/hard-refresh.directive';
|
|
20
21
|
// --------------------------------------------------
|
|
21
22
|
// Component Module Exports
|
|
22
23
|
// --------------------------------------------------
|
|
23
24
|
export { TaeFooterComponent } from './lib/components/tae-footer/tae-footer.component';
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL3RlZ2VsLWFuZ3VsYXItZXh0ZW5zaW9ucy9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEscURBQXFEO0FBQ3JELHVCQUF1QjtBQUN2QixxREFBcUQ7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsWUFBWSxHQUViLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBS3pELHFEQUFxRDtBQUNyRCxxQkFBcUI7QUFDckIscURBQXFEO0FBQ3JELE9BQU87QUFDUCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTdELFVBQVU7QUFDVixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNoRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUU5RSxxREFBcUQ7QUFDckQsMkJBQTJCO0FBQzNCLHFEQUFxRDtBQUNyRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNyRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUUvRSxxREFBcUQ7QUFDckQsMkJBQTJCO0FBQzNCLHFEQUFxRDtBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUb2FzdCBNb2R1bGUgRXhwb3J0c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmV4cG9ydCB7IHByb3ZpZGVUb2FzdCB9IGZyb20gJy4vbGliL3RvYXN0L3Byb3ZpZGUtdG9hc3QnO1xuZXhwb3J0IHtcbiAgREVGQVVMVF9UT0FTVF9DT05GSUcsXG4gIFRPQVNUX0NPTkZJRyxcbiAgVG9hc3RDb25maWcsXG59IGZyb20gJy4vbGliL3RvYXN0L3RvYXN0LmNvbmZpZyc7XG5leHBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICcuL2xpYi90b2FzdC90b2FzdC5zZXJ2aWNlJztcblxuLy8gTW9kZWxzXG5leHBvcnQgeyBUb2FzdCwgVG9hc3RPcHRpb25zIH0gZnJvbSAnLi9saWIvdG9hc3QvbW9kZWxzL3RvYXN0Lm1vZGVsJztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEVudiBNb2R1bGUgRXhwb3J0c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENvcmVcbmV4cG9ydCB7IGNyZWF0ZUVudktpdCB9IGZyb20gJy4vbGliL2Vudi9jb3JlL2NyZWF0ZS1lbnYta2l0JztcbmV4cG9ydCB7IHBhcnNlRW52RmlsZSB9IGZyb20gJy4vbGliL2Vudi9jb3JlL3BhcnNlLWVudi1maWxlJztcblxuLy8gQW5ndWxhclxuZXhwb3J0IHsgcHJvdmlkZVJ1bnRpbWVDb25maWcgfSBmcm9tICcuL2xpYi9lbnYvYW5ndWxhci9wcm92aWRlLXJ1bnRpbWUtY29uZmlnJztcbmV4cG9ydCB7IHByb3ZpZGVTdGF0aWNDb25maWcgfSBmcm9tICcuL2xpYi9lbnYvYW5ndWxhci9wcm92aWRlLXN0YXRpYy1jb25maWcnO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGlyZWN0aXZlIE1vZHVsZSBFeHBvcnRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZXhwb3J0IHsgQmFyY29kZVNjYW5uZXJEaXJlY3RpdmUgfSBmcm9tICcuL2xpYi9kaXJlY3RpdmVzL2JhcmNvZGUtc2Nhbm5lci5kaXJlY3RpdmUnO1xuZXhwb3J0IHsgSGFyZFJlZnJlc2hEaXJlY3RpdmUgfSBmcm9tICcuL2xpYi9kaXJlY3RpdmVzL2hhcmQtcmVmcmVzaC5kaXJlY3RpdmUnO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQ29tcG9uZW50IE1vZHVsZSBFeHBvcnRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZXhwb3J0IHsgVGFlRm9vdGVyQ29tcG9uZW50IH0gZnJvbSAnLi9saWIvY29tcG9uZW50cy90YWUtZm9vdGVyL3RhZS1mb290ZXIuY29tcG9uZW50JztcbiJdfQ==
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { DOCUMENT } from '@angular/common';
|
|
2
|
+
import { Directive, inject, input, NgZone, output } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { catchError, EMPTY, exhaustMap, filter, fromEvent, map, share, startWith, takeWhile, timeout, toArray, } from 'rxjs';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* Directive that listens for rapid key sequences ending in a terminator key
|
|
8
|
+
* (default: Enter) and emits the collected characters as a barcode string.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* <ng-container
|
|
12
|
+
* taeBarcodeScanner
|
|
13
|
+
* (barcodeScanned)="handleScan($event)"
|
|
14
|
+
* [inputWindowMs]="100"
|
|
15
|
+
* terminatorKey="Enter"
|
|
16
|
+
* />
|
|
17
|
+
*/
|
|
18
|
+
export class BarcodeScannerDirective {
|
|
19
|
+
/**
|
|
20
|
+
* Angular zone used to run key handling outside of change detection.
|
|
21
|
+
*/
|
|
22
|
+
_ngZone = inject(NgZone);
|
|
23
|
+
/**
|
|
24
|
+
* Document reference for attaching global keydown event listeners.
|
|
25
|
+
*/
|
|
26
|
+
_document = inject(DOCUMENT);
|
|
27
|
+
/**
|
|
28
|
+
* Maximum time window in milliseconds between consecutive keypresses.
|
|
29
|
+
* Sequences exceeding this duration are discarded.
|
|
30
|
+
*
|
|
31
|
+
* @default 100
|
|
32
|
+
*/
|
|
33
|
+
inputWindowMs = input(100);
|
|
34
|
+
/**
|
|
35
|
+
* Key that terminates and completes a barcode sequence.
|
|
36
|
+
*
|
|
37
|
+
* @default "Enter"
|
|
38
|
+
*/
|
|
39
|
+
terminatorKey = input('Enter');
|
|
40
|
+
/**
|
|
41
|
+
* Emits the complete barcode string captured from the scanner.
|
|
42
|
+
* * @remarks
|
|
43
|
+
* This output is required by the directive selector.
|
|
44
|
+
*/
|
|
45
|
+
barcodeScanned = output();
|
|
46
|
+
/**
|
|
47
|
+
* Sets up the global keydown listener and barcode detection pipeline.
|
|
48
|
+
* The pipeline runs outside Angular's zone and only re-enters when a barcode
|
|
49
|
+
* is emitted, to avoid triggering change detection on every keypress.
|
|
50
|
+
*/
|
|
51
|
+
constructor() {
|
|
52
|
+
// Run the key handling pipeline outside Angular's zone to avoid triggering
|
|
53
|
+
// change detection on every keypress.
|
|
54
|
+
this._ngZone.runOutsideAngular(() => {
|
|
55
|
+
// Create a global stream of valid keydown events
|
|
56
|
+
const key$ = fromEvent(this._document, 'keydown').pipe(
|
|
57
|
+
// Auto-unsubscribe when the directive is destroyed.
|
|
58
|
+
takeUntilDestroyed(),
|
|
59
|
+
// Allow only character keys and the terminator key
|
|
60
|
+
// Modifier keys (Shift, Ctrl, Alt, Meta) are ignored
|
|
61
|
+
filter((e) => e.key.length === 1 || e.key === this.terminatorKey()),
|
|
62
|
+
// Share a single keydown stream between outer and inner subscribers.
|
|
63
|
+
share());
|
|
64
|
+
key$
|
|
65
|
+
.pipe(
|
|
66
|
+
// Start a new scan session on the first key event
|
|
67
|
+
exhaustMap((firstEvent) => key$.pipe(startWith(firstEvent),
|
|
68
|
+
// Collect until the terminator key is pressed
|
|
69
|
+
takeWhile((e) => e.key !== this.terminatorKey()),
|
|
70
|
+
// Abort the sequence if no key is pressed within the time window
|
|
71
|
+
timeout(this.inputWindowMs()),
|
|
72
|
+
// Materialize the sequence as an array of KeyboardEvents
|
|
73
|
+
toArray(),
|
|
74
|
+
// Ignore empty sequences (e.g. stray terminator presses)
|
|
75
|
+
filter((events) => events.length > 0),
|
|
76
|
+
// On timeout (or other error), drop the sequence silently
|
|
77
|
+
catchError(() => EMPTY))),
|
|
78
|
+
// Map collected key events to their key values and join into a string
|
|
79
|
+
map((events) => events.map((e) => e.key).join('')))
|
|
80
|
+
// Re-enter Angular's zone only to emit the completed barcode.
|
|
81
|
+
.subscribe((barcode) => this._ngZone.run(() => this.barcodeScanned.emit(barcode)));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BarcodeScannerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
85
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: BarcodeScannerDirective, isStandalone: true, selector: "[taeBarcodeScanner]", inputs: { inputWindowMs: { classPropertyName: "inputWindowMs", publicName: "inputWindowMs", isSignal: true, isRequired: false, transformFunction: null }, terminatorKey: { classPropertyName: "terminatorKey", publicName: "terminatorKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { barcodeScanned: "barcodeScanned" }, ngImport: i0 });
|
|
86
|
+
}
|
|
87
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: BarcodeScannerDirective, decorators: [{
|
|
88
|
+
type: Directive,
|
|
89
|
+
args: [{
|
|
90
|
+
selector: '[taeBarcodeScanner]',
|
|
91
|
+
standalone: true,
|
|
92
|
+
}]
|
|
93
|
+
}], ctorParameters: () => [] });
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyY29kZS1zY2FubmVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvdGVnZWwtYW5ndWxhci1leHRlbnNpb25zL3NyYy9saWIvZGlyZWN0aXZlcy9iYXJjb2RlLXNjYW5uZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsVUFBVSxFQUNWLEtBQUssRUFDTCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFNBQVMsRUFDVCxHQUFHLEVBQ0gsS0FBSyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBQ1QsT0FBTyxFQUNQLE9BQU8sR0FDUixNQUFNLE1BQU0sQ0FBQzs7QUFFZDs7Ozs7Ozs7Ozs7R0FXRztBQUtILE1BQU0sT0FBTyx1QkFBdUI7SUFDbEM7O09BRUc7SUFDYyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTFDOztPQUVHO0lBQ2MsU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUU5Qzs7Ozs7T0FLRztJQUNNLGFBQWEsR0FBRyxLQUFLLENBQVMsR0FBRyxDQUFDLENBQUM7SUFFNUM7Ozs7T0FJRztJQUNNLGFBQWEsR0FBRyxLQUFLLENBQVMsT0FBTyxDQUFDLENBQUM7SUFFaEQ7Ozs7T0FJRztJQUNNLGNBQWMsR0FBRyxNQUFNLEVBQVUsQ0FBQztJQUUzQzs7OztPQUlHO0lBQ0g7UUFDRSwyRUFBMkU7UUFDM0Usc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2xDLGlEQUFpRDtZQUNqRCxNQUFNLElBQUksR0FBRyxTQUFTLENBQWdCLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsSUFBSTtZQUNuRSxvREFBb0Q7WUFDcEQsa0JBQWtCLEVBQUU7WUFDcEIsbURBQW1EO1lBQ25ELHFEQUFxRDtZQUNyRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuRSxxRUFBcUU7WUFDckUsS0FBSyxFQUFFLENBQ1IsQ0FBQztZQUVGLElBQUk7aUJBQ0QsSUFBSTtZQUNILGtEQUFrRDtZQUNsRCxVQUFVLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUN4QixJQUFJLENBQUMsSUFBSSxDQUNQLFNBQVMsQ0FBQyxVQUFVLENBQUM7WUFDckIsOENBQThDO1lBQzlDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDaEQsaUVBQWlFO1lBQ2pFLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDN0IseURBQXlEO1lBQ3pELE9BQU8sRUFBRTtZQUNULHlEQUF5RDtZQUN6RCxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ3JDLDBEQUEwRDtZQUMxRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQ3hCLENBQ0Y7WUFDRCxzRUFBc0U7WUFDdEUsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQ25EO2dCQUNELDhEQUE4RDtpQkFDN0QsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FDMUQsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0EvRVUsdUJBQXVCOzRGQUF2Qix1QkFBdUI7OzRGQUF2Qix1QkFBdUI7a0JBSm5DLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLHFCQUFxQjtvQkFDL0IsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRGlyZWN0aXZlLCBpbmplY3QsIGlucHV0LCBOZ1pvbmUsIG91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHtcbiAgY2F0Y2hFcnJvcixcbiAgRU1QVFksXG4gIGV4aGF1c3RNYXAsXG4gIGZpbHRlcixcbiAgZnJvbUV2ZW50LFxuICBtYXAsXG4gIHNoYXJlLFxuICBzdGFydFdpdGgsXG4gIHRha2VXaGlsZSxcbiAgdGltZW91dCxcbiAgdG9BcnJheSxcbn0gZnJvbSAncnhqcyc7XG5cbi8qKlxuICogRGlyZWN0aXZlIHRoYXQgbGlzdGVucyBmb3IgcmFwaWQga2V5IHNlcXVlbmNlcyBlbmRpbmcgaW4gYSB0ZXJtaW5hdG9yIGtleVxuICogKGRlZmF1bHQ6IEVudGVyKSBhbmQgZW1pdHMgdGhlIGNvbGxlY3RlZCBjaGFyYWN0ZXJzIGFzIGEgYmFyY29kZSBzdHJpbmcuXG4gKlxuICogQGV4YW1wbGVcbiAqIDxuZy1jb250YWluZXJcbiAqICAgdGFlQmFyY29kZVNjYW5uZXJcbiAqICAgKGJhcmNvZGVTY2FubmVkKT1cImhhbmRsZVNjYW4oJGV2ZW50KVwiXG4gKiAgIFtpbnB1dFdpbmRvd01zXT1cIjEwMFwiXG4gKiAgIHRlcm1pbmF0b3JLZXk9XCJFbnRlclwiXG4gKiAvPlxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbdGFlQmFyY29kZVNjYW5uZXJdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQmFyY29kZVNjYW5uZXJEaXJlY3RpdmUge1xuICAvKipcbiAgICogQW5ndWxhciB6b25lIHVzZWQgdG8gcnVuIGtleSBoYW5kbGluZyBvdXRzaWRlIG9mIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmUgPSBpbmplY3QoTmdab25lKTtcblxuICAvKipcbiAgICogRG9jdW1lbnQgcmVmZXJlbmNlIGZvciBhdHRhY2hpbmcgZ2xvYmFsIGtleWRvd24gZXZlbnQgbGlzdGVuZXJzLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIHRpbWUgd2luZG93IGluIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIGNvbnNlY3V0aXZlIGtleXByZXNzZXMuXG4gICAqIFNlcXVlbmNlcyBleGNlZWRpbmcgdGhpcyBkdXJhdGlvbiBhcmUgZGlzY2FyZGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxMDBcbiAgICovXG4gIHJlYWRvbmx5IGlucHV0V2luZG93TXMgPSBpbnB1dDxudW1iZXI+KDEwMCk7XG5cbiAgLyoqXG4gICAqIEtleSB0aGF0IHRlcm1pbmF0ZXMgYW5kIGNvbXBsZXRlcyBhIGJhcmNvZGUgc2VxdWVuY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiRW50ZXJcIlxuICAgKi9cbiAgcmVhZG9ubHkgdGVybWluYXRvcktleSA9IGlucHV0PHN0cmluZz4oJ0VudGVyJyk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBjb21wbGV0ZSBiYXJjb2RlIHN0cmluZyBjYXB0dXJlZCBmcm9tIHRoZSBzY2FubmVyLlxuICAgKiAqIEByZW1hcmtzXG4gICAqIFRoaXMgb3V0cHV0IGlzIHJlcXVpcmVkIGJ5IHRoZSBkaXJlY3RpdmUgc2VsZWN0b3IuXG4gICAqL1xuICByZWFkb25seSBiYXJjb2RlU2Nhbm5lZCA9IG91dHB1dDxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIFNldHMgdXAgdGhlIGdsb2JhbCBrZXlkb3duIGxpc3RlbmVyIGFuZCBiYXJjb2RlIGRldGVjdGlvbiBwaXBlbGluZS5cbiAgICogVGhlIHBpcGVsaW5lIHJ1bnMgb3V0c2lkZSBBbmd1bGFyJ3Mgem9uZSBhbmQgb25seSByZS1lbnRlcnMgd2hlbiBhIGJhcmNvZGVcbiAgICogaXMgZW1pdHRlZCwgdG8gYXZvaWQgdHJpZ2dlcmluZyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIGV2ZXJ5IGtleXByZXNzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gUnVuIHRoZSBrZXkgaGFuZGxpbmcgcGlwZWxpbmUgb3V0c2lkZSBBbmd1bGFyJ3Mgem9uZSB0byBhdm9pZCB0cmlnZ2VyaW5nXG4gICAgLy8gY2hhbmdlIGRldGVjdGlvbiBvbiBldmVyeSBrZXlwcmVzcy5cbiAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgLy8gQ3JlYXRlIGEgZ2xvYmFsIHN0cmVhbSBvZiB2YWxpZCBrZXlkb3duIGV2ZW50c1xuICAgICAgY29uc3Qga2V5JCA9IGZyb21FdmVudDxLZXlib2FyZEV2ZW50Pih0aGlzLl9kb2N1bWVudCwgJ2tleWRvd24nKS5waXBlKFxuICAgICAgICAvLyBBdXRvLXVuc3Vic2NyaWJlIHdoZW4gdGhlIGRpcmVjdGl2ZSBpcyBkZXN0cm95ZWQuXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgICAvLyBBbGxvdyBvbmx5IGNoYXJhY3RlciBrZXlzIGFuZCB0aGUgdGVybWluYXRvciBrZXlcbiAgICAgICAgLy8gTW9kaWZpZXIga2V5cyAoU2hpZnQsIEN0cmwsIEFsdCwgTWV0YSkgYXJlIGlnbm9yZWRcbiAgICAgICAgZmlsdGVyKChlKSA9PiBlLmtleS5sZW5ndGggPT09IDEgfHwgZS5rZXkgPT09IHRoaXMudGVybWluYXRvcktleSgpKSxcbiAgICAgICAgLy8gU2hhcmUgYSBzaW5nbGUga2V5ZG93biBzdHJlYW0gYmV0d2VlbiBvdXRlciBhbmQgaW5uZXIgc3Vic2NyaWJlcnMuXG4gICAgICAgIHNoYXJlKCksXG4gICAgICApO1xuXG4gICAgICBrZXkkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIC8vIFN0YXJ0IGEgbmV3IHNjYW4gc2Vzc2lvbiBvbiB0aGUgZmlyc3Qga2V5IGV2ZW50XG4gICAgICAgICAgZXhoYXVzdE1hcCgoZmlyc3RFdmVudCkgPT5cbiAgICAgICAgICAgIGtleSQucGlwZShcbiAgICAgICAgICAgICAgc3RhcnRXaXRoKGZpcnN0RXZlbnQpLFxuICAgICAgICAgICAgICAvLyBDb2xsZWN0IHVudGlsIHRoZSB0ZXJtaW5hdG9yIGtleSBpcyBwcmVzc2VkXG4gICAgICAgICAgICAgIHRha2VXaGlsZSgoZSkgPT4gZS5rZXkgIT09IHRoaXMudGVybWluYXRvcktleSgpKSxcbiAgICAgICAgICAgICAgLy8gQWJvcnQgdGhlIHNlcXVlbmNlIGlmIG5vIGtleSBpcyBwcmVzc2VkIHdpdGhpbiB0aGUgdGltZSB3aW5kb3dcbiAgICAgICAgICAgICAgdGltZW91dCh0aGlzLmlucHV0V2luZG93TXMoKSksXG4gICAgICAgICAgICAgIC8vIE1hdGVyaWFsaXplIHRoZSBzZXF1ZW5jZSBhcyBhbiBhcnJheSBvZiBLZXlib2FyZEV2ZW50c1xuICAgICAgICAgICAgICB0b0FycmF5KCksXG4gICAgICAgICAgICAgIC8vIElnbm9yZSBlbXB0eSBzZXF1ZW5jZXMgKGUuZy4gc3RyYXkgdGVybWluYXRvciBwcmVzc2VzKVxuICAgICAgICAgICAgICBmaWx0ZXIoKGV2ZW50cykgPT4gZXZlbnRzLmxlbmd0aCA+IDApLFxuICAgICAgICAgICAgICAvLyBPbiB0aW1lb3V0IChvciBvdGhlciBlcnJvciksIGRyb3AgdGhlIHNlcXVlbmNlIHNpbGVudGx5XG4gICAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gRU1QVFkpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICAgIC8vIE1hcCBjb2xsZWN0ZWQga2V5IGV2ZW50cyB0byB0aGVpciBrZXkgdmFsdWVzIGFuZCBqb2luIGludG8gYSBzdHJpbmdcbiAgICAgICAgICBtYXAoKGV2ZW50cykgPT4gZXZlbnRzLm1hcCgoZSkgPT4gZS5rZXkpLmpvaW4oJycpKSxcbiAgICAgICAgKVxuICAgICAgICAvLyBSZS1lbnRlciBBbmd1bGFyJ3Mgem9uZSBvbmx5IHRvIGVtaXQgdGhlIGNvbXBsZXRlZCBiYXJjb2RlLlxuICAgICAgICAuc3Vic2NyaWJlKChiYXJjb2RlKSA9PlxuICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy5iYXJjb2RlU2Nhbm5lZC5lbWl0KGJhcmNvZGUpKSxcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxufVxuIl19
|
package/index.d.ts
CHANGED
|
@@ -464,6 +464,56 @@ type ProvideStaticConfigOptions<T> = {
|
|
|
464
464
|
*/
|
|
465
465
|
declare function provideStaticConfig<T>(env: T | undefined, options: ProvideStaticConfigOptions<T>): EnvironmentProviders;
|
|
466
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Directive that listens for rapid key sequences ending in a terminator key
|
|
469
|
+
* (default: Enter) and emits the collected characters as a barcode string.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* <ng-container
|
|
473
|
+
* taeBarcodeScanner
|
|
474
|
+
* (barcodeScanned)="handleScan($event)"
|
|
475
|
+
* [inputWindowMs]="100"
|
|
476
|
+
* terminatorKey="Enter"
|
|
477
|
+
* />
|
|
478
|
+
*/
|
|
479
|
+
declare class BarcodeScannerDirective {
|
|
480
|
+
/**
|
|
481
|
+
* Angular zone used to run key handling outside of change detection.
|
|
482
|
+
*/
|
|
483
|
+
private readonly _ngZone;
|
|
484
|
+
/**
|
|
485
|
+
* Document reference for attaching global keydown event listeners.
|
|
486
|
+
*/
|
|
487
|
+
private readonly _document;
|
|
488
|
+
/**
|
|
489
|
+
* Maximum time window in milliseconds between consecutive keypresses.
|
|
490
|
+
* Sequences exceeding this duration are discarded.
|
|
491
|
+
*
|
|
492
|
+
* @default 100
|
|
493
|
+
*/
|
|
494
|
+
readonly inputWindowMs: _angular_core.InputSignal<number>;
|
|
495
|
+
/**
|
|
496
|
+
* Key that terminates and completes a barcode sequence.
|
|
497
|
+
*
|
|
498
|
+
* @default "Enter"
|
|
499
|
+
*/
|
|
500
|
+
readonly terminatorKey: _angular_core.InputSignal<string>;
|
|
501
|
+
/**
|
|
502
|
+
* Emits the complete barcode string captured from the scanner.
|
|
503
|
+
* * @remarks
|
|
504
|
+
* This output is required by the directive selector.
|
|
505
|
+
*/
|
|
506
|
+
readonly barcodeScanned: _angular_core.OutputEmitterRef<string>;
|
|
507
|
+
/**
|
|
508
|
+
* Sets up the global keydown listener and barcode detection pipeline.
|
|
509
|
+
* The pipeline runs outside Angular's zone and only re-enters when a barcode
|
|
510
|
+
* is emitted, to avoid triggering change detection on every keypress.
|
|
511
|
+
*/
|
|
512
|
+
constructor();
|
|
513
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BarcodeScannerDirective, never>;
|
|
514
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BarcodeScannerDirective, "[taeBarcodeScanner]", never, { "inputWindowMs": { "alias": "inputWindowMs"; "required": false; "isSignal": true; }; "terminatorKey": { "alias": "terminatorKey"; "required": false; "isSignal": true; }; }, { "barcodeScanned": "barcodeScanned"; }, never, never, true, never>;
|
|
515
|
+
}
|
|
516
|
+
|
|
467
517
|
/**
|
|
468
518
|
* Directive that triggers a hard page refresh when the host element is clicked
|
|
469
519
|
* a specified number of times within a configurable time window.
|
|
@@ -543,5 +593,5 @@ declare class TaeFooterComponent {
|
|
|
543
593
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TaeFooterComponent, "tae-footer", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "version": { "alias": "version"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
544
594
|
}
|
|
545
595
|
|
|
546
|
-
export { DEFAULT_TOAST_CONFIG, HardRefreshDirective, TOAST_CONFIG, TaeFooterComponent, ToastService, createEnvKit, parseEnvFile, provideRuntimeConfig, provideStaticConfig, provideToast };
|
|
596
|
+
export { BarcodeScannerDirective, DEFAULT_TOAST_CONFIG, HardRefreshDirective, TOAST_CONFIG, TaeFooterComponent, ToastService, createEnvKit, parseEnvFile, provideRuntimeConfig, provideStaticConfig, provideToast };
|
|
547
597
|
export type { Toast, ToastConfig, ToastOptions };
|