@ruc-lib/input-otp 3.2.0 → 4.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 +46 -36
- package/fesm2022/ruc-lib-input-otp.mjs +153 -0
- package/fesm2022/ruc-lib-input-otp.mjs.map +1 -0
- package/index.d.ts +47 -3
- package/package.json +6 -18
- package/esm2020/index.mjs +0 -4
- package/esm2020/lib/input-otp/input-otp.component.mjs +0 -142
- package/esm2020/lib/ruclib-input-otp.module.mjs +0 -20
- package/esm2020/modal/constants.mjs +0 -2
- package/esm2020/modal/input-otp-config.mjs +0 -2
- package/esm2020/ruc-lib-input-otp.mjs +0 -5
- package/fesm2015/ruc-lib-input-otp.mjs +0 -168
- package/fesm2015/ruc-lib-input-otp.mjs.map +0 -1
- package/fesm2020/ruc-lib-input-otp.mjs +0 -167
- package/fesm2020/ruc-lib-input-otp.mjs.map +0 -1
- package/lib/input-otp/input-otp.component.d.ts +0 -25
- package/lib/ruclib-input-otp.module.d.ts +0 -10
- package/modal/constants.d.ts +0 -1
- package/modal/input-otp-config.d.ts +0 -18
package/README.md
CHANGED
|
@@ -14,63 +14,74 @@ npm install @uxpractice/ruc-lib
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
### Install Individual Component
|
|
17
|
-
If you only need the Input OTP component:
|
|
18
|
-
```bash
|
|
19
|
-
npm install @ruc-lib/input-otp`
|
|
20
17
|
|
|
18
|
+
If you only need the InputOtp component:
|
|
19
|
+
|
|
20
|
+
**For Angular 15:**
|
|
21
|
+
```bash
|
|
22
|
+
npm install @ruc-lib/input-otp@3.2.0 @angular/material@^15.0.0 @angular/cdk@^15.0.0
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
**For Angular 16:**
|
|
26
|
+
```bash
|
|
27
|
+
npm install @ruc-lib/input-otp@3.2.0 @angular/material@^16.0.0 @angular/cdk@^16.0.0
|
|
28
|
+
```
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
**For Angular 17:**
|
|
31
|
+
```bash
|
|
32
|
+
npm install @ruc-lib/input-otp@4.0.0 @angular/material@^17.0.0 @angular/cdk@^17.0.0
|
|
33
|
+
```
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
**For Angular 18:**
|
|
36
|
+
```bash
|
|
37
|
+
npm install @ruc-lib/input-otp@4.0.0 @angular/material@^18.0.0 @angular/cdk@^18.0.0
|
|
38
|
+
```
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
**For Angular 19:**
|
|
41
|
+
```bash
|
|
42
|
+
npm install @ruc-lib/input-otp@4.0.0 @angular/material@^19.0.0 @angular/cdk@^19.0.0
|
|
43
|
+
```
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
**For Angular 20:**
|
|
46
|
+
```bash
|
|
47
|
+
npm install @ruc-lib/input-otp@4.0.0
|
|
48
|
+
```
|
|
37
49
|
|
|
50
|
+
> **Note:** When installing in Angular 15-19 apps, you must specify the matching `@angular/material` and `@angular/cdk` versions to avoid peer dependency conflicts. Angular 20 will automatically use the correct versions.
|
|
38
51
|
|
|
39
|
-
|
|
52
|
+
### 📦 Version Compatibility
|
|
40
53
|
|
|
41
|
-
Please ensure you install the correct version of `@ruc-lib/input-otp` based on your Angular version.
|
|
42
|
-
|
|
43
54
|
| Angular Version | Compatible `@ruc-lib/input-otp` Version |
|
|
44
55
|
|--------------------|---------------------------------------------|
|
|
45
56
|
| 15.x.x | `npm install @ruc-lib/input-otp@^3.2.0` |
|
|
46
57
|
| 16.x.x | `npm install @ruc-lib/input-otp@^3.2.0` |
|
|
47
|
-
|
|
58
|
+
| 17.x.x | `npm install @ruc-lib/input-otp@^4.0.0` |
|
|
59
|
+
| 18.x.x | `npm install @ruc-lib/input-otp@^4.0.0` |
|
|
60
|
+
| 19.x.x | `npm install @ruc-lib/input-otp@^4.0.0` |
|
|
61
|
+
| 20.x.x | `npm install @ruc-lib/input-otp@^4.0.0` |
|
|
48
62
|
|
|
49
63
|
## Usage
|
|
50
64
|
|
|
51
|
-
### 1. Import the
|
|
52
|
-
In your Angular
|
|
65
|
+
### 1. Import the Component
|
|
66
|
+
In your Angular component file (e.g., `app.component.ts`), import the `RuclibInputOtpComponent`:
|
|
53
67
|
|
|
54
68
|
```typescript
|
|
69
|
+
import { Component } from '@angular/core';
|
|
70
|
+
|
|
55
71
|
// For Complete Library
|
|
56
|
-
import {
|
|
72
|
+
import { RuclibInputOtpComponent } from '@uxpractice/ruc-lib/input-otp';
|
|
57
73
|
|
|
58
74
|
// For Individual Package
|
|
59
|
-
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
declarations: [AppComponent],
|
|
66
|
-
imports: [
|
|
67
|
-
BrowserModule,
|
|
68
|
-
RuclibInputOtpModule
|
|
69
|
-
],
|
|
70
|
-
providers: [],
|
|
71
|
-
bootstrap: [AppComponent]
|
|
75
|
+
import { RuclibInputOtpComponent } from '@ruc-lib/input-otp';
|
|
76
|
+
|
|
77
|
+
@Component({
|
|
78
|
+
selector: 'app-root',
|
|
79
|
+
imports: [RuclibInputOtpComponent],
|
|
80
|
+
templateUrl: './app.component.html',
|
|
72
81
|
})
|
|
73
|
-
export class
|
|
82
|
+
export class AppComponent {
|
|
83
|
+
// Component code here
|
|
84
|
+
}
|
|
74
85
|
```
|
|
75
86
|
### 2. Use the Component
|
|
76
87
|
In your component's template, use the `<uxp-ruclib-input-otp>` selector and pass the configuration object to the `rucInputData` input.
|
|
@@ -175,5 +186,4 @@ When implementing **custom themes**, such as:
|
|
|
175
186
|
Contributions are welcome! Feel free to open issues or pull requests for any enhancements or fixes.
|
|
176
187
|
|
|
177
188
|
# Acknowledgements
|
|
178
|
-
Thank you for choosing the Input OTP Component Library. If you have any feedback or suggestions, please let us know!
|
|
179
|
-
|
|
189
|
+
Thank you for choosing the Input OTP Component Library. If you have any feedback or suggestions, please let us know!
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, AfterViewInit, OnDestroy, EventEmitter, QueryList, ElementRef } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
interface InputOtpConfig {
|
|
5
|
+
/** Number of OTP digits */
|
|
6
|
+
length?: number;
|
|
7
|
+
/** Mask input as password */
|
|
8
|
+
mask?: boolean;
|
|
9
|
+
/** Sizes: small, medium, large */
|
|
10
|
+
size?: 'small' | 'medium' | 'large';
|
|
11
|
+
/** Only allow integers 0-9 */
|
|
12
|
+
integerOnly?: boolean;
|
|
13
|
+
/** Autofocus and auto-jump */
|
|
14
|
+
autoFocus?: boolean;
|
|
15
|
+
autoSubmit?: boolean;
|
|
16
|
+
timeLimit?: number;
|
|
17
|
+
copyProtection?: boolean;
|
|
18
|
+
templateType?: 'rectangle' | 'circle' | 'underscore';
|
|
19
|
+
/** Validation state for visual feedback */
|
|
20
|
+
validationState?: 'valid' | 'invalid' | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare class RuclibInputOtpComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
24
|
+
readonly DEFAULT_OTP_LENGTH = 6;
|
|
25
|
+
readonly TIME_LEFT = "Time left";
|
|
26
|
+
readonly EXPIRED_MSG = "OTP expired. Please request a new one.";
|
|
27
|
+
rucEvent: EventEmitter<any>;
|
|
28
|
+
customTheme?: string;
|
|
29
|
+
rucInputData: InputOtpConfig;
|
|
30
|
+
timeLeft: number;
|
|
31
|
+
timerId: any;
|
|
32
|
+
inputs: QueryList<ElementRef<HTMLInputElement>>;
|
|
33
|
+
otpValues: string[];
|
|
34
|
+
ngOnInit(): void;
|
|
35
|
+
ngAfterViewInit(): void;
|
|
36
|
+
handleInput(event: Event, index: number): void;
|
|
37
|
+
handleKeyDown(event: KeyboardEvent, index: number): void;
|
|
38
|
+
handlePaste(event: ClipboardEvent): void;
|
|
39
|
+
private isOtpComplete;
|
|
40
|
+
private disableAllInputs;
|
|
41
|
+
ngOnDestroy(): void;
|
|
42
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RuclibInputOtpComponent, never>;
|
|
43
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RuclibInputOtpComponent, "uxp-ruclib-input-otp", never, { "customTheme": { "alias": "customTheme"; "required": false; }; "rucInputData": { "alias": "rucInputData"; "required": false; }; }, { "rucEvent": "rucEvent"; }, never, never, true, never>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { RuclibInputOtpComponent };
|
|
47
|
+
export type { InputOtpConfig };
|
package/package.json
CHANGED
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruc-lib/input-otp",
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "MIT",
|
|
3
|
+
"version": "4.0.0",
|
|
5
4
|
"peerDependencies": {
|
|
6
|
-
"@angular/common": "^
|
|
7
|
-
"@angular/core": "^
|
|
8
|
-
"@angular/material": "^15.
|
|
5
|
+
"@angular/common": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
|
|
6
|
+
"@angular/core": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0",
|
|
7
|
+
"@angular/material": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0"
|
|
9
8
|
},
|
|
10
9
|
"dependencies": {
|
|
11
10
|
"tslib": "^2.3.0"
|
|
12
11
|
},
|
|
13
|
-
"publishConfig": {
|
|
14
|
-
"access": "public"
|
|
15
|
-
},
|
|
16
12
|
"sideEffects": false,
|
|
17
|
-
"module": "
|
|
18
|
-
"es2020": "fesm2020/ruc-lib-input-otp.mjs",
|
|
19
|
-
"esm2020": "esm2020/ruc-lib-input-otp.mjs",
|
|
20
|
-
"fesm2020": "fesm2020/ruc-lib-input-otp.mjs",
|
|
21
|
-
"fesm2015": "fesm2015/ruc-lib-input-otp.mjs",
|
|
13
|
+
"module": "fesm2022/ruc-lib-input-otp.mjs",
|
|
22
14
|
"typings": "index.d.ts",
|
|
23
15
|
"exports": {
|
|
24
16
|
"./package.json": {
|
|
@@ -26,11 +18,7 @@
|
|
|
26
18
|
},
|
|
27
19
|
".": {
|
|
28
20
|
"types": "./index.d.ts",
|
|
29
|
-
"
|
|
30
|
-
"es2020": "./fesm2020/ruc-lib-input-otp.mjs",
|
|
31
|
-
"es2015": "./fesm2015/ruc-lib-input-otp.mjs",
|
|
32
|
-
"node": "./fesm2015/ruc-lib-input-otp.mjs",
|
|
33
|
-
"default": "./fesm2020/ruc-lib-input-otp.mjs"
|
|
21
|
+
"default": "./fesm2022/ruc-lib-input-otp.mjs"
|
|
34
22
|
}
|
|
35
23
|
}
|
|
36
24
|
}
|
package/esm2020/index.mjs
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export * from './lib/ruclib-input-otp.module';
|
|
2
|
-
export * from './lib/input-otp/input-otp.component';
|
|
3
|
-
export * from './modal/input-otp-config';
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLHFDQUFxQyxDQUFDO0FBQ3BELGNBQWMsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9ydWNsaWItaW5wdXQtb3RwLm1vZHVsZSc7XHJcbmV4cG9ydCAqIGZyb20gJy4vbGliL2lucHV0LW90cC9pbnB1dC1vdHAuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9tb2RhbC9pbnB1dC1vdHAtY29uZmlnJztcclxuIl19
|