ng-otp-box 0.0.1
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 +24 -0
- package/esm2020/lib/ng-otp-box.component.mjs +19 -0
- package/esm2020/lib/ng-otp-box.module.mjs +31 -0
- package/esm2020/lib/ng-otp-box.service.mjs +14 -0
- package/esm2020/lib/otp-box/otp-box.component.mjs +148 -0
- package/esm2020/ng-otp-box.mjs +5 -0
- package/esm2020/public-api.mjs +8 -0
- package/fesm2015/ng-otp-box.mjs +215 -0
- package/fesm2015/ng-otp-box.mjs.map +1 -0
- package/fesm2020/ng-otp-box.mjs +214 -0
- package/fesm2020/ng-otp-box.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/ng-otp-box.component.d.ts +5 -0
- package/lib/ng-otp-box.module.d.ts +10 -0
- package/lib/ng-otp-box.service.d.ts +6 -0
- package/lib/otp-box/otp-box.component.d.ts +33 -0
- package/package.json +33 -0
- package/public-api.d.ts +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# NgOtpBox
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.1.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project ng-otp-box` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ng-otp-box`.
|
|
8
|
+
> Note: Don't forget to add `--project ng-otp-box` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build ng-otp-box` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build ng-otp-box`, go to the dist folder `cd dist/ng-otp-box` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test ng-otp-box` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class NgOtpBoxComponent {
|
|
4
|
+
}
|
|
5
|
+
NgOtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6
|
+
NgOtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgOtpBoxComponent, selector: "lib-ng-otp-box", ngImport: i0, template: `
|
|
7
|
+
<p>
|
|
8
|
+
ng-otp-box works!
|
|
9
|
+
</p>
|
|
10
|
+
`, isInline: true });
|
|
11
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, decorators: [{
|
|
12
|
+
type: Component,
|
|
13
|
+
args: [{ selector: 'lib-ng-otp-box', template: `
|
|
14
|
+
<p>
|
|
15
|
+
ng-otp-box works!
|
|
16
|
+
</p>
|
|
17
|
+
` }]
|
|
18
|
+
}] });
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctb3RwLWJveC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1vdHAtYm94L3NyYy9saWIvbmctb3RwLWJveC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFZMUMsTUFBTSxPQUFPLGlCQUFpQjs7K0dBQWpCLGlCQUFpQjttR0FBakIsaUJBQWlCLHNEQVJsQjs7OztHQUlUOzRGQUlVLGlCQUFpQjtrQkFWN0IsU0FBUzsrQkFDRSxnQkFBZ0IsWUFDaEI7Ozs7R0FJVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItbmctb3RwLWJveCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgPHA+XG4gICAgICBuZy1vdHAtYm94IHdvcmtzIVxuICAgIDwvcD5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTmdPdHBCb3hDb21wb25lbnQge1xuXG59XG4iXX0=
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { MatInputModule } from '@angular/material/input';
|
|
5
|
+
import { OtpBoxComponent } from './otp-box/otp-box.component';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export class NgOtpBoxModule {
|
|
8
|
+
}
|
|
9
|
+
NgOtpBoxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
10
|
+
NgOtpBoxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, declarations: [OtpBoxComponent], imports: [CommonModule,
|
|
11
|
+
ReactiveFormsModule,
|
|
12
|
+
FormsModule,
|
|
13
|
+
MatInputModule], exports: [OtpBoxComponent] });
|
|
14
|
+
NgOtpBoxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, imports: [CommonModule,
|
|
15
|
+
ReactiveFormsModule,
|
|
16
|
+
FormsModule,
|
|
17
|
+
MatInputModule] });
|
|
18
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, decorators: [{
|
|
19
|
+
type: NgModule,
|
|
20
|
+
args: [{
|
|
21
|
+
declarations: [OtpBoxComponent],
|
|
22
|
+
imports: [
|
|
23
|
+
CommonModule,
|
|
24
|
+
ReactiveFormsModule,
|
|
25
|
+
FormsModule,
|
|
26
|
+
MatInputModule,
|
|
27
|
+
],
|
|
28
|
+
exports: [OtpBoxComponent],
|
|
29
|
+
}]
|
|
30
|
+
}] });
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctb3RwLWJveC5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1vdHAtYm94L3NyYy9saWIvbmctb3RwLWJveC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBWTlELE1BQU0sT0FBTyxjQUFjOzs0R0FBZCxjQUFjOzZHQUFkLGNBQWMsaUJBVFYsZUFBZSxhQUU1QixZQUFZO1FBQ1osbUJBQW1CO1FBQ25CLFdBQVc7UUFDWCxjQUFjLGFBRU4sZUFBZTs2R0FFZCxjQUFjLFlBUHZCLFlBQVk7UUFDWixtQkFBbUI7UUFDbkIsV0FBVztRQUNYLGNBQWM7NEZBSUwsY0FBYztrQkFWMUIsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUUsQ0FBQyxlQUFlLENBQUM7b0JBQy9CLE9BQU8sRUFBRTt3QkFDUCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsV0FBVzt3QkFDWCxjQUFjO3FCQUNmO29CQUNELE9BQU8sRUFBRSxDQUFDLGVBQWUsQ0FBQztpQkFDM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcblxuaW1wb3J0IHsgT3RwQm94Q29tcG9uZW50IH0gZnJvbSAnLi9vdHAtYm94L290cC1ib3guY29tcG9uZW50JztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbT3RwQm94Q29tcG9uZW50XSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdElucHV0TW9kdWxlLFxuICBdLFxuICBleHBvcnRzOiBbT3RwQm94Q29tcG9uZW50XSxcbn0pXG5leHBvcnQgY2xhc3MgTmdPdHBCb3hNb2R1bGUge31cbiJdfQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class NgOtpBoxService {
|
|
4
|
+
constructor() { }
|
|
5
|
+
}
|
|
6
|
+
NgOtpBoxService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7
|
+
NgOtpBoxService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, providedIn: 'root' });
|
|
8
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, decorators: [{
|
|
9
|
+
type: Injectable,
|
|
10
|
+
args: [{
|
|
11
|
+
providedIn: 'root'
|
|
12
|
+
}]
|
|
13
|
+
}], ctorParameters: function () { return []; } });
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctb3RwLWJveC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctb3RwLWJveC9zcmMvbGliL25nLW90cC1ib3guc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUszQyxNQUFNLE9BQU8sZUFBZTtJQUUxQixnQkFBZ0IsQ0FBQzs7NkdBRk4sZUFBZTtpSEFBZixlQUFlLGNBRmQsTUFBTTs0RkFFUCxlQUFlO2tCQUgzQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTmdPdHBCb3hTZXJ2aWNlIHtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxufVxuIl19
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Input, Output, ViewChildren } from '@angular/core';
|
|
2
|
+
import { Component, EventEmitter } from '@angular/core';
|
|
3
|
+
import { Validators } from '@angular/forms';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/forms";
|
|
6
|
+
import * as i2 from "@angular/common";
|
|
7
|
+
import * as i3 from "@angular/material/input";
|
|
8
|
+
import * as i4 from "@angular/material/form-field";
|
|
9
|
+
export class OtpBoxComponent {
|
|
10
|
+
constructor(fb) {
|
|
11
|
+
this.fb = fb;
|
|
12
|
+
this.otpChange = new EventEmitter();
|
|
13
|
+
this.otpLength = 6;
|
|
14
|
+
this.inputType = 'number';
|
|
15
|
+
// @Input() allowUppercase: boolean = true;
|
|
16
|
+
// @Input() showUnMaskCheckBoxYN : boolean = false;
|
|
17
|
+
this.unmaskPassword = false;
|
|
18
|
+
}
|
|
19
|
+
ngOnInit() {
|
|
20
|
+
this.otpForm = this.fb.group({
|
|
21
|
+
otp: this.fb.array([]),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
ngAfterViewInit() {
|
|
25
|
+
this.buildOtpControls();
|
|
26
|
+
// this.otpForm.valueChanges.subscribe((val) => {
|
|
27
|
+
// this.emitOtp();
|
|
28
|
+
// });
|
|
29
|
+
}
|
|
30
|
+
get otpArray() {
|
|
31
|
+
return this.otpForm.get('otp');
|
|
32
|
+
}
|
|
33
|
+
getInputPattern() {
|
|
34
|
+
const alpha = 'a-zA-Z';
|
|
35
|
+
const alphanumeric = 'a-zA-Z0-9';
|
|
36
|
+
switch (this.inputType) {
|
|
37
|
+
case 'text':
|
|
38
|
+
return new RegExp(`^[${alpha}]$`);
|
|
39
|
+
case 'number':
|
|
40
|
+
return /^[0-9+]$/;
|
|
41
|
+
case 'mixed':
|
|
42
|
+
return /^[a-zA-Z0-9]$/;
|
|
43
|
+
case 'masked':
|
|
44
|
+
return new RegExp(`^[${alphanumeric}]$`);
|
|
45
|
+
default:
|
|
46
|
+
return /^[0-9]$/;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
buildOtpControls() {
|
|
50
|
+
this.otpArray.clear();
|
|
51
|
+
const pattern = this.getInputPattern();
|
|
52
|
+
for (let i = 0; i < this.otpLength; i++) {
|
|
53
|
+
this.otpArray.push(this.fb.control('', [Validators.required, Validators.pattern(pattern)]));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
togglePasswordVisibility() {
|
|
57
|
+
this.unmaskPassword = !this.unmaskPassword;
|
|
58
|
+
}
|
|
59
|
+
focusFirstInput() {
|
|
60
|
+
if (this.inputs && this.inputs.length > 0) {
|
|
61
|
+
this.inputs.first.nativeElement.focus();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
onInput(event, index) {
|
|
65
|
+
const input = event.target;
|
|
66
|
+
const { value, message } = this.sanitizeWithMessage(input.value);
|
|
67
|
+
this.emitChange(message);
|
|
68
|
+
this.otpArray.at(index).setValue(value, { emitEvent: false });
|
|
69
|
+
if (value && index < this.otpLength - 1) {
|
|
70
|
+
this.inputs.toArray()[index + 1].nativeElement.focus();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
sanitizeWithMessage(rawValue) {
|
|
74
|
+
switch (this.inputType) {
|
|
75
|
+
case 'number':
|
|
76
|
+
if (/[^0-9]/.test(rawValue)) {
|
|
77
|
+
return {
|
|
78
|
+
value: rawValue.replace(/\D/g, ''),
|
|
79
|
+
message: 'Only numbers are allowed'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return { value: rawValue };
|
|
83
|
+
case 'text':
|
|
84
|
+
if (/[^a-zA-Z]/.test(rawValue)) {
|
|
85
|
+
return {
|
|
86
|
+
value: rawValue.replace(/[^a-zA-Z]/g, ''),
|
|
87
|
+
message: 'Only letters are allowed'
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return { value: rawValue, message: 'success' };
|
|
91
|
+
case 'mixed':
|
|
92
|
+
case 'masked':
|
|
93
|
+
if (/[^a-zA-Z0-9]/.test(rawValue)) {
|
|
94
|
+
return {
|
|
95
|
+
value: rawValue.replace(/[^a-zA-Z0-9]/g, ''),
|
|
96
|
+
message: 'Only letters and numbers are allowed'
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { value: rawValue, message: 'success' };
|
|
100
|
+
default:
|
|
101
|
+
return { value: rawValue, message: 'success' };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
onKeyDown(event, index) {
|
|
105
|
+
if (event.key === 'Backspace' &&
|
|
106
|
+
!this.otpArray.at(index).value &&
|
|
107
|
+
index > 0) {
|
|
108
|
+
this.inputs.toArray()[index - 1].nativeElement.focus();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
onPaste(event) {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
const pasteData = event.clipboardData?.getData('text') ?? '';
|
|
114
|
+
const { value, message } = this.sanitizeWithMessage(pasteData);
|
|
115
|
+
if (value.length !== this.otpLength) {
|
|
116
|
+
this.emitChange('Invalid OTP length');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
value.split('').forEach((char, i) => {
|
|
120
|
+
this.otpArray.at(i).setValue(char, { emitEvent: false });
|
|
121
|
+
});
|
|
122
|
+
this.emitChange(message);
|
|
123
|
+
}
|
|
124
|
+
emitChange(message) {
|
|
125
|
+
const otp = this.otpArray.value.join('');
|
|
126
|
+
this.otpChange.emit({
|
|
127
|
+
value: otp,
|
|
128
|
+
isValid: this.otpForm.valid,
|
|
129
|
+
message: message
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
OtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
134
|
+
OtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OtpBoxComponent, selector: "lib-otp-box", inputs: { otpLength: "otpLength", inputType: "inputType" }, outputs: { otpChange: "otpChange" }, viewQueries: [{ propertyName: "inputs", predicate: ["otpInput"], descendants: true }], ngImport: i0, template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }] });
|
|
135
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, decorators: [{
|
|
136
|
+
type: Component,
|
|
137
|
+
args: [{ selector: 'lib-otp-box', template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"] }]
|
|
138
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { otpChange: [{
|
|
139
|
+
type: Output
|
|
140
|
+
}], otpLength: [{
|
|
141
|
+
type: Input
|
|
142
|
+
}], inputType: [{
|
|
143
|
+
type: Input
|
|
144
|
+
}], inputs: [{
|
|
145
|
+
type: ViewChildren,
|
|
146
|
+
args: ['otpInput']
|
|
147
|
+
}] } });
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLWJveC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1vdHAtYm94L3NyYy9saWIvb3RwLWJveC9vdHAtYm94LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLW90cC1ib3gvc3JjL2xpYi9vdHAtYm94L290cC1ib3guY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBcUMsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQWEvRSxNQUFNLE9BQU8sZUFBZTtJQVkxQixZQUFvQixFQUFlO1FBQWYsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQVh6QixjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNyQyxjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsY0FBUyxHQUEyQyxRQUFRLENBQUM7UUFDdEUsMkNBQTJDO1FBQzNDLG1EQUFtRDtRQUNuRCxtQkFBYyxHQUFZLEtBQUssQ0FBQztJQU1NLENBQUM7SUFFdkMsUUFBUTtRQUNOLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDM0IsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBRXhCLGlEQUFpRDtRQUNqRCxvQkFBb0I7UUFDcEIsTUFBTTtJQUNSLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMs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b20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIFF1ZXJ5TGlzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQnVpbGRlciwgRm9ybUFycmF5LCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIG90cE1vZGVsIHtcbiAgaXNWYWxpZDogYm9vbGVhbjtcbiAgdmFsdWU6IG51bWJlcjtcbiAgbWVzc2FnZT8gOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1vdHAtYm94JyxcbiAgdGVtcGxhdGVVcmw6ICcuL290cC1ib3guY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9vdHAtYm94LmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBPdHBCb3hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBAT3V0cHV0KCkgb3RwQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBJbnB1dCgpIG90cExlbmd0aCA9IDY7XG4gIEBJbnB1dCgpIGlucHV0VHlwZTogJ3RleHQnIHwgJ251bWJlcicgfCAnbWl4ZWQnIHwgJ21hc2tlZCcgPSAnbnVtYmVyJztcbiAgLy8gQElucHV0KCkgYWxsb3dVcHBlcmNhc2U6IGJvb2xlYW4gPSB0cnVlO1xuICAvLyBASW5wdXQoKSBzaG93VW5NYXNrQ2hlY2tCb3hZTiA6IGJvb2xlYW4gPSBmYWxzZTtcbiAgdW5tYXNrUGFzc3dvcmQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBvdHBGb3JtITogRm9ybUdyb3VwO1xuXG4gIEBWaWV3Q2hpbGRyZW4oJ290cElucHV0JykgaW5wdXRzITogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMub3RwRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgb3RwOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmJ1aWxkT3RwQ29udHJvbHMoKTtcblxuICAgIC8vIHRoaXMub3RwRm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh2YWwpID0+IHtcbiAgICAvLyAgIHRoaXMuZW1pdE90cCgpO1xuICAgIC8vIH0pO1xuICB9XG5cbiAgZ2V0IG90cEFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMub3RwRm9ybS5nZXQoJ290cCcpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SW5wdXRQYXR0ZXJuKCk6IFJlZ0V4cCB7XG4gICAgY29uc3QgYWxwaGEgPSAgJ2EtekEtWic7XG4gICAgY29uc3QgYWxwaGFudW1lcmljID0gJ2EtekEtWjAtOSc7XG4gICAgc3dpdGNoICh0aGlzLmlucHV0VHlwZSkge1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIHJldHVybiBuZXcgUmVnRXhwKGBeWyR7YWxwaGF9XSRgKTtcblxuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgcmV0dXJuIC9eWzAtOStdJC87XG5cbiAgICAgIGNhc2UgJ21peGVkJzpcbiAgICAgICAgcmV0dXJuIC9eW2EtekEtWjAtOV0kLztcblxuICAgICAgY2FzZSAnbWFza2VkJzpcbiAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAoYF5bJHthbHBoYW51bWVyaWN9XSRgKTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIC9eWzAtOV0kLztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkT3RwQ29udHJvbHMoKTogdm9pZCB7XG4gICAgdGhpcy5vdHBBcnJheS5jbGVhcigpO1xuICAgIGNvbnN0IHBhdHRlcm4gPSB0aGlzLmdldElucHV0UGF0dGVybigpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm90cExlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLm90cEFycmF5LnB1c2goXG4gICAgICAgIHRoaXMuZmIuY29udHJvbCgnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMucGF0dGVybihwYXR0ZXJuKV0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVBhc3N3b3JkVmlzaWJpbGl0eSgpOiB2b2lkIHtcbiAgICB0aGlzLnVubWFza1Bhc3N3b3JkID0gIXRoaXMudW5tYXNrUGFzc3dvcmQ7XG4gIH1cblxuICBmb2N1c0ZpcnN0SW5wdXQoKSB7XG4gICAgaWYgKHRoaXMuaW5wdXRzICYmIHRoaXMuaW5wdXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuaW5wdXRzLmZpcnN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBvbklucHV0KGV2ZW50OiBFdmVudCwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgeyB2YWx1ZSwgbWVzc2FnZSB9ID0gdGhpcy5zYW5pdGl6ZVdpdGhNZXNzYWdlKGlucHV0LnZhbHVlKTtcbiAgICB0aGlzLmVtaXRDaGFuZ2UobWVzc2FnZSk7XG4gICAgdGhpcy5vdHBBcnJheS5hdChpbmRleCkuc2V0VmFsdWUodmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgIGlmICh2YWx1ZSAmJiBpbmRleCA8IHRoaXMub3RwTGVuZ3RoIC0gMSkge1xuICAgICAgdGhpcy5pbnB1dHMudG9BcnJheSgpW2luZGV4ICsgMV0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2FuaXRpemVXaXRoTWVzc2FnZShyYXdWYWx1ZTogc3RyaW5nKTogeyB2YWx1ZTogc3RyaW5nOyBtZXNzYWdlPzogc3RyaW5nIH0ge1xuICBzd2l0Y2ggKHRoaXMuaW5wdXRUeXBlKSB7XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGlmICgvW14wLTldLy50ZXN0KHJhd1ZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHZhbHVlOiByYXdWYWx1ZS5yZXBsYWNlKC9cXEQvZywgJycpLFxuICAgICAgICAgIG1lc3NhZ2U6ICdPbmx5IG51bWJlcnMgYXJlIGFsbG93ZWQnXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4geyB2YWx1ZTogcmF3VmFsdWUgfTtcblxuICAgIGNhc2UgJ3RleHQnOlxuICAgICAgaWYgKC9bXmEtekEtWl0vLnRlc3QocmF3VmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsdWU6IHJhd1ZhbHVlLnJlcGxhY2UoL1teYS16QS1aXS9nLCAnJyksXG4gICAgICAgICAgbWVzc2FnZTogJ09ubHkgbGV0dGVycyBhcmUgYWxsb3dlZCdcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IHZhbHVlOiByYXdWYWx1ZSwgbWVzc2FnZTogJ3N1Y2Nlc3MnIH07XG5cbiAgICBjYXNlICdtaXhlZCc6XG4gICAgY2FzZSAnbWFza2VkJzpcbiAgICAgIGlmICgvW15hLXpBLVowLTldLy50ZXN0KHJhd1ZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHZhbHVlOiByYXdWYWx1ZS5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgJycpLFxuICAgICAgICAgIG1lc3NhZ2U6ICdPbmx5IGxldHRlcnMgYW5kIG51bWJlcnMgYXJlIGFsbG93ZWQnXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4geyB2YWx1ZTogcmF3VmFsdWUsIG1lc3NhZ2U6ICdzdWNjZXNzJyB9O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IHZhbHVlOiByYXdWYWx1ZSwgbWVzc2FnZTogJ3N1Y2Nlc3MnIH07XG4gIH1cbn1cblxuICBvbktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICBldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnICYmXG4gICAgICAhdGhpcy5vdHBBcnJheS5hdChpbmRleCkudmFsdWUgJiZcbiAgICAgIGluZGV4ID4gMFxuICAgICkge1xuICAgICAgdGhpcy5pbnB1dHMudG9BcnJheSgpW2luZGV4IC0gMV0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG5vblBhc3RlKGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQge1xuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIGNvbnN0IHBhc3RlRGF0YSA9IGV2ZW50LmNsaXBib2FyZERhdGE/LmdldERhdGEoJ3RleHQnKSA/PyAnJztcbiAgY29uc3QgeyB2YWx1ZSwgbWVzc2FnZSB9ID0gdGhpcy5zYW5pdGl6ZVdpdGhNZXNzYWdlKHBhc3RlRGF0YSk7XG5cbiAgaWYgKHZhbHVlLmxlbmd0aCAhPT0gdGhpcy5vdHBMZW5ndGgpIHtcbiAgICB0aGlzLmVtaXRDaGFuZ2UoJ0ludmFsaWQgT1RQIGxlbmd0aCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhbHVlLnNwbGl0KCcnKS5mb3JFYWNoKChjaGFyLCBpKSA9PiB7XG4gICAgdGhpcy5vdHBBcnJheS5hdChpKS5zZXRWYWx1ZShjaGFyLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gIH0pO1xuXG4gIHRoaXMuZW1pdENoYW5nZShtZXNzYWdlKTtcbn1cblxuICBwcml2YXRlIGVtaXRDaGFuZ2UobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgY29uc3Qgb3RwID0gdGhpcy5vdHBBcnJheS52YWx1ZS5qb2luKCcnKTtcbiAgICB0aGlzLm90cENoYW5nZS5lbWl0KHtcbiAgICAgIHZhbHVlOiBvdHAsXG4gICAgICBpc1ZhbGlkOiB0aGlzLm90cEZvcm0udmFsaWQsXG4gICAgICBtZXNzYWdlOiBtZXNzYWdlXG4gICAgfSk7XG4gIH1cbn1cbiIsIjxkaXY+XG4gIDxmb3JtIFtmb3JtR3JvdXBdPVwib3RwRm9ybVwiIChwYXN0ZSk9XCJvblBhc3RlKCRldmVudClcIj5cblxuICAgIDxkaXYgY2xhc3M9XCJvdHAtY29udGFpbmVyXCIgZm9ybUFycmF5TmFtZT1cIm90cFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY3RybCBvZiBvdHBBcnJheS5jb250cm9sczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cIm90cC1tYXQtZmllbGRcIiBbY2xhc3MubWF0LWZvcm0tZmllbGQtaW52YWxpZF09XCJcbiAgICAgICAgICBvdHBGb3JtLmludmFsaWQgJiYgKG90cEZvcm0udG91Y2hlZCB8fCBvdHBGb3JtLmRpcnR5KVwiPlxuICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbdHlwZV09XCJpbnB1dFR5cGUgPT09ICdtYXNrZWQnID8gJ3Bhc3N3b3JkJyA6ICd0ZXh0J1wiIG1heGxlbmd0aD1cIjFcIlxuICAgICAgICAgICAgI290cElucHV0IGNka0ZvY3VzSW5pdGlhbCBbZm9ybUNvbnRyb2xOYW1lXT1cImlcIiAoaW5wdXQpPVwib25JbnB1dCgkZXZlbnQsIGkpXCJcbiAgICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQsIGkpXCIgLz5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICAgIDwhLS0gPGRpdiBjbGFzcz1cIm90cC1wYXNzd29yZC10b2dnbGVcIiAqbmdJZj1cImlucHV0VHlwZSA9PT0gJ3Bhc3N3b3JkJyAmJiBzaG93VW5NYXNrQ2hlY2tCb3hZTlwiPlxuICAgICAgPG1hdC1jaGVja2JveCBbY2hlY2tlZF09XCJ1bm1hc2tQYXNzd29yZFwiIChjaGFuZ2UpPVwidG9nZ2xlUGFzc3dvcmRWaXNpYmlsaXR5KClcIj5cbiAgICAgICAgU2hvdyBwYXNzd29yZFxuICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgPC9kaXY+IC0tPlxuXG4gIDwvZm9ybT5cbjwvZGl2PiJdfQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctb3RwLWJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25nLW90cC1ib3gvc3JjL25nLW90cC1ib3gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of ng-otp-box
|
|
3
|
+
*/
|
|
4
|
+
export * from './lib/ng-otp-box.service';
|
|
5
|
+
export * from './lib/ng-otp-box.component';
|
|
6
|
+
export * from './lib/ng-otp-box.module';
|
|
7
|
+
export * from './lib/otp-box/otp-box.component';
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25nLW90cC1ib3gvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLGlDQUFpQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZy1vdHAtYm94XG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9saWIvbmctb3RwLWJveC5zZXJ2aWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL25nLW90cC1ib3guY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL25nLW90cC1ib3gubW9kdWxlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL290cC1ib3gvb3RwLWJveC5jb21wb25lbnQnO1xuIl19
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, Component, EventEmitter, Output, Input, ViewChildren, NgModule } from '@angular/core';
|
|
3
|
+
import * as i2 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i1 from '@angular/forms';
|
|
6
|
+
import { Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
7
|
+
import * as i3 from '@angular/material/input';
|
|
8
|
+
import { MatInputModule } from '@angular/material/input';
|
|
9
|
+
import * as i4 from '@angular/material/form-field';
|
|
10
|
+
|
|
11
|
+
class NgOtpBoxService {
|
|
12
|
+
constructor() { }
|
|
13
|
+
}
|
|
14
|
+
NgOtpBoxService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
15
|
+
NgOtpBoxService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, providedIn: 'root' });
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, decorators: [{
|
|
17
|
+
type: Injectable,
|
|
18
|
+
args: [{
|
|
19
|
+
providedIn: 'root'
|
|
20
|
+
}]
|
|
21
|
+
}], ctorParameters: function () { return []; } });
|
|
22
|
+
|
|
23
|
+
class NgOtpBoxComponent {
|
|
24
|
+
}
|
|
25
|
+
NgOtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26
|
+
NgOtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgOtpBoxComponent, selector: "lib-ng-otp-box", ngImport: i0, template: `
|
|
27
|
+
<p>
|
|
28
|
+
ng-otp-box works!
|
|
29
|
+
</p>
|
|
30
|
+
`, isInline: true });
|
|
31
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, decorators: [{
|
|
32
|
+
type: Component,
|
|
33
|
+
args: [{ selector: 'lib-ng-otp-box', template: `
|
|
34
|
+
<p>
|
|
35
|
+
ng-otp-box works!
|
|
36
|
+
</p>
|
|
37
|
+
` }]
|
|
38
|
+
}] });
|
|
39
|
+
|
|
40
|
+
class OtpBoxComponent {
|
|
41
|
+
constructor(fb) {
|
|
42
|
+
this.fb = fb;
|
|
43
|
+
this.otpChange = new EventEmitter();
|
|
44
|
+
this.otpLength = 6;
|
|
45
|
+
this.inputType = 'number';
|
|
46
|
+
// @Input() allowUppercase: boolean = true;
|
|
47
|
+
// @Input() showUnMaskCheckBoxYN : boolean = false;
|
|
48
|
+
this.unmaskPassword = false;
|
|
49
|
+
}
|
|
50
|
+
ngOnInit() {
|
|
51
|
+
this.otpForm = this.fb.group({
|
|
52
|
+
otp: this.fb.array([]),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
ngAfterViewInit() {
|
|
56
|
+
this.buildOtpControls();
|
|
57
|
+
// this.otpForm.valueChanges.subscribe((val) => {
|
|
58
|
+
// this.emitOtp();
|
|
59
|
+
// });
|
|
60
|
+
}
|
|
61
|
+
get otpArray() {
|
|
62
|
+
return this.otpForm.get('otp');
|
|
63
|
+
}
|
|
64
|
+
getInputPattern() {
|
|
65
|
+
const alpha = 'a-zA-Z';
|
|
66
|
+
const alphanumeric = 'a-zA-Z0-9';
|
|
67
|
+
switch (this.inputType) {
|
|
68
|
+
case 'text':
|
|
69
|
+
return new RegExp(`^[${alpha}]$`);
|
|
70
|
+
case 'number':
|
|
71
|
+
return /^[0-9+]$/;
|
|
72
|
+
case 'mixed':
|
|
73
|
+
return /^[a-zA-Z0-9]$/;
|
|
74
|
+
case 'masked':
|
|
75
|
+
return new RegExp(`^[${alphanumeric}]$`);
|
|
76
|
+
default:
|
|
77
|
+
return /^[0-9]$/;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
buildOtpControls() {
|
|
81
|
+
this.otpArray.clear();
|
|
82
|
+
const pattern = this.getInputPattern();
|
|
83
|
+
for (let i = 0; i < this.otpLength; i++) {
|
|
84
|
+
this.otpArray.push(this.fb.control('', [Validators.required, Validators.pattern(pattern)]));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
togglePasswordVisibility() {
|
|
88
|
+
this.unmaskPassword = !this.unmaskPassword;
|
|
89
|
+
}
|
|
90
|
+
focusFirstInput() {
|
|
91
|
+
if (this.inputs && this.inputs.length > 0) {
|
|
92
|
+
this.inputs.first.nativeElement.focus();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
onInput(event, index) {
|
|
96
|
+
const input = event.target;
|
|
97
|
+
const { value, message } = this.sanitizeWithMessage(input.value);
|
|
98
|
+
this.emitChange(message);
|
|
99
|
+
this.otpArray.at(index).setValue(value, { emitEvent: false });
|
|
100
|
+
if (value && index < this.otpLength - 1) {
|
|
101
|
+
this.inputs.toArray()[index + 1].nativeElement.focus();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
sanitizeWithMessage(rawValue) {
|
|
105
|
+
switch (this.inputType) {
|
|
106
|
+
case 'number':
|
|
107
|
+
if (/[^0-9]/.test(rawValue)) {
|
|
108
|
+
return {
|
|
109
|
+
value: rawValue.replace(/\D/g, ''),
|
|
110
|
+
message: 'Only numbers are allowed'
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { value: rawValue };
|
|
114
|
+
case 'text':
|
|
115
|
+
if (/[^a-zA-Z]/.test(rawValue)) {
|
|
116
|
+
return {
|
|
117
|
+
value: rawValue.replace(/[^a-zA-Z]/g, ''),
|
|
118
|
+
message: 'Only letters are allowed'
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return { value: rawValue, message: 'success' };
|
|
122
|
+
case 'mixed':
|
|
123
|
+
case 'masked':
|
|
124
|
+
if (/[^a-zA-Z0-9]/.test(rawValue)) {
|
|
125
|
+
return {
|
|
126
|
+
value: rawValue.replace(/[^a-zA-Z0-9]/g, ''),
|
|
127
|
+
message: 'Only letters and numbers are allowed'
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return { value: rawValue, message: 'success' };
|
|
131
|
+
default:
|
|
132
|
+
return { value: rawValue, message: 'success' };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
onKeyDown(event, index) {
|
|
136
|
+
if (event.key === 'Backspace' &&
|
|
137
|
+
!this.otpArray.at(index).value &&
|
|
138
|
+
index > 0) {
|
|
139
|
+
this.inputs.toArray()[index - 1].nativeElement.focus();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
onPaste(event) {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
const pasteData = (_b = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) !== null && _b !== void 0 ? _b : '';
|
|
146
|
+
const { value, message } = this.sanitizeWithMessage(pasteData);
|
|
147
|
+
if (value.length !== this.otpLength) {
|
|
148
|
+
this.emitChange('Invalid OTP length');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
value.split('').forEach((char, i) => {
|
|
152
|
+
this.otpArray.at(i).setValue(char, { emitEvent: false });
|
|
153
|
+
});
|
|
154
|
+
this.emitChange(message);
|
|
155
|
+
}
|
|
156
|
+
emitChange(message) {
|
|
157
|
+
const otp = this.otpArray.value.join('');
|
|
158
|
+
this.otpChange.emit({
|
|
159
|
+
value: otp,
|
|
160
|
+
isValid: this.otpForm.valid,
|
|
161
|
+
message: message
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
OtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
166
|
+
OtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OtpBoxComponent, selector: "lib-otp-box", inputs: { otpLength: "otpLength", inputType: "inputType" }, outputs: { otpChange: "otpChange" }, viewQueries: [{ propertyName: "inputs", predicate: ["otpInput"], descendants: true }], ngImport: i0, template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }] });
|
|
167
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, decorators: [{
|
|
168
|
+
type: Component,
|
|
169
|
+
args: [{ selector: 'lib-otp-box', template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"] }]
|
|
170
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { otpChange: [{
|
|
171
|
+
type: Output
|
|
172
|
+
}], otpLength: [{
|
|
173
|
+
type: Input
|
|
174
|
+
}], inputType: [{
|
|
175
|
+
type: Input
|
|
176
|
+
}], inputs: [{
|
|
177
|
+
type: ViewChildren,
|
|
178
|
+
args: ['otpInput']
|
|
179
|
+
}] } });
|
|
180
|
+
|
|
181
|
+
class NgOtpBoxModule {
|
|
182
|
+
}
|
|
183
|
+
NgOtpBoxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
184
|
+
NgOtpBoxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, declarations: [OtpBoxComponent], imports: [CommonModule,
|
|
185
|
+
ReactiveFormsModule,
|
|
186
|
+
FormsModule,
|
|
187
|
+
MatInputModule], exports: [OtpBoxComponent] });
|
|
188
|
+
NgOtpBoxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, imports: [CommonModule,
|
|
189
|
+
ReactiveFormsModule,
|
|
190
|
+
FormsModule,
|
|
191
|
+
MatInputModule] });
|
|
192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, decorators: [{
|
|
193
|
+
type: NgModule,
|
|
194
|
+
args: [{
|
|
195
|
+
declarations: [OtpBoxComponent],
|
|
196
|
+
imports: [
|
|
197
|
+
CommonModule,
|
|
198
|
+
ReactiveFormsModule,
|
|
199
|
+
FormsModule,
|
|
200
|
+
MatInputModule,
|
|
201
|
+
],
|
|
202
|
+
exports: [OtpBoxComponent],
|
|
203
|
+
}]
|
|
204
|
+
}] });
|
|
205
|
+
|
|
206
|
+
/*
|
|
207
|
+
* Public API Surface of ng-otp-box
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Generated bundle index. Do not edit.
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
export { NgOtpBoxComponent, NgOtpBoxModule, NgOtpBoxService, OtpBoxComponent };
|
|
215
|
+
//# sourceMappingURL=ng-otp-box.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-otp-box.mjs","sources":["../../../projects/ng-otp-box/src/lib/ng-otp-box.service.ts","../../../projects/ng-otp-box/src/lib/ng-otp-box.component.ts","../../../projects/ng-otp-box/src/lib/otp-box/otp-box.component.ts","../../../projects/ng-otp-box/src/lib/otp-box/otp-box.component.html","../../../projects/ng-otp-box/src/lib/ng-otp-box.module.ts","../../../projects/ng-otp-box/src/public-api.ts","../../../projects/ng-otp-box/src/ng-otp-box.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NgOtpBoxService {\n\n constructor() { }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-ng-otp-box',\n template: `\n <p>\n ng-otp-box works!\n </p>\n `,\n styles: [\n ]\n})\nexport class NgOtpBoxComponent {\n\n}\n","import { Input, OnInit, Output, ViewChildren } from '@angular/core';\nimport { Component, ElementRef, EventEmitter, QueryList } from '@angular/core';\nimport { FormGroup, FormBuilder, FormArray, Validators } from '@angular/forms';\n\nexport interface otpModel {\n isValid: boolean;\n value: number;\n message? : string;\n}\n\n@Component({\n selector: 'lib-otp-box',\n templateUrl: './otp-box.component.html',\n styleUrls: ['./otp-box.component.css']\n})\nexport class OtpBoxComponent implements OnInit {\n @Output() otpChange = new EventEmitter<any>();\n @Input() otpLength = 6;\n @Input() inputType: 'text' | 'number' | 'mixed' | 'masked' = 'number';\n // @Input() allowUppercase: boolean = true;\n // @Input() showUnMaskCheckBoxYN : boolean = false;\n unmaskPassword: boolean = false;\n\n otpForm!: FormGroup;\n\n @ViewChildren('otpInput') inputs!: QueryList<ElementRef>;\n\n constructor(private fb: FormBuilder) {}\n\n ngOnInit(): void {\n this.otpForm = this.fb.group({\n otp: this.fb.array([]),\n });\n }\n\n ngAfterViewInit(): void {\n this.buildOtpControls();\n\n // this.otpForm.valueChanges.subscribe((val) => {\n // this.emitOtp();\n // });\n }\n\n get otpArray(): FormArray {\n return this.otpForm.get('otp') as FormArray;\n }\n\n private getInputPattern(): RegExp {\n const alpha = 'a-zA-Z';\n const alphanumeric = 'a-zA-Z0-9';\n switch (this.inputType) {\n case 'text':\n return new RegExp(`^[${alpha}]$`);\n\n case 'number':\n return /^[0-9+]$/;\n\n case 'mixed':\n return /^[a-zA-Z0-9]$/;\n\n case 'masked':\n return new RegExp(`^[${alphanumeric}]$`);\n\n default:\n return /^[0-9]$/;\n }\n }\n\n private buildOtpControls(): void {\n this.otpArray.clear();\n const pattern = this.getInputPattern();\n\n for (let i = 0; i < this.otpLength; i++) {\n this.otpArray.push(\n this.fb.control('', [Validators.required, Validators.pattern(pattern)])\n );\n }\n }\n\n togglePasswordVisibility(): void {\n this.unmaskPassword = !this.unmaskPassword;\n }\n\n focusFirstInput() {\n if (this.inputs && this.inputs.length > 0) {\n this.inputs.first.nativeElement.focus();\n }\n }\n\n onInput(event: Event, index: number): void {\n const input = event.target as HTMLInputElement;\n const { value, message } = this.sanitizeWithMessage(input.value);\n this.emitChange(message);\n this.otpArray.at(index).setValue(value, { emitEvent: false });\n\n if (value && index < this.otpLength - 1) {\n this.inputs.toArray()[index + 1].nativeElement.focus();\n }\n }\n\n private sanitizeWithMessage(rawValue: string): { value: string; message?: string } {\n switch (this.inputType) {\n case 'number':\n if (/[^0-9]/.test(rawValue)) {\n return {\n value: rawValue.replace(/\\D/g, ''),\n message: 'Only numbers are allowed'\n };\n }\n return { value: rawValue };\n\n case 'text':\n if (/[^a-zA-Z]/.test(rawValue)) {\n return {\n value: rawValue.replace(/[^a-zA-Z]/g, ''),\n message: 'Only letters are allowed'\n };\n }\n return { value: rawValue, message: 'success' };\n\n case 'mixed':\n case 'masked':\n if (/[^a-zA-Z0-9]/.test(rawValue)) {\n return {\n value: rawValue.replace(/[^a-zA-Z0-9]/g, ''),\n message: 'Only letters and numbers are allowed'\n };\n }\n return { value: rawValue, message: 'success' };\n\n default:\n return { value: rawValue, message: 'success' };\n }\n}\n\n onKeyDown(event: KeyboardEvent, index: number): void {\n if (\n event.key === 'Backspace' &&\n !this.otpArray.at(index).value &&\n index > 0\n ) {\n this.inputs.toArray()[index - 1].nativeElement.focus();\n }\n }\n\nonPaste(event: ClipboardEvent): void {\n event.preventDefault();\n\n const pasteData = event.clipboardData?.getData('text') ?? '';\n const { value, message } = this.sanitizeWithMessage(pasteData);\n\n if (value.length !== this.otpLength) {\n this.emitChange('Invalid OTP length');\n return;\n }\n\n value.split('').forEach((char, i) => {\n this.otpArray.at(i).setValue(char, { emitEvent: false });\n });\n\n this.emitChange(message);\n}\n\n private emitChange(message: any): void {\n const otp = this.otpArray.value.join('');\n this.otpChange.emit({\n value: otp,\n isValid: this.otpForm.valid,\n message: message\n });\n }\n}\n","<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\nimport { MatInputModule } from '@angular/material/input';\n\nimport { OtpBoxComponent } from './otp-box/otp-box.component';\n\n@NgModule({\n declarations: [OtpBoxComponent],\n imports: [\n CommonModule,\n ReactiveFormsModule,\n FormsModule,\n MatInputModule,\n ],\n exports: [OtpBoxComponent],\n})\nexport class NgOtpBoxModule {}\n","/*\n * Public API Surface of ng-otp-box\n */\n\nexport * from './lib/ng-otp-box.service';\nexport * from './lib/ng-otp-box.component';\nexport * from './lib/ng-otp-box.module';\nexport * from './lib/otp-box/otp-box.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, Component, EventEmitter, Output, Input, ViewChildren, NgModule } from '@angular/core';
|
|
3
|
+
import * as i2 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i1 from '@angular/forms';
|
|
6
|
+
import { Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
7
|
+
import * as i3 from '@angular/material/input';
|
|
8
|
+
import { MatInputModule } from '@angular/material/input';
|
|
9
|
+
import * as i4 from '@angular/material/form-field';
|
|
10
|
+
|
|
11
|
+
class NgOtpBoxService {
|
|
12
|
+
constructor() { }
|
|
13
|
+
}
|
|
14
|
+
NgOtpBoxService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
15
|
+
NgOtpBoxService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, providedIn: 'root' });
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxService, decorators: [{
|
|
17
|
+
type: Injectable,
|
|
18
|
+
args: [{
|
|
19
|
+
providedIn: 'root'
|
|
20
|
+
}]
|
|
21
|
+
}], ctorParameters: function () { return []; } });
|
|
22
|
+
|
|
23
|
+
class NgOtpBoxComponent {
|
|
24
|
+
}
|
|
25
|
+
NgOtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26
|
+
NgOtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgOtpBoxComponent, selector: "lib-ng-otp-box", ngImport: i0, template: `
|
|
27
|
+
<p>
|
|
28
|
+
ng-otp-box works!
|
|
29
|
+
</p>
|
|
30
|
+
`, isInline: true });
|
|
31
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxComponent, decorators: [{
|
|
32
|
+
type: Component,
|
|
33
|
+
args: [{ selector: 'lib-ng-otp-box', template: `
|
|
34
|
+
<p>
|
|
35
|
+
ng-otp-box works!
|
|
36
|
+
</p>
|
|
37
|
+
` }]
|
|
38
|
+
}] });
|
|
39
|
+
|
|
40
|
+
class OtpBoxComponent {
|
|
41
|
+
constructor(fb) {
|
|
42
|
+
this.fb = fb;
|
|
43
|
+
this.otpChange = new EventEmitter();
|
|
44
|
+
this.otpLength = 6;
|
|
45
|
+
this.inputType = 'number';
|
|
46
|
+
// @Input() allowUppercase: boolean = true;
|
|
47
|
+
// @Input() showUnMaskCheckBoxYN : boolean = false;
|
|
48
|
+
this.unmaskPassword = false;
|
|
49
|
+
}
|
|
50
|
+
ngOnInit() {
|
|
51
|
+
this.otpForm = this.fb.group({
|
|
52
|
+
otp: this.fb.array([]),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
ngAfterViewInit() {
|
|
56
|
+
this.buildOtpControls();
|
|
57
|
+
// this.otpForm.valueChanges.subscribe((val) => {
|
|
58
|
+
// this.emitOtp();
|
|
59
|
+
// });
|
|
60
|
+
}
|
|
61
|
+
get otpArray() {
|
|
62
|
+
return this.otpForm.get('otp');
|
|
63
|
+
}
|
|
64
|
+
getInputPattern() {
|
|
65
|
+
const alpha = 'a-zA-Z';
|
|
66
|
+
const alphanumeric = 'a-zA-Z0-9';
|
|
67
|
+
switch (this.inputType) {
|
|
68
|
+
case 'text':
|
|
69
|
+
return new RegExp(`^[${alpha}]$`);
|
|
70
|
+
case 'number':
|
|
71
|
+
return /^[0-9+]$/;
|
|
72
|
+
case 'mixed':
|
|
73
|
+
return /^[a-zA-Z0-9]$/;
|
|
74
|
+
case 'masked':
|
|
75
|
+
return new RegExp(`^[${alphanumeric}]$`);
|
|
76
|
+
default:
|
|
77
|
+
return /^[0-9]$/;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
buildOtpControls() {
|
|
81
|
+
this.otpArray.clear();
|
|
82
|
+
const pattern = this.getInputPattern();
|
|
83
|
+
for (let i = 0; i < this.otpLength; i++) {
|
|
84
|
+
this.otpArray.push(this.fb.control('', [Validators.required, Validators.pattern(pattern)]));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
togglePasswordVisibility() {
|
|
88
|
+
this.unmaskPassword = !this.unmaskPassword;
|
|
89
|
+
}
|
|
90
|
+
focusFirstInput() {
|
|
91
|
+
if (this.inputs && this.inputs.length > 0) {
|
|
92
|
+
this.inputs.first.nativeElement.focus();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
onInput(event, index) {
|
|
96
|
+
const input = event.target;
|
|
97
|
+
const { value, message } = this.sanitizeWithMessage(input.value);
|
|
98
|
+
this.emitChange(message);
|
|
99
|
+
this.otpArray.at(index).setValue(value, { emitEvent: false });
|
|
100
|
+
if (value && index < this.otpLength - 1) {
|
|
101
|
+
this.inputs.toArray()[index + 1].nativeElement.focus();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
sanitizeWithMessage(rawValue) {
|
|
105
|
+
switch (this.inputType) {
|
|
106
|
+
case 'number':
|
|
107
|
+
if (/[^0-9]/.test(rawValue)) {
|
|
108
|
+
return {
|
|
109
|
+
value: rawValue.replace(/\D/g, ''),
|
|
110
|
+
message: 'Only numbers are allowed'
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { value: rawValue };
|
|
114
|
+
case 'text':
|
|
115
|
+
if (/[^a-zA-Z]/.test(rawValue)) {
|
|
116
|
+
return {
|
|
117
|
+
value: rawValue.replace(/[^a-zA-Z]/g, ''),
|
|
118
|
+
message: 'Only letters are allowed'
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return { value: rawValue, message: 'success' };
|
|
122
|
+
case 'mixed':
|
|
123
|
+
case 'masked':
|
|
124
|
+
if (/[^a-zA-Z0-9]/.test(rawValue)) {
|
|
125
|
+
return {
|
|
126
|
+
value: rawValue.replace(/[^a-zA-Z0-9]/g, ''),
|
|
127
|
+
message: 'Only letters and numbers are allowed'
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return { value: rawValue, message: 'success' };
|
|
131
|
+
default:
|
|
132
|
+
return { value: rawValue, message: 'success' };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
onKeyDown(event, index) {
|
|
136
|
+
if (event.key === 'Backspace' &&
|
|
137
|
+
!this.otpArray.at(index).value &&
|
|
138
|
+
index > 0) {
|
|
139
|
+
this.inputs.toArray()[index - 1].nativeElement.focus();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
onPaste(event) {
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
const pasteData = event.clipboardData?.getData('text') ?? '';
|
|
145
|
+
const { value, message } = this.sanitizeWithMessage(pasteData);
|
|
146
|
+
if (value.length !== this.otpLength) {
|
|
147
|
+
this.emitChange('Invalid OTP length');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
value.split('').forEach((char, i) => {
|
|
151
|
+
this.otpArray.at(i).setValue(char, { emitEvent: false });
|
|
152
|
+
});
|
|
153
|
+
this.emitChange(message);
|
|
154
|
+
}
|
|
155
|
+
emitChange(message) {
|
|
156
|
+
const otp = this.otpArray.value.join('');
|
|
157
|
+
this.otpChange.emit({
|
|
158
|
+
value: otp,
|
|
159
|
+
isValid: this.otpForm.valid,
|
|
160
|
+
message: message
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
OtpBoxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
165
|
+
OtpBoxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OtpBoxComponent, selector: "lib-otp-box", inputs: { otpLength: "otpLength", inputType: "inputType" }, outputs: { otpChange: "otpChange" }, viewQueries: [{ propertyName: "inputs", predicate: ["otpInput"], descendants: true }], ngImport: i0, template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }] });
|
|
166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OtpBoxComponent, decorators: [{
|
|
167
|
+
type: Component,
|
|
168
|
+
args: [{ selector: 'lib-otp-box', template: "<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>", styles: [".otp-container{display:flex;gap:10px;align-items:center}.otp-mat-field{width:46px}.otp-mat-field input{text-align:center;font-size:18px}.otp-mat-field.mat-form-field-appearance-fill .mat-form-field-flex{background-color:#f2f2f2;border-radius:6px}.otp-mat-field.mat-form-field-invalid .mat-form-field-flex{background-color:#fdecea}\n"] }]
|
|
169
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }]; }, propDecorators: { otpChange: [{
|
|
170
|
+
type: Output
|
|
171
|
+
}], otpLength: [{
|
|
172
|
+
type: Input
|
|
173
|
+
}], inputType: [{
|
|
174
|
+
type: Input
|
|
175
|
+
}], inputs: [{
|
|
176
|
+
type: ViewChildren,
|
|
177
|
+
args: ['otpInput']
|
|
178
|
+
}] } });
|
|
179
|
+
|
|
180
|
+
class NgOtpBoxModule {
|
|
181
|
+
}
|
|
182
|
+
NgOtpBoxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
183
|
+
NgOtpBoxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, declarations: [OtpBoxComponent], imports: [CommonModule,
|
|
184
|
+
ReactiveFormsModule,
|
|
185
|
+
FormsModule,
|
|
186
|
+
MatInputModule], exports: [OtpBoxComponent] });
|
|
187
|
+
NgOtpBoxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, imports: [CommonModule,
|
|
188
|
+
ReactiveFormsModule,
|
|
189
|
+
FormsModule,
|
|
190
|
+
MatInputModule] });
|
|
191
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgOtpBoxModule, decorators: [{
|
|
192
|
+
type: NgModule,
|
|
193
|
+
args: [{
|
|
194
|
+
declarations: [OtpBoxComponent],
|
|
195
|
+
imports: [
|
|
196
|
+
CommonModule,
|
|
197
|
+
ReactiveFormsModule,
|
|
198
|
+
FormsModule,
|
|
199
|
+
MatInputModule,
|
|
200
|
+
],
|
|
201
|
+
exports: [OtpBoxComponent],
|
|
202
|
+
}]
|
|
203
|
+
}] });
|
|
204
|
+
|
|
205
|
+
/*
|
|
206
|
+
* Public API Surface of ng-otp-box
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Generated bundle index. Do not edit.
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
export { NgOtpBoxComponent, NgOtpBoxModule, NgOtpBoxService, OtpBoxComponent };
|
|
214
|
+
//# sourceMappingURL=ng-otp-box.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-otp-box.mjs","sources":["../../../projects/ng-otp-box/src/lib/ng-otp-box.service.ts","../../../projects/ng-otp-box/src/lib/ng-otp-box.component.ts","../../../projects/ng-otp-box/src/lib/otp-box/otp-box.component.ts","../../../projects/ng-otp-box/src/lib/otp-box/otp-box.component.html","../../../projects/ng-otp-box/src/lib/ng-otp-box.module.ts","../../../projects/ng-otp-box/src/public-api.ts","../../../projects/ng-otp-box/src/ng-otp-box.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NgOtpBoxService {\n\n constructor() { }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-ng-otp-box',\n template: `\n <p>\n ng-otp-box works!\n </p>\n `,\n styles: [\n ]\n})\nexport class NgOtpBoxComponent {\n\n}\n","import { Input, OnInit, Output, ViewChildren } from '@angular/core';\nimport { Component, ElementRef, EventEmitter, QueryList } from '@angular/core';\nimport { FormGroup, FormBuilder, FormArray, Validators } from '@angular/forms';\n\nexport interface otpModel {\n isValid: boolean;\n value: number;\n message? : string;\n}\n\n@Component({\n selector: 'lib-otp-box',\n templateUrl: './otp-box.component.html',\n styleUrls: ['./otp-box.component.css']\n})\nexport class OtpBoxComponent implements OnInit {\n @Output() otpChange = new EventEmitter<any>();\n @Input() otpLength = 6;\n @Input() inputType: 'text' | 'number' | 'mixed' | 'masked' = 'number';\n // @Input() allowUppercase: boolean = true;\n // @Input() showUnMaskCheckBoxYN : boolean = false;\n unmaskPassword: boolean = false;\n\n otpForm!: FormGroup;\n\n @ViewChildren('otpInput') inputs!: QueryList<ElementRef>;\n\n constructor(private fb: FormBuilder) {}\n\n ngOnInit(): void {\n this.otpForm = this.fb.group({\n otp: this.fb.array([]),\n });\n }\n\n ngAfterViewInit(): void {\n this.buildOtpControls();\n\n // this.otpForm.valueChanges.subscribe((val) => {\n // this.emitOtp();\n // });\n }\n\n get otpArray(): FormArray {\n return this.otpForm.get('otp') as FormArray;\n }\n\n private getInputPattern(): RegExp {\n const alpha = 'a-zA-Z';\n const alphanumeric = 'a-zA-Z0-9';\n switch (this.inputType) {\n case 'text':\n return new RegExp(`^[${alpha}]$`);\n\n case 'number':\n return /^[0-9+]$/;\n\n case 'mixed':\n return /^[a-zA-Z0-9]$/;\n\n case 'masked':\n return new RegExp(`^[${alphanumeric}]$`);\n\n default:\n return /^[0-9]$/;\n }\n }\n\n private buildOtpControls(): void {\n this.otpArray.clear();\n const pattern = this.getInputPattern();\n\n for (let i = 0; i < this.otpLength; i++) {\n this.otpArray.push(\n this.fb.control('', [Validators.required, Validators.pattern(pattern)])\n );\n }\n }\n\n togglePasswordVisibility(): void {\n this.unmaskPassword = !this.unmaskPassword;\n }\n\n focusFirstInput() {\n if (this.inputs && this.inputs.length > 0) {\n this.inputs.first.nativeElement.focus();\n }\n }\n\n onInput(event: Event, index: number): void {\n const input = event.target as HTMLInputElement;\n const { value, message } = this.sanitizeWithMessage(input.value);\n this.emitChange(message);\n this.otpArray.at(index).setValue(value, { emitEvent: false });\n\n if (value && index < this.otpLength - 1) {\n this.inputs.toArray()[index + 1].nativeElement.focus();\n }\n }\n\n private sanitizeWithMessage(rawValue: string): { value: string; message?: string } {\n switch (this.inputType) {\n case 'number':\n if (/[^0-9]/.test(rawValue)) {\n return {\n value: rawValue.replace(/\\D/g, ''),\n message: 'Only numbers are allowed'\n };\n }\n return { value: rawValue };\n\n case 'text':\n if (/[^a-zA-Z]/.test(rawValue)) {\n return {\n value: rawValue.replace(/[^a-zA-Z]/g, ''),\n message: 'Only letters are allowed'\n };\n }\n return { value: rawValue, message: 'success' };\n\n case 'mixed':\n case 'masked':\n if (/[^a-zA-Z0-9]/.test(rawValue)) {\n return {\n value: rawValue.replace(/[^a-zA-Z0-9]/g, ''),\n message: 'Only letters and numbers are allowed'\n };\n }\n return { value: rawValue, message: 'success' };\n\n default:\n return { value: rawValue, message: 'success' };\n }\n}\n\n onKeyDown(event: KeyboardEvent, index: number): void {\n if (\n event.key === 'Backspace' &&\n !this.otpArray.at(index).value &&\n index > 0\n ) {\n this.inputs.toArray()[index - 1].nativeElement.focus();\n }\n }\n\nonPaste(event: ClipboardEvent): void {\n event.preventDefault();\n\n const pasteData = event.clipboardData?.getData('text') ?? '';\n const { value, message } = this.sanitizeWithMessage(pasteData);\n\n if (value.length !== this.otpLength) {\n this.emitChange('Invalid OTP length');\n return;\n }\n\n value.split('').forEach((char, i) => {\n this.otpArray.at(i).setValue(char, { emitEvent: false });\n });\n\n this.emitChange(message);\n}\n\n private emitChange(message: any): void {\n const otp = this.otpArray.value.join('');\n this.otpChange.emit({\n value: otp,\n isValid: this.otpForm.valid,\n message: message\n });\n }\n}\n","<div>\n <form [formGroup]=\"otpForm\" (paste)=\"onPaste($event)\">\n\n <div class=\"otp-container\" formArrayName=\"otp\">\n <ng-container *ngFor=\"let ctrl of otpArray.controls; let i = index\">\n <mat-form-field appearance=\"outline\" class=\"otp-mat-field\" [class.mat-form-field-invalid]=\"\n otpForm.invalid && (otpForm.touched || otpForm.dirty)\">\n <input matInput [type]=\"inputType === 'masked' ? 'password' : 'text'\" maxlength=\"1\"\n #otpInput cdkFocusInitial [formControlName]=\"i\" (input)=\"onInput($event, i)\"\n (keydown)=\"onKeyDown($event, i)\" />\n </mat-form-field>\n </ng-container>\n </div>\n <!-- <div class=\"otp-password-toggle\" *ngIf=\"inputType === 'password' && showUnMaskCheckBoxYN\">\n <mat-checkbox [checked]=\"unmaskPassword\" (change)=\"togglePasswordVisibility()\">\n Show password\n </mat-checkbox>\n </div> -->\n\n </form>\n</div>","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\nimport { MatInputModule } from '@angular/material/input';\n\nimport { OtpBoxComponent } from './otp-box/otp-box.component';\n\n@NgModule({\n declarations: [OtpBoxComponent],\n imports: [\n CommonModule,\n ReactiveFormsModule,\n FormsModule,\n MatInputModule,\n ],\n exports: [OtpBoxComponent],\n})\nexport class NgOtpBoxModule {}\n","/*\n * Public API Surface of ng-otp-box\n */\n\nexport * from './lib/ng-otp-box.service';\nexport * from './lib/ng-otp-box.component';\nexport * from './lib/ng-otp-box.module';\nexport * from './lib/otp-box/otp-box.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./otp-box/otp-box.component";
|
|
3
|
+
import * as i2 from "@angular/common";
|
|
4
|
+
import * as i3 from "@angular/forms";
|
|
5
|
+
import * as i4 from "@angular/material/input";
|
|
6
|
+
export declare class NgOtpBoxModule {
|
|
7
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgOtpBoxModule, never>;
|
|
8
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<NgOtpBoxModule, [typeof i1.OtpBoxComponent], [typeof i2.CommonModule, typeof i3.ReactiveFormsModule, typeof i3.FormsModule, typeof i4.MatInputModule], [typeof i1.OtpBoxComponent]>;
|
|
9
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<NgOtpBoxModule>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { ElementRef, EventEmitter, QueryList } from '@angular/core';
|
|
3
|
+
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export interface otpModel {
|
|
6
|
+
isValid: boolean;
|
|
7
|
+
value: number;
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class OtpBoxComponent implements OnInit {
|
|
11
|
+
private fb;
|
|
12
|
+
otpChange: EventEmitter<any>;
|
|
13
|
+
otpLength: number;
|
|
14
|
+
inputType: 'text' | 'number' | 'mixed' | 'masked';
|
|
15
|
+
unmaskPassword: boolean;
|
|
16
|
+
otpForm: FormGroup;
|
|
17
|
+
inputs: QueryList<ElementRef>;
|
|
18
|
+
constructor(fb: FormBuilder);
|
|
19
|
+
ngOnInit(): void;
|
|
20
|
+
ngAfterViewInit(): void;
|
|
21
|
+
get otpArray(): FormArray;
|
|
22
|
+
private getInputPattern;
|
|
23
|
+
private buildOtpControls;
|
|
24
|
+
togglePasswordVisibility(): void;
|
|
25
|
+
focusFirstInput(): void;
|
|
26
|
+
onInput(event: Event, index: number): void;
|
|
27
|
+
private sanitizeWithMessage;
|
|
28
|
+
onKeyDown(event: KeyboardEvent, index: number): void;
|
|
29
|
+
onPaste(event: ClipboardEvent): void;
|
|
30
|
+
private emitChange;
|
|
31
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OtpBoxComponent, never>;
|
|
32
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<OtpBoxComponent, "lib-otp-box", never, { "otpLength": "otpLength"; "inputType": "inputType"; }, { "otpChange": "otpChange"; }, never, never, false, never>;
|
|
33
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ng-otp-box",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^15.1.0",
|
|
6
|
+
"@angular/core": "^15.1.0",
|
|
7
|
+
"@angular/cdk": "^15.0.0",
|
|
8
|
+
"@angular/material": "^15.0.0"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"module": "fesm2015/ng-otp-box.mjs",
|
|
15
|
+
"es2020": "fesm2020/ng-otp-box.mjs",
|
|
16
|
+
"esm2020": "esm2020/ng-otp-box.mjs",
|
|
17
|
+
"fesm2020": "fesm2020/ng-otp-box.mjs",
|
|
18
|
+
"fesm2015": "fesm2015/ng-otp-box.mjs",
|
|
19
|
+
"typings": "index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
"./package.json": {
|
|
22
|
+
"default": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./index.d.ts",
|
|
26
|
+
"esm2020": "./esm2020/ng-otp-box.mjs",
|
|
27
|
+
"es2020": "./fesm2020/ng-otp-box.mjs",
|
|
28
|
+
"es2015": "./fesm2015/ng-otp-box.mjs",
|
|
29
|
+
"node": "./fesm2015/ng-otp-box.mjs",
|
|
30
|
+
"default": "./fesm2020/ng-otp-box.mjs"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
package/public-api.d.ts
ADDED