@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 CHANGED
@@ -1,20 +1,24 @@
1
- # ruclib-carousel
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
- ## RUC Library Installation Guide
5
+ ## Installation Guide
6
6
 
7
- Users can easily install the RUC (Ruxptest Library) from npm. Additionally, they can also choose to install individual components based on their requirements.
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
- ## Install Individual Components
15
- If users only need the carousel component, they can install it separately:
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
- `npm install @ruc-lib/input-otp`
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
- # import required modules
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
- Import ContextModule into app.module.ts file.
67
+ ```html
68
+ <uxp-input-otp [customTheme]="customTheme" [rucInputData]="inputObjectDataInputOtp"></uxp-input-otp>
69
+ ```
37
70
 
38
- for library
71
+ ## API Reference
39
72
 
40
- `import { RuclibInputOtpModule } from '@uxpractice/ruc-lib/carousel'`
73
+ ### Component Inputs
41
74
 
42
- for seperate package
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
- # Features
47
- User can have Basic Input
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
- # Use component selector
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
- # Input and Output
102
+ ```typescript
103
+ import { Component } from '@angular/core';
104
+ // For Complete Library
105
+ import { InputOtpConfig } from '@uxpractice/ruc-lib/input-otp';
70
106
 
71
- # Inputs
72
- rucInputData -> It is the configuration input to configure the Input OTP component
107
+ // For Individual package
108
+ import { InputOtpConfig } from '@ruc-lib/input-otp';
73
109
 
74
- customTheme -> It is the name of the theme.
75
- # Output
76
-
77
- # rucInputData (sample object)
78
-
79
- # Detail definition of the each property can be found in type definition file.
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;color:inherit}.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}\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"] }] });
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;color:inherit}.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}\n"] }]
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;color:inherit}.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}\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
+ 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;color:inherit}.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}\n"] }]
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;color:inherit}.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}\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"] }] });
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;color:inherit}.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}\n"] }]
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruc-lib/input-otp",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "license": "MIT",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^17.0.0 || ^16.0.0 || ^15.0.0",