@ruc-lib/input-otp 3.1.0 → 3.2.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.
@@ -1,153 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { EventEmitter, ViewChildren, Input, Output, Component } from '@angular/core';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { MatIconModule } from '@angular/material/icon';
6
- import * as i2 from '@angular/forms';
7
- import { FormsModule } from '@angular/forms';
8
-
9
- const BACKSPACE_KEY = "Backspace";
10
-
11
- class RuclibInputOtpComponent {
12
- constructor() {
13
- this.DEFAULT_OTP_LENGTH = 6;
14
- this.TIME_LEFT = "Time left";
15
- this.EXPIRED_MSG = "OTP expired. Please request a new one.";
16
- this.rucEvent = new EventEmitter();
17
- this.rucInputData = {};
18
- this.timeLeft = 0;
19
- this.timerId = null;
20
- this.otpValues = [];
21
- }
22
- ngOnInit() {
23
- this.otpValues = Array(this.rucInputData.length || 6).fill('');
24
- if (this.rucInputData.timeLimit) {
25
- this.timeLeft = this.rucInputData.timeLimit;
26
- }
27
- // Set default for copyProtection
28
- if (this.rucInputData.copyProtection === undefined) {
29
- this.rucInputData.copyProtection = true;
30
- }
31
- }
32
- ngAfterViewInit() {
33
- // Merge input config with defaults
34
- this.otpValues = Array(this.rucInputData.length || 6).fill('');
35
- if (this.rucInputData.autoFocus) {
36
- setTimeout(() => this.inputs.first?.nativeElement.focus(), 0); // Auto-focus first input
37
- }
38
- if (this.rucInputData.timeLimit) {
39
- this.timeLeft = this.rucInputData.timeLimit;
40
- this.timerId = setInterval(() => {
41
- this.timeLeft--;
42
- if (this.timeLeft <= 0) {
43
- clearInterval(this.timerId);
44
- this.disableAllInputs();
45
- this.rucEvent.emit({ eventName: 'timeout', eventOutput: null });
46
- }
47
- }, 1000);
48
- }
49
- }
50
- // Handle OTP input
51
- handleInput(event, index) {
52
- const input = event.target;
53
- const value = input.value;
54
- if (this.rucInputData.integerOnly && !/^\d*$/.test(value)) {
55
- input.value = ''; // Allow integers only
56
- this.otpValues[index] = '';
57
- return;
58
- }
59
- this.otpValues[index] = value.slice(-1); // Take last digit
60
- input.value = this.otpValues[index];
61
- // Auto-jump to next input
62
- if (value && index < (this.rucInputData.length || 6) - 1 && this.rucInputData.autoFocus) {
63
- this.inputs.toArray()[index + 1].nativeElement.focus();
64
- }
65
- // Auto-submit on complete
66
- if (this.rucInputData.autoSubmit && this.isOtpComplete(this.otpValues)) {
67
- if (this.timerId) {
68
- clearInterval(this.timerId);
69
- this.timerId = null;
70
- }
71
- this.rucEvent.emit({ eventName: 'completed', eventOutput: this.otpValues.join('') });
72
- }
73
- }
74
- // Handle Keyboard navigation
75
- handleKeyDown(event, index) {
76
- const input = event.target;
77
- if (event.key === BACKSPACE_KEY && !input.value && index > 0 && this.rucInputData.autoFocus) {
78
- this.inputs.toArray()[index - 1].nativeElement.focus();
79
- }
80
- else if (event.key === 'ArrowLeft' && index > 0) {
81
- event.preventDefault();
82
- this.inputs.toArray()[index - 1].nativeElement.focus();
83
- }
84
- else if (event.key === 'ArrowRight' && index < (this.rucInputData.length || 6) - 1) {
85
- event.preventDefault();
86
- this.inputs.toArray()[index + 1].nativeElement.focus();
87
- }
88
- }
89
- //Handle Paste Event
90
- handlePaste(event) {
91
- event.preventDefault();
92
- let pasteData = event.clipboardData?.getData('text');
93
- if (this.rucInputData.integerOnly) {
94
- pasteData = pasteData?.replace(/\D/g, ''); // Extract digits only
95
- }
96
- if (!pasteData)
97
- return;
98
- const pasteLength = Math.min(pasteData.length, this.rucInputData.length || 6);
99
- for (let i = 0; i < pasteLength; i++) {
100
- this.otpValues[i] = pasteData[i];
101
- this.inputs.toArray()[i].nativeElement.value = pasteData[i];
102
- }
103
- // Focus last filled input or last input
104
- const focusIndex = pasteLength < (this.rucInputData.length || 6) ? pasteLength : (this.rucInputData.length || 6) - 1;
105
- this.inputs.toArray()[focusIndex].nativeElement.focus();
106
- // Auto-submit if complete
107
- if (this.rucInputData.autoSubmit && this.isOtpComplete(this.otpValues)) {
108
- if (this.timerId) {
109
- clearInterval(this.timerId);
110
- this.timerId = null;
111
- }
112
- this.rucEvent.emit({ eventName: 'completed', eventOutput: this.otpValues.join('') });
113
- }
114
- }
115
- //Check if OTP is completed
116
- isOtpComplete(otpArray) {
117
- return otpArray.every(val => val.trim() !== '');
118
- }
119
- // Disable inputs
120
- disableAllInputs() {
121
- this.inputs.forEach((inputRef) => {
122
- inputRef.nativeElement.disabled = true;
123
- });
124
- }
125
- //Clear Interval
126
- ngOnDestroy() {
127
- if (this.timerId) {
128
- clearInterval(this.timerId);
129
- }
130
- }
131
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibInputOtpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
132
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: RuclibInputOtpComponent, isStandalone: true, selector: "uxp-ruclib-input-otp", inputs: { customTheme: "customTheme", rucInputData: "rucInputData" }, outputs: { rucEvent: "rucEvent" }, viewQueries: [{ propertyName: "inputs", predicate: ["otpInput"], descendants: true }], ngImport: i0, template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n @for (_ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); track _; let i = $index) {\r\n <input\r\n #otpInput\r\n [type]=\"rucInputData.mask ? 'password' : 'text'\"\r\n [ngClass]=\"[\r\n 'otp-input',\r\n rucInputData.templateType || 'rectangle',\r\n rucInputData.validationState === 'valid' ? 'is-valid' : '',\r\n rucInputData.validationState === 'invalid' ? 'is-invalid' : ''\r\n ]\"\r\n maxlength=\"1\"\r\n [(ngModel)]=\"otpValues[i]\"\r\n (input)=\"handleInput($event, i)\"\r\n (copy)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (paste)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (contextmenu)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (keydown)=\"handleKeyDown($event, i)\"\r\n [attr.inputmode]=\"rucInputData.integerOnly ? 'numeric' : 'text'\"\r\n [pattern]=\"rucInputData.integerOnly ? '[0-9]*' : '.*'\"\r\n autocomplete=\"one-time-code\">\r\n }\r\n</div>\r\n<!-- Timer -->\r\n@if (rucInputData.timeLimit) {\r\n <div class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n </div>\r\n}\r\n<!-- Timeout message -->\r\n@if (rucInputData.timeLimit && timeLeft === 0) {\r\n <div class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n </div>\r\n}\r\n\r\n", styles: [".otp-container{display:flex;gap:10px;justify-content:center}.otp-input{text-align:center;font-size:18px;border:1px solid #ccc;border-radius:4px;outline:none;transition:border-color .2s}.otp-input:focus{border-color:#007bff;box-shadow:0 0 5px #007bff4d}.otp-input::-webkit-outer-spin-button,.otp-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.otp-input[type=number]{-moz-appearance:textfield}.small .otp-input{width:30px;height:30px;font-size:14px}.medium .otp-input{width:40px;height:40px;font-size:18px}.large .otp-input{width:50px;height:50px;font-size:22px}.otp-timer{text-align:center;font-size:.9rem;color:#d9534f;font-weight:700}.otp-timeout-message{text-align:center;color:#d9534f;font-size:.9rem;margin-top:.5rem}.otp-input.rectangle{border-radius:8px}.otp-input.circle{border-radius:50%}.otp-input.underscore{border:none;border-bottom:2px solid #ccc;border-radius:0;background-color:transparent}.otp-input.is-valid{border-color:#28a745;background-color:#e6ffed}.otp-input.is-invalid{border-color:#dc3545;background-color:#ffe6e6}.dark-theme .otp-input:not(.is-invalid){color:#fff;background-color:#333}.light-theme .otp-input:not(.is-invalid){color:#000}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
133
- }
134
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibInputOtpComponent, decorators: [{
135
- type: Component,
136
- args: [{ selector: 'uxp-ruclib-input-otp', imports: [CommonModule, MatIconModule, FormsModule], template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n @for (_ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); track _; let i = $index) {\r\n <input\r\n #otpInput\r\n [type]=\"rucInputData.mask ? 'password' : 'text'\"\r\n [ngClass]=\"[\r\n 'otp-input',\r\n rucInputData.templateType || 'rectangle',\r\n rucInputData.validationState === 'valid' ? 'is-valid' : '',\r\n rucInputData.validationState === 'invalid' ? 'is-invalid' : ''\r\n ]\"\r\n maxlength=\"1\"\r\n [(ngModel)]=\"otpValues[i]\"\r\n (input)=\"handleInput($event, i)\"\r\n (copy)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (paste)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (contextmenu)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (keydown)=\"handleKeyDown($event, i)\"\r\n [attr.inputmode]=\"rucInputData.integerOnly ? 'numeric' : 'text'\"\r\n [pattern]=\"rucInputData.integerOnly ? '[0-9]*' : '.*'\"\r\n autocomplete=\"one-time-code\">\r\n }\r\n</div>\r\n<!-- Timer -->\r\n@if (rucInputData.timeLimit) {\r\n <div class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n </div>\r\n}\r\n<!-- Timeout message -->\r\n@if (rucInputData.timeLimit && timeLeft === 0) {\r\n <div class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n </div>\r\n}\r\n\r\n", styles: [".otp-container{display:flex;gap:10px;justify-content:center}.otp-input{text-align:center;font-size:18px;border:1px solid #ccc;border-radius:4px;outline:none;transition:border-color .2s}.otp-input:focus{border-color:#007bff;box-shadow:0 0 5px #007bff4d}.otp-input::-webkit-outer-spin-button,.otp-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.otp-input[type=number]{-moz-appearance:textfield}.small .otp-input{width:30px;height:30px;font-size:14px}.medium .otp-input{width:40px;height:40px;font-size:18px}.large .otp-input{width:50px;height:50px;font-size:22px}.otp-timer{text-align:center;font-size:.9rem;color:#d9534f;font-weight:700}.otp-timeout-message{text-align:center;color:#d9534f;font-size:.9rem;margin-top:.5rem}.otp-input.rectangle{border-radius:8px}.otp-input.circle{border-radius:50%}.otp-input.underscore{border:none;border-bottom:2px solid #ccc;border-radius:0;background-color:transparent}.otp-input.is-valid{border-color:#28a745;background-color:#e6ffed}.otp-input.is-invalid{border-color:#dc3545;background-color:#ffe6e6}.dark-theme .otp-input:not(.is-invalid){color:#fff;background-color:#333}.light-theme .otp-input:not(.is-invalid){color:#000}\n"] }]
137
- }], propDecorators: { rucEvent: [{
138
- type: Output
139
- }], customTheme: [{
140
- type: Input
141
- }], rucInputData: [{
142
- type: Input
143
- }], inputs: [{
144
- type: ViewChildren,
145
- args: ['otpInput']
146
- }] } });
147
-
148
- /**
149
- * Generated bundle index. Do not edit.
150
- */
151
-
152
- export { RuclibInputOtpComponent };
153
- //# sourceMappingURL=ruc-lib-input-otp.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ruc-lib-input-otp.mjs","sources":["../../src/modal/constants.ts","../../src/lib/ruclib-input-otp/ruclib-input-otp.component.ts","../../src/lib/ruclib-input-otp/ruclib-input-otp.component.html","../../src/ruc-lib-input-otp.ts"],"sourcesContent":["export const BACKSPACE_KEY = \"Backspace\"","import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, QueryList, ViewChildren } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { InputOtpConfig } from '../../modal/input-otp-config';\r\nimport { BACKSPACE_KEY } from '../../modal/constants';\r\n\r\n@Component({\r\n selector: 'uxp-ruclib-input-otp',\r\n imports: [CommonModule, MatIconModule, FormsModule],\r\n templateUrl: './ruclib-input-otp.component.html',\r\n styleUrl: './ruclib-input-otp.component.scss'\r\n})\r\nexport class RuclibInputOtpComponent implements OnInit, AfterViewInit, OnDestroy {\r\n readonly DEFAULT_OTP_LENGTH = 6;\r\n readonly TIME_LEFT = \"Time left\";\r\n readonly EXPIRED_MSG = \"OTP expired. Please request a new one.\"\r\n\r\n @Output() rucEvent = new EventEmitter<any>();\r\n @Input() customTheme?: string;\r\n\r\n @Input() rucInputData: InputOtpConfig = {};\r\n timeLeft = 0;\r\n timerId: any = null;\r\n\r\n @ViewChildren('otpInput') inputs!: QueryList<ElementRef<HTMLInputElement>>;\r\n\r\n otpValues: string[] = [];\r\n\r\n ngOnInit(): void {\r\n this.otpValues = Array(this.rucInputData.length || 6).fill('');\r\n if (this.rucInputData.timeLimit) {\r\n this.timeLeft = this.rucInputData.timeLimit;\r\n }\r\n\r\n // Set default for copyProtection\r\n if (this.rucInputData.copyProtection === undefined) {\r\n this.rucInputData.copyProtection = true;\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Merge input config with defaults\r\n this.otpValues = Array(this.rucInputData.length || 6).fill('');\r\n if (this.rucInputData.autoFocus) {\r\n setTimeout(() => this.inputs.first?.nativeElement.focus(), 0); // Auto-focus first input\r\n }\r\n\r\n if (this.rucInputData.timeLimit) {\r\n this.timeLeft = this.rucInputData.timeLimit;\r\n this.timerId = setInterval(() => {\r\n this.timeLeft--;\r\n if (this.timeLeft <= 0) {\r\n clearInterval(this.timerId);\r\n this.disableAllInputs();\r\n this.rucEvent.emit({ eventName: 'timeout', eventOutput: null });\r\n }\r\n }, 1000);\r\n }\r\n }\r\n// Handle OTP input\r\n handleInput(event: Event, index: number): void {\r\n const input = event.target as HTMLInputElement;\r\n const value = input.value;\r\n\r\n if (this.rucInputData.integerOnly && !/^\\d*$/.test(value)) {\r\n input.value = ''; // Allow integers only\r\n this.otpValues[index] = '';\r\n return;\r\n }\r\n\r\n this.otpValues[index] = value.slice(-1); // Take last digit\r\n input.value = this.otpValues[index];\r\n\r\n // Auto-jump to next input\r\n if (value && index < (this.rucInputData.length || 6) - 1 && this.rucInputData.autoFocus) {\r\n this.inputs.toArray()[index + 1].nativeElement.focus();\r\n }\r\n\r\n // Auto-submit on complete\r\n if (this.rucInputData.autoSubmit && this.isOtpComplete(this.otpValues)) {\r\n if (this.timerId) {\r\n clearInterval(this.timerId);\r\n this.timerId = null;\r\n }\r\n this.rucEvent.emit({ eventName: 'completed', eventOutput: this.otpValues.join('') });\r\n }\r\n }\r\n\r\n// Handle Keyboard navigation\r\n handleKeyDown(event: KeyboardEvent, index: number): void {\r\n const input = event.target as HTMLInputElement;\r\n\r\n if (event.key === BACKSPACE_KEY && !input.value && index > 0 && this.rucInputData.autoFocus) {\r\n this.inputs.toArray()[index - 1].nativeElement.focus();\r\n } else if (event.key === 'ArrowLeft' && index > 0) {\r\n event.preventDefault();\r\n this.inputs.toArray()[index - 1].nativeElement.focus();\r\n } else if (event.key === 'ArrowRight' && index < (this.rucInputData.length || 6) - 1) {\r\n event.preventDefault();\r\n this.inputs.toArray()[index + 1].nativeElement.focus();\r\n }\r\n }\r\n\r\n//Handle Paste Event\r\n handlePaste(event: ClipboardEvent): void {\r\n event.preventDefault();\r\n let pasteData = event.clipboardData?.getData('text');\r\n if (this.rucInputData.integerOnly) {\r\n pasteData = pasteData?.replace(/\\D/g, ''); // Extract digits only\r\n }\r\n if (!pasteData) return;\r\n\r\n const pasteLength = Math.min(pasteData.length, this.rucInputData.length || 6);\r\n for (let i = 0; i < pasteLength; i++) {\r\n this.otpValues[i] = pasteData[i];\r\n this.inputs.toArray()[i].nativeElement.value = pasteData[i];\r\n }\r\n\r\n // Focus last filled input or last input\r\n const focusIndex = pasteLength < (this.rucInputData.length || 6) ? pasteLength : (this.rucInputData.length || 6) - 1;\r\n this.inputs.toArray()[focusIndex].nativeElement.focus();\r\n\r\n // Auto-submit if complete\r\n if (this.rucInputData.autoSubmit && this.isOtpComplete(this.otpValues)) {\r\n if (this.timerId) {\r\n clearInterval(this.timerId);\r\n this.timerId = null;\r\n }\r\n this.rucEvent.emit({ eventName: 'completed', eventOutput: this.otpValues.join('') });\r\n }\r\n }\r\n\r\n //Check if OTP is completed\r\n private isOtpComplete(otpArray: string[]): boolean {\r\n return otpArray.every(val => val.trim() !== '');\r\n }\r\n\r\n// Disable inputs\r\n private disableAllInputs(): void {\r\n this.inputs.forEach((inputRef) => {\r\n inputRef.nativeElement.disabled = true;\r\n });\r\n }\r\n\r\n //Clear Interval\r\n ngOnDestroy(): void {\r\n if (this.timerId) {\r\n clearInterval(this.timerId);\r\n }\r\n }\r\n}\r\n\r\n","<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n @for (_ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); track _; let i = $index) {\r\n <input\r\n #otpInput\r\n [type]=\"rucInputData.mask ? 'password' : 'text'\"\r\n [ngClass]=\"[\r\n 'otp-input',\r\n rucInputData.templateType || 'rectangle',\r\n rucInputData.validationState === 'valid' ? 'is-valid' : '',\r\n rucInputData.validationState === 'invalid' ? 'is-invalid' : ''\r\n ]\"\r\n maxlength=\"1\"\r\n [(ngModel)]=\"otpValues[i]\"\r\n (input)=\"handleInput($event, i)\"\r\n (copy)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (paste)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (contextmenu)=\"rucInputData.copyProtection && $event.preventDefault()\"\r\n (keydown)=\"handleKeyDown($event, i)\"\r\n [attr.inputmode]=\"rucInputData.integerOnly ? 'numeric' : 'text'\"\r\n [pattern]=\"rucInputData.integerOnly ? '[0-9]*' : '.*'\"\r\n autocomplete=\"one-time-code\">\r\n }\r\n</div>\r\n<!-- Timer -->\r\n@if (rucInputData.timeLimit) {\r\n <div class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n </div>\r\n}\r\n<!-- Timeout message -->\r\n@if (rucInputData.timeLimit && timeLeft === 0) {\r\n <div class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n </div>\r\n}\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}