@ruc-lib/input-otp 2.0.0 → 2.0.2
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 +95 -51
- package/esm2020/lib/input-otp/input-otp.component.mjs +2 -2
- package/fesm2015/ruc-lib-input-otp.mjs +2 -2
- package/fesm2015/ruc-lib-input-otp.mjs.map +1 -1
- package/fesm2020/ruc-lib-input-otp.mjs +2 -2
- package/fesm2020/ruc-lib-input-otp.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
# ruclib-
|
|
1
|
+
# uxp-ruclib-input-otp
|
|
2
2
|
|
|
3
3
|
This library provides a flexible and customizable Input OTP component for your Angular applications. Users can integrate the Input OTP component using Angular services or selectors with ease. Below are the features, usage instructions, and integration details
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation Guide
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
Install RUC Library.
|
|
7
|
+
To use the Input OTP component, you can install the entire RUC library or just this specific component.
|
|
9
8
|
|
|
10
|
-
To install the entire RUC library:
|
|
11
9
|
|
|
12
|
-
`npm install @uxpractice/ruc-lib`
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
### Install the Entire Library
|
|
12
|
+
```bash
|
|
13
|
+
npm install @uxpractice/ruc-lib
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Install Individual Component
|
|
17
|
+
If you only need the Input OTP component:
|
|
18
|
+
```bash
|
|
19
|
+
npm install @ruc-lib/input-otp`
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
```
|
|
18
22
|
|
|
19
23
|
After installing the the required package successfully, we have to import the CSS in our style.scss file in following way.
|
|
20
24
|
|
|
@@ -31,55 +35,84 @@ for seperate package
|
|
|
31
35
|
`@import "../node_modules/primeng/resources/themes/lara-light-indigo/theme.css";`
|
|
32
36
|
`@import "../node_modules/primeng/resources/primeng.min.css";`
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### 1. Import the Module
|
|
41
|
+
In your Angular module file (e.g., `app.module.ts`), import the `RuclibInputOtpModule`:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// For Complete Library
|
|
45
|
+
import { RuclibInputOtpModule } from '@uxpractice/ruc-lib/input-otp';
|
|
46
|
+
|
|
47
|
+
// For Individual Package
|
|
48
|
+
import { RuclibInputOtpModule } from '@ruc-lib/input-otp';
|
|
49
|
+
import { AppComponent } from './app.component';
|
|
50
|
+
import { NgModule } from '@angular/core';
|
|
51
|
+
import { BrowserModule } from '@angular/platform-browser';
|
|
52
|
+
|
|
53
|
+
@NgModule({
|
|
54
|
+
declarations: [AppComponent],
|
|
55
|
+
imports: [
|
|
56
|
+
BrowserModule,
|
|
57
|
+
RuclibInputOtpModule
|
|
58
|
+
],
|
|
59
|
+
providers: [],
|
|
60
|
+
bootstrap: [AppComponent]
|
|
61
|
+
})
|
|
62
|
+
export class AppModule {}
|
|
63
|
+
```
|
|
64
|
+
### 2. Use the Component
|
|
65
|
+
In your component's template, use the `<uxp-input-otp>` selector and pass the configuration object to the `rucInputData` input.
|
|
35
66
|
|
|
36
|
-
|
|
67
|
+
```html
|
|
68
|
+
<uxp-input-otp [customTheme]="customTheme" [rucInputData]="inputObjectDataInputOtp"></uxp-input-otp>
|
|
69
|
+
```
|
|
37
70
|
|
|
38
|
-
|
|
71
|
+
## API Reference
|
|
39
72
|
|
|
40
|
-
|
|
73
|
+
### Component Inputs
|
|
41
74
|
|
|
42
|
-
|
|
75
|
+
| Input | Type | Description |
|
|
76
|
+
|----------------|--------------------|----------------------------------------------|
|
|
77
|
+
| `rucInputData` | `InputOtpConfig` | The main configuration object for the component. |
|
|
78
|
+
| `customTheme` | `string` | An optional CSS class for custom theming. |
|
|
43
79
|
|
|
44
|
-
`import { RuclibInputOtpModule } from '@ruc-lib/carousel'`
|
|
45
80
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
User can have Masking support
|
|
49
|
-
User can have Sizing functionality
|
|
50
|
-
User can Integer only support
|
|
51
|
-
User can have Custom OTP length
|
|
52
|
-
User can have Auto focus and auto jump
|
|
53
|
-
User can have Paste support
|
|
54
|
-
User can have Auto Submit on Complete
|
|
55
|
-
User can have Input Timeout/Expiry
|
|
56
|
-
User should enter the Otp input within the specified time limit (optional)
|
|
57
|
-
User can have custom templates/ Layouts (circle, rectangle and underscore lines ) for the Input OTP
|
|
58
|
-
User can validate input otp validation if the OTP is correct or not
|
|
59
|
-
User can have Copy and Paste Protection
|
|
81
|
+
### `InputOtpConfig`
|
|
82
|
+
This is the main configuration object for the Input OTP.
|
|
60
83
|
|
|
61
|
-
|
|
84
|
+
| Property | Type | Description |
|
|
85
|
+
|-----------------------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------------|
|
|
86
|
+
| `length` | `number` | Number of OTP digits |
|
|
87
|
+
| `mask` | `boolean` | Mask input as password |
|
|
88
|
+
| `size` | `'small' \| 'medium' \| 'large'` | Sizes: small, medium, large |
|
|
89
|
+
| `integerOnly` | `boolean` | Only allow integers 0-9 |
|
|
90
|
+
| `autoFocus` | `boolean` | auto focus and auto jump |
|
|
91
|
+
| `autoSubmit` | `boolean` | Auto Submit |
|
|
92
|
+
| `timeLimit` | `number` | Optional Time linit in seconds |
|
|
93
|
+
| `copyProtection` | `boolean` | /copy and paste protection |
|
|
94
|
+
| `templateType` | `'rectangle' \| 'circle' \| 'underscore'` | template style |
|
|
95
|
+
| `validationState` | `'valid' \| 'invalid' \| 'undefined'` | Validation state for visual feedback |
|
|
62
96
|
|
|
63
|
-
```
|
|
64
|
-
<uxp-input-otp (rucEvent)="passEvent($event)" [rucInputData]="inputObjectDataInputOtp"></uxp-input-otp>
|
|
65
97
|
|
|
98
|
+
## Example Configuration
|
|
66
99
|
|
|
67
|
-
|
|
100
|
+
Here's an example of how to configure the Input OTP in your component's TypeScript file.
|
|
68
101
|
|
|
69
|
-
|
|
102
|
+
```typescript
|
|
103
|
+
import { Component } from '@angular/core';
|
|
104
|
+
// For Complete Library
|
|
105
|
+
import { InputOtpConfig } from '@uxpractice/ruc-lib/input-otp';
|
|
70
106
|
|
|
71
|
-
|
|
72
|
-
|
|
107
|
+
// For Individual package
|
|
108
|
+
import { InputOtpConfig } from '@ruc-lib/input-otp';
|
|
73
109
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
const defaultConfig = {
|
|
110
|
+
@Component({
|
|
111
|
+
selector: 'app-root',
|
|
112
|
+
templateUrl: './app.component.html',
|
|
113
|
+
})
|
|
114
|
+
export class AppComponent {
|
|
115
|
+
const defaultConfig : InputOtpConfig = {
|
|
83
116
|
length: 6,
|
|
84
117
|
autoFocus: true,
|
|
85
118
|
integerOnly: true,
|
|
@@ -91,14 +124,25 @@ const defaultConfig = {
|
|
|
91
124
|
validationState: undefined,
|
|
92
125
|
timeLimit: undefined,
|
|
93
126
|
};
|
|
94
|
-
|
|
95
|
-
export const Default: Story = {
|
|
96
|
-
args: {
|
|
97
|
-
rucInputData: { ...defaultConfig },
|
|
98
|
-
},
|
|
99
|
-
};
|
|
127
|
+
}
|
|
100
128
|
```
|
|
101
129
|
|
|
130
|
+
# Features
|
|
131
|
+
User can have Basic Input
|
|
132
|
+
User can have Masking support
|
|
133
|
+
User can have Sizing functionality
|
|
134
|
+
User can Integer only support
|
|
135
|
+
User can have Custom OTP length
|
|
136
|
+
User can have Auto focus and auto jump
|
|
137
|
+
User can have Paste support
|
|
138
|
+
User can have Auto Submit on Complete
|
|
139
|
+
User can have Input Timeout/Expiry
|
|
140
|
+
User should enter the Otp input within the specified time limit (optional)
|
|
141
|
+
User can have custom templates/ Layouts (circle, rectangle and underscore lines ) for the Input OTP
|
|
142
|
+
User can validate input otp validation if the OTP is correct or not
|
|
143
|
+
User can have Copy and Paste Protection
|
|
144
|
+
|
|
145
|
+
|
|
102
146
|
# Contribution
|
|
103
147
|
Contributions are welcome! Feel free to open issues or pull requests for any enhancements or fixes.
|
|
104
148
|
|
|
@@ -125,10 +125,10 @@ export class InputOtpComponent {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
InputOtpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
128
|
-
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
128
|
+
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }] });
|
|
129
129
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, decorators: [{
|
|
130
130
|
type: Component,
|
|
131
|
-
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
131
|
+
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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"] }]
|
|
132
132
|
}], propDecorators: { rucEvent: [{
|
|
133
133
|
type: Output
|
|
134
134
|
}], customTheme: [{
|
|
@@ -131,10 +131,10 @@ class InputOtpComponent {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
InputOtpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
134
|
-
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
134
|
+
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }] });
|
|
135
135
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, decorators: [{
|
|
136
136
|
type: Component,
|
|
137
|
-
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
137
|
+
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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"] }]
|
|
138
138
|
}], propDecorators: { rucEvent: [{
|
|
139
139
|
type: Output
|
|
140
140
|
}], customTheme: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruc-lib-input-otp.mjs","sources":["../../src/modal/constants.ts","../../src/lib/input-otp/input-otp.component.ts","../../src/lib/input-otp/input-otp.component.html","../../src/lib/ruclib-input-otp.module.ts","../../src/ruc-lib-input-otp.ts"],"sourcesContent":["export const BACKSPACE_KEY = \"Backspace\"","import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ViewChildren,\r\n ElementRef,\r\n QueryList,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n} from '@angular/core';\r\nimport { InputOtpConfig } from '../../modal/input-otp-config';\r\nimport { BACKSPACE_KEY } from '../../modal/constants';\r\n\r\n@Component({\r\n selector: 'uxp-input-otp',\r\n templateUrl: './input-otp.component.html',\r\n styleUrls: ['./input-otp.component.scss']\r\n})\r\nexport class InputOtpComponent 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","<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\r\n\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { InputOtpComponent } from './input-otp/input-otp.component';\r\n\r\n@NgModule({\r\n imports: [CommonModule, MatIconModule, FormsModule],\r\n declarations: [InputOtpComponent],\r\n exports : [InputOtpComponent]\r\n\r\n})\r\nexport class RuclibInputOtpModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ruc-lib-input-otp.mjs","sources":["../../src/modal/constants.ts","../../src/lib/input-otp/input-otp.component.ts","../../src/lib/input-otp/input-otp.component.html","../../src/lib/ruclib-input-otp.module.ts","../../src/ruc-lib-input-otp.ts"],"sourcesContent":["export const BACKSPACE_KEY = \"Backspace\"","import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ViewChildren,\r\n ElementRef,\r\n QueryList,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n} from '@angular/core';\r\nimport { InputOtpConfig } from '../../modal/input-otp-config';\r\nimport { BACKSPACE_KEY } from '../../modal/constants';\r\n\r\n@Component({\r\n selector: 'uxp-input-otp',\r\n templateUrl: './input-otp.component.html',\r\n styleUrls: ['./input-otp.component.scss']\r\n})\r\nexport class InputOtpComponent 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","<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\r\n\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { InputOtpComponent } from './input-otp/input-otp.component';\r\n\r\n@NgModule({\r\n imports: [CommonModule, MatIconModule, FormsModule],\r\n declarations: [InputOtpComponent],\r\n exports : [InputOtpComponent]\r\n\r\n})\r\nexport class RuclibInputOtpModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -130,10 +130,10 @@ class InputOtpComponent {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
InputOtpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
133
|
-
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
133
|
+
InputOtpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputOtpComponent, selector: "uxp-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 <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }] });
|
|
134
134
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputOtpComponent, decorators: [{
|
|
135
135
|
type: Component,
|
|
136
|
-
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
|
|
136
|
+
args: [{ selector: 'uxp-input-otp', template: "<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\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
137
|
}], propDecorators: { rucEvent: [{
|
|
138
138
|
type: Output
|
|
139
139
|
}], customTheme: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruc-lib-input-otp.mjs","sources":["../../src/modal/constants.ts","../../src/lib/input-otp/input-otp.component.ts","../../src/lib/input-otp/input-otp.component.html","../../src/lib/ruclib-input-otp.module.ts","../../src/ruc-lib-input-otp.ts"],"sourcesContent":["export const BACKSPACE_KEY = \"Backspace\"","import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ViewChildren,\r\n ElementRef,\r\n QueryList,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n} from '@angular/core';\r\nimport { InputOtpConfig } from '../../modal/input-otp-config';\r\nimport { BACKSPACE_KEY } from '../../modal/constants';\r\n\r\n@Component({\r\n selector: 'uxp-input-otp',\r\n templateUrl: './input-otp.component.html',\r\n styleUrls: ['./input-otp.component.scss']\r\n})\r\nexport class InputOtpComponent 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","<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\r\n\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { InputOtpComponent } from './input-otp/input-otp.component';\r\n\r\n@NgModule({\r\n imports: [CommonModule, MatIconModule, FormsModule],\r\n declarations: [InputOtpComponent],\r\n exports : [InputOtpComponent]\r\n\r\n})\r\nexport class RuclibInputOtpModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ruc-lib-input-otp.mjs","sources":["../../src/modal/constants.ts","../../src/lib/input-otp/input-otp.component.ts","../../src/lib/input-otp/input-otp.component.html","../../src/lib/ruclib-input-otp.module.ts","../../src/ruc-lib-input-otp.ts"],"sourcesContent":["export const BACKSPACE_KEY = \"Backspace\"","import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ViewChildren,\r\n ElementRef,\r\n QueryList,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n} from '@angular/core';\r\nimport { InputOtpConfig } from '../../modal/input-otp-config';\r\nimport { BACKSPACE_KEY } from '../../modal/constants';\r\n\r\n@Component({\r\n selector: 'uxp-input-otp',\r\n templateUrl: './input-otp.component.html',\r\n styleUrls: ['./input-otp.component.scss']\r\n})\r\nexport class InputOtpComponent 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","<div class=\"{{customTheme}} otp-container\" [ngClass]=\"rucInputData.size || 'medium'\" (paste)=\"handlePaste($event)\">\r\n <input *ngFor=\"let _ of [].constructor(rucInputData.length || DEFAULT_OTP_LENGTH); let i = index\"\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</div>\r\n<!-- Timer -->\r\n<div *ngIf=\"rucInputData.timeLimit\" class=\"otp-timer\">\r\n {{TIME_LEFT}}: {{ timeLeft }}s\r\n</div>\r\n<!-- Timeout message -->\r\n<div *ngIf=\"rucInputData.timeLimit && timeLeft === 0\" class=\"otp-timeout-message\">\r\n {{EXPIRED_MSG}}\r\n</div>\r\n\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { InputOtpComponent } from './input-otp/input-otp.component';\r\n\r\n@NgModule({\r\n imports: [CommonModule, MatIconModule, FormsModule],\r\n declarations: [InputOtpComponent],\r\n exports : [InputOtpComponent]\r\n\r\n})\r\nexport class RuclibInputOtpModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|