diff --git a/.prettierrc b/.prettierrc index 4985d6f..f5aa16b 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,8 @@ "arrowParens": "avoid", "printWidth": 80, "proseWrap": "always", - "singleQuote": true + "singleQuote": true, + "semi": false, + "trailingComma": "none", + "bracketSpacing": true } diff --git a/apps/playground-e2e/cypress.config.ts b/apps/playground-e2e/cypress.config.ts index 22f7c84..95e482d 100644 --- a/apps/playground-e2e/cypress.config.ts +++ b/apps/playground-e2e/cypress.config.ts @@ -1,6 +1,6 @@ -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; +import { defineConfig } from 'cypress' +import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset' export default defineConfig({ - e2e: nxE2EPreset(__dirname), -}); + e2e: nxE2EPreset(__dirname) +}) diff --git a/apps/playground-e2e/src/e2e/app.cy.ts b/apps/playground-e2e/src/e2e/app.cy.ts index 11c20bc..d5d2372 100644 --- a/apps/playground-e2e/src/e2e/app.cy.ts +++ b/apps/playground-e2e/src/e2e/app.cy.ts @@ -1,13 +1,13 @@ -import { getGreeting } from '../support/app.po'; +import { getGreeting } from '../support/app.po' describe('playground', () => { - beforeEach(() => cy.visit('/')); + beforeEach(() => cy.visit('/')) it('should display welcome message', () => { // Custom command example, see `../support/commands.ts` file - cy.login('my-email@something.com', 'myPassword'); + cy.login('my-email@something.com', 'myPassword') // Function helper example, see `../support/app.po.ts` file - getGreeting().contains('Welcome playground'); - }); -}); + getGreeting().contains('Welcome playground') + }) +}) diff --git a/apps/playground-e2e/src/support/app.po.ts b/apps/playground-e2e/src/support/app.po.ts index 3293424..00f556e 100644 --- a/apps/playground-e2e/src/support/app.po.ts +++ b/apps/playground-e2e/src/support/app.po.ts @@ -1 +1 @@ -export const getGreeting = () => cy.get('h1'); +export const getGreeting = () => cy.get('h1') diff --git a/apps/playground-e2e/src/support/commands.ts b/apps/playground-e2e/src/support/commands.ts index 310f1fa..270f023 100644 --- a/apps/playground-e2e/src/support/commands.ts +++ b/apps/playground-e2e/src/support/commands.ts @@ -12,14 +12,14 @@ declare namespace Cypress { // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Chainable { - login(email: string, password: string): void; + login(email: string, password: string): void } } // // -- This is a parent command -- Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); + console.log('Custom command example: Login', email, password) +}) // // -- This is a child command -- // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) diff --git a/apps/playground-e2e/src/support/e2e.ts b/apps/playground-e2e/src/support/e2e.ts index 3d469a6..185d654 100644 --- a/apps/playground-e2e/src/support/e2e.ts +++ b/apps/playground-e2e/src/support/e2e.ts @@ -14,4 +14,4 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands'; +import './commands' diff --git a/apps/playground/jest.config.ts b/apps/playground/jest.config.ts index 16e9f4b..5d083c1 100644 --- a/apps/playground/jest.config.ts +++ b/apps/playground/jest.config.ts @@ -6,17 +6,17 @@ export default { globals: { 'ts-jest': { tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, + stringifyContentPathRegex: '\\.(html|svg)$' + } }, coverageDirectory: '../../coverage/apps/playground', transform: { - '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', + '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular' }, transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], snapshotSerializers: [ 'jest-preset-angular/build/serializers/no-ng-attributes', 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; + 'jest-preset-angular/build/serializers/html-comment' + ] +} diff --git a/apps/playground/src/app/app-routing.module.ts b/apps/playground/src/app/app-routing.module.ts index 75c17ff..73b3dd7 100644 --- a/apps/playground/src/app/app-routing.module.ts +++ b/apps/playground/src/app/app-routing.module.ts @@ -1,13 +1,13 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { PassCodeDemoComponent } from './demos/pass-code/pass-code-demo.component'; +import { NgModule } from '@angular/core' +import { RouterModule, Routes } from '@angular/router' +import { PassCodeDemoComponent } from './demos/pass-code/pass-code-demo.component' const routes: Routes = [ - { path: 'ngx-pass-code', component: PassCodeDemoComponent }, -]; + { path: 'ngx-pass-code', component: PassCodeDemoComponent } +] @NgModule({ imports: [RouterModule.forRoot(routes)], - exports: [RouterModule], + exports: [RouterModule] }) export class AppRoutingModule {} diff --git a/apps/playground/src/app/app.component.ts b/apps/playground/src/app/app.component.ts index 7424415..992660b 100644 --- a/apps/playground/src/app/app.component.ts +++ b/apps/playground/src/app/app.component.ts @@ -1,8 +1,8 @@ -import { Component } from '@angular/core'; +import { Component } from '@angular/core' @Component({ selector: 'ngx-libs-workspace-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + styleUrls: ['./app.component.scss'] }) export class AppComponent {} diff --git a/apps/playground/src/app/app.module.ts b/apps/playground/src/app/app.module.ts index cfe59cc..bf2e4fb 100644 --- a/apps/playground/src/app/app.module.ts +++ b/apps/playground/src/app/app.module.ts @@ -1,12 +1,12 @@ -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { NgxPassCodeModule } from 'ngx-pass-code'; +import { NgModule } from '@angular/core' +import { ReactiveFormsModule } from '@angular/forms' +import { BrowserModule } from '@angular/platform-browser' +import { NgxPassCodeModule } from 'ngx-pass-code' -import { AppComponent } from './app.component'; +import { AppComponent } from './app.component' -import { AppRoutingModule } from './app-routing.module'; -import { PassCodeDemoComponent } from './demos/pass-code/pass-code-demo.component'; +import { AppRoutingModule } from './app-routing.module' +import { PassCodeDemoComponent } from './demos/pass-code/pass-code-demo.component' @NgModule({ declarations: [AppComponent, PassCodeDemoComponent], @@ -14,8 +14,8 @@ import { PassCodeDemoComponent } from './demos/pass-code/pass-code-demo.componen BrowserModule, AppRoutingModule, ReactiveFormsModule, - NgxPassCodeModule, + NgxPassCodeModule ], - bootstrap: [AppComponent], + bootstrap: [AppComponent] }) export class AppModule {} diff --git a/apps/playground/src/app/demos/pass-code/pass-code-demo.component.ts b/apps/playground/src/app/demos/pass-code/pass-code-demo.component.ts index 223a811..07a7a29 100644 --- a/apps/playground/src/app/demos/pass-code/pass-code-demo.component.ts +++ b/apps/playground/src/app/demos/pass-code/pass-code-demo.component.ts @@ -1,20 +1,20 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { ChangeDetectionStrategy, Component } from '@angular/core' +import { FormControl, FormGroup, Validators } from '@angular/forms' @Component({ selector: 'ngx-libs-workspace-pass-code-demo', templateUrl: './pass-code.component.html', styleUrls: ['./pass-code.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, + changeDetection: ChangeDetectionStrategy.OnPush }) export class PassCodeDemoComponent { form = new FormGroup({ textCode: new FormControl('76', { validators: [Validators.required] }), numberCode: new FormControl(''), - passwordCode: new FormControl('mypass1'), - }); + passwordCode: new FormControl('mypass1') + }) - textCode = this.form.get('textCode') as FormControl; - numberCode = this.form.get('numberCode') as FormControl; - passwordCode = this.form.get('passwordCode') as FormControl; + textCode = this.form.get('textCode') as FormControl + numberCode = this.form.get('numberCode') as FormControl + passwordCode = this.form.get('passwordCode') as FormControl } diff --git a/apps/playground/src/environments/environment.prod.ts b/apps/playground/src/environments/environment.prod.ts index c966979..bc0327d 100644 --- a/apps/playground/src/environments/environment.prod.ts +++ b/apps/playground/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true, -}; + production: true +} diff --git a/apps/playground/src/environments/environment.ts b/apps/playground/src/environments/environment.ts index 66998ae..bc79a5b 100644 --- a/apps/playground/src/environments/environment.ts +++ b/apps/playground/src/environments/environment.ts @@ -3,8 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false, -}; + production: false +} /* * For easier debugging in development mode, you can import the following file diff --git a/apps/playground/src/main.ts b/apps/playground/src/main.ts index d9a2e7e..11a2158 100644 --- a/apps/playground/src/main.ts +++ b/apps/playground/src/main.ts @@ -1,13 +1,13 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { enableProdMode } from '@angular/core' +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import { AppModule } from './app/app.module' +import { environment } from './environments/environment' if (environment.production) { - enableProdMode(); + enableProdMode() } platformBrowserDynamic() .bootstrapModule(AppModule) - .catch((err) => console.error(err)); + .catch(err => console.error(err)) diff --git a/apps/playground/src/polyfills.ts b/apps/playground/src/polyfills.ts index e4555ed..5173f2f 100644 --- a/apps/playground/src/polyfills.ts +++ b/apps/playground/src/polyfills.ts @@ -45,7 +45,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js'; // Included with Angular CLI. +import 'zone.js' // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/apps/playground/src/test-setup.ts b/apps/playground/src/test-setup.ts index 1100b3e..90bc506 100644 --- a/apps/playground/src/test-setup.ts +++ b/apps/playground/src/test-setup.ts @@ -1 +1 @@ -import 'jest-preset-angular/setup-jest'; +import 'jest-preset-angular/setup-jest' diff --git a/jest.config.ts b/jest.config.ts index 2a738f7..e08fb56 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,5 +1,5 @@ -import { getJestProjects } from '@nrwl/jest'; +import { getJestProjects } from '@nrwl/jest' export default { - projects: getJestProjects(), -}; + projects: getJestProjects() +} diff --git a/libs/ngx-pass-code/jest.config.ts b/libs/ngx-pass-code/jest.config.ts index f2c00c4..15655b1 100644 --- a/libs/ngx-pass-code/jest.config.ts +++ b/libs/ngx-pass-code/jest.config.ts @@ -6,17 +6,17 @@ export default { globals: { 'ts-jest': { tsconfig: '/tsconfig.spec.json', - stringifyContentPathRegex: '\\.(html|svg)$', - }, + stringifyContentPathRegex: '\\.(html|svg)$' + } }, coverageDirectory: '../../coverage/libs/ngx-pass-code', transform: { - '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', + '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular' }, transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], snapshotSerializers: [ 'jest-preset-angular/build/serializers/no-ng-attributes', 'jest-preset-angular/build/serializers/ng-snapshot', - 'jest-preset-angular/build/serializers/html-comment', - ], -}; + 'jest-preset-angular/build/serializers/html-comment' + ] +} diff --git a/libs/ngx-pass-code/src/index.ts b/libs/ngx-pass-code/src/index.ts index 6fbdebf..a0f2b70 100644 --- a/libs/ngx-pass-code/src/index.ts +++ b/libs/ngx-pass-code/src/index.ts @@ -1,2 +1,2 @@ -export { PassCodeComponent } from './lib/component/pass-code.component'; -export * from './lib/ngx-pass-code.module'; +export { PassCodeComponent } from './lib/component/pass-code.component' +export * from './lib/ngx-pass-code.module' diff --git a/libs/ngx-pass-code/src/lib/component/pass-code.component.spec.ts b/libs/ngx-pass-code/src/lib/component/pass-code.component.spec.ts index 03a00d2..3d19c7f 100644 --- a/libs/ngx-pass-code/src/lib/component/pass-code.component.spec.ts +++ b/libs/ngx-pass-code/src/lib/component/pass-code.component.spec.ts @@ -1,10 +1,10 @@ -import { Component, ViewChild } from '@angular/core'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; -import { NgxPassCodeModule } from '../ngx-pass-code.module'; +import { Component, ViewChild } from '@angular/core' +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing' +import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms' +import { NgxPassCodeModule } from '../ngx-pass-code.module' -import { PassCodeComponent } from './pass-code.component'; -import spyOn = jest.spyOn; +import { PassCodeComponent } from './pass-code.component' +import spyOn = jest.spyOn @Component({ template: ``, + >` }) class HostTextCodeComponent { - @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent; + @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent control = new FormControl( { value: 'mypass1', disabled: false }, { - validators: Validators.required, + validators: Validators.required } - ); + ) } describe('PassCodeComponent - type text + validation', () => { - let hostComponent: HostTextCodeComponent; - let hostFixture: ComponentFixture; - const codeLength = 7; + let hostComponent: HostTextCodeComponent + let hostFixture: ComponentFixture + const codeLength = 7 const getAllInputs = (): HTMLInputElement[] => { - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - return component.querySelectorAll('input'); - }; + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + return component.querySelectorAll('input') + } beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ReactiveFormsModule, NgxPassCodeModule], - declarations: [HostTextCodeComponent], - }).compileComponents(); + declarations: [HostTextCodeComponent] + }).compileComponents() - hostFixture = TestBed.createComponent(HostTextCodeComponent); - hostComponent = hostFixture.componentInstance; - hostFixture.detectChanges(); - }); + hostFixture = TestBed.createComponent(HostTextCodeComponent) + hostComponent = hostFixture.componentInstance + hostFixture.detectChanges() + }) beforeEach(waitForAsync(() => { // async as initial value is set in timeout hostFixture.whenStable().then(() => { - hostFixture.detectChanges(); - }); - })); + hostFixture.detectChanges() + }) + })) afterEach(() => { - hostFixture.destroy(); - }); + hostFixture.destroy() + }) it('should create', () => { - expect(hostComponent).toBeTruthy(); - expect(hostComponent.passCodeComponent).toBeTruthy(); - expect(getAllInputs().length).toStrictEqual(codeLength); - }); + expect(hostComponent).toBeTruthy() + expect(hostComponent.passCodeComponent).toBeTruthy() + expect(getAllInputs().length).toStrictEqual(codeLength) + }) it('should set the initial value in the ui', () => { expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ @@ -72,21 +72,21 @@ describe('PassCodeComponent - type text + validation', () => { 'a', 's', 's', - '1', - ]); - }); + '1' + ]) + }) it('should update value based on same size set/patched formControl value', () => { - const value = 'test123'; - hostComponent.control.patchValue(value); + const value = 'test123' + hostComponent.control.patchValue(value) expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ - ...value, - ]); - }); + ...value + ]) + }) it('should update value based on smaller set/patched formControl value', () => { - hostComponent.control.patchValue('cat'); + hostComponent.control.patchValue('cat') expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ 'c', @@ -95,93 +95,93 @@ describe('PassCodeComponent - type text + validation', () => { null, null, null, - null, - ]); - }); + null + ]) + }) it('should update value based on bigger set/patched formControl value', () => { - const value = 'dogsareawesome'; - hostComponent.control.patchValue(value); + const value = 'dogsareawesome' + hostComponent.control.patchValue(value) // it will only take how much is needed by length property expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ - ...value.substring(0, codeLength), - ]); - }); + ...value.substring(0, codeLength) + ]) + }) it('should send a new value to parent when view value changes', () => { - const value = 'newvals'; - hostComponent.passCodeComponent.passCodes.patchValue([...value]); + const value = 'newvals' + hostComponent.passCodeComponent.passCodes.patchValue([...value]) - expect(hostComponent.control.value).toStrictEqual(value.toUpperCase()); - }); + expect(hostComponent.control.value).toStrictEqual(value.toUpperCase()) + }) it('should send a lowercase value to parent when view value changes', () => { - const value = 'newvals'; - hostComponent.passCodeComponent.uppercase = false; - hostComponent.passCodeComponent.passCodes.patchValue([...value]); + const value = 'newvals' + hostComponent.passCodeComponent.uppercase = false + hostComponent.passCodeComponent.passCodes.patchValue([...value]) - expect(hostComponent.control.value).toStrictEqual(value); - }); + expect(hostComponent.control.value).toStrictEqual(value) + }) it('should send a touch event when input interaction', () => { - expect(hostComponent.control.touched).toBe(false); // initially + expect(hostComponent.control.touched).toBe(false) // initially - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - component.querySelector('input').dispatchEvent(new Event('blur')); - hostFixture.detectChanges(); + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + component.querySelector('input').dispatchEvent(new Event('blur')) + hostFixture.detectChanges() - expect(hostComponent.control.touched).toBe(true); - expect(component.classList.contains('ng-touched')).toBe(true); - }); + expect(hostComponent.control.touched).toBe(true) + expect(component.classList.contains('ng-touched')).toBe(true) + }) it('should set invalid class when field is required and send null value', () => { - expect(hostComponent.control.valid).toBe(true); // initially + expect(hostComponent.control.valid).toBe(true) // initially - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - const compiledInput = component.querySelector('input'); + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + const compiledInput = component.querySelector('input') - expect(component.classList.contains('ng-invalid')).toBe(false); - expect(compiledInput.classList.contains('invalid-input')).toBe(false); // custom validation class + expect(component.classList.contains('ng-invalid')).toBe(false) + expect(compiledInput.classList.contains('invalid-input')).toBe(false) // custom validation class // clearing value in ui hostComponent.passCodeComponent.passCodes.setValue([ - ...new Array(codeLength).fill(null).map(() => null), - ]); + ...new Array(codeLength).fill(null).map(() => null) + ]) // mark every control dirty hostComponent.passCodeComponent.passCodes.controls.forEach(c => c.markAsDirty() - ); - hostComponent.passCodeComponent.passCodes.updateValueAndValidity(); + ) + hostComponent.passCodeComponent.passCodes.updateValueAndValidity() - hostFixture.detectChanges(); + hostFixture.detectChanges() - expect(hostComponent.control.value).toStrictEqual(null); - expect(component.classList.contains('ng-invalid')).toBe(true); - expect(compiledInput.classList.contains('invalid-input')).toBe(true); - }); + expect(hostComponent.control.value).toStrictEqual(null) + expect(component.classList.contains('ng-invalid')).toBe(true) + expect(compiledInput.classList.contains('invalid-input')).toBe(true) + }) it('should disable/enable ui on control disable', () => { - expect(hostComponent.control.enabled).toStrictEqual(true); + expect(hostComponent.control.enabled).toStrictEqual(true) expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( true - ); + ) - hostComponent.control.disable(); + hostComponent.control.disable() expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( false - ); + ) - hostComponent.control.enable(); + hostComponent.control.enable() expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( true - ); - }); -}); + ) + }) +}) @Component({ template: ` { type="number" [formControl]="control" [autoblur]="true" - >`, + >` }) class HostNumbersCodeComponent { - @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent; - control = new FormControl(null); + @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent + control = new FormControl(null) } describe('PassCodeComponent - type numbers', () => { - let hostComponent: HostNumbersCodeComponent; - let hostFixture: ComponentFixture; - const codeLength = 5; + let hostComponent: HostNumbersCodeComponent + let hostFixture: ComponentFixture + const codeLength = 5 const getAllInputs = (): HTMLInputElement[] => { - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - return component.querySelectorAll('input'); - }; + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + return component.querySelectorAll('input') + } beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ReactiveFormsModule, NgxPassCodeModule], - declarations: [HostNumbersCodeComponent], - }).compileComponents(); + declarations: [HostNumbersCodeComponent] + }).compileComponents() - hostFixture = TestBed.createComponent(HostNumbersCodeComponent); - hostComponent = hostFixture.componentInstance; - hostFixture.detectChanges(); - }); + hostFixture = TestBed.createComponent(HostNumbersCodeComponent) + hostComponent = hostFixture.componentInstance + hostFixture.detectChanges() + }) beforeEach(waitForAsync(() => { // async as initial value is set in timeout hostFixture.whenStable().then(() => { - hostFixture.detectChanges(); - }); - })); + hostFixture.detectChanges() + }) + })) afterEach(() => { - hostFixture.destroy(); - }); + hostFixture.destroy() + }) it('should create', () => { - expect(hostComponent).toBeTruthy(); - expect(hostComponent.passCodeComponent).toBeTruthy(); - expect(getAllInputs().length).toStrictEqual(codeLength); - }); + expect(hostComponent).toBeTruthy() + expect(hostComponent.passCodeComponent).toBeTruthy() + expect(getAllInputs().length).toStrictEqual(codeLength) + }) it('should set the initial value in the ui', () => { expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual( new Array(codeLength).fill(null) - ); - }); + ) + }) it('should update value based on same size set/patched formControl value', () => { - const value = 52647; - hostComponent.control.patchValue(value); + const value = 52647 + hostComponent.control.patchValue(value) expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ - ...value.toString(), - ]); - }); + ...value.toString() + ]) + }) it('should update value based on smaller set/patched formControl value', () => { - hostComponent.control.patchValue(666); + hostComponent.control.patchValue(666) expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ '6', '6', '6', null, - null, - ]); - }); + null + ]) + }) it('should throw error if value type does not match provided type property', () => { - expect(() => hostComponent.control.patchValue('ADSD5')).toThrow(TypeError); - }); + expect(() => hostComponent.control.patchValue('ADSD5')).toThrow(TypeError) + }) it('should update value based on bigger set/patched formControl value', () => { - const value = 6351232; - hostComponent.control.patchValue(value); + const value = 6351232 + hostComponent.control.patchValue(value) // it will only take how much is needed by length property expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual([ - ...value.toString().substring(0, codeLength), - ]); - }); + ...value.toString().substring(0, codeLength) + ]) + }) it('should send a new value to parent when view value changes', () => { - const value = 95123; - hostComponent.passCodeComponent.passCodes.patchValue([...value.toString()]); - expect(hostComponent.control.value).toStrictEqual(value); - }); + const value = 95123 + hostComponent.passCodeComponent.passCodes.patchValue([...value.toString()]) + expect(hostComponent.control.value).toStrictEqual(value) + }) it('should not set invalid class when field is not required and send null value', () => { - expect(hostComponent.control.valid).toBe(true); // initially + expect(hostComponent.control.valid).toBe(true) // initially - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - const compiledInput = component.querySelector('input'); + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + const compiledInput = component.querySelector('input') - expect(component.classList.contains('ng-invalid')).toBe(false); - expect(compiledInput.classList.contains('invalid-input')).toBe(false); // custom validation class + expect(component.classList.contains('ng-invalid')).toBe(false) + expect(compiledInput.classList.contains('invalid-input')).toBe(false) // custom validation class // clearing value in ui hostComponent.passCodeComponent.passCodes.setValue([ - ...new Array(codeLength).fill(null), - ]); + ...new Array(codeLength).fill(null) + ]) - hostFixture.detectChanges(); + hostFixture.detectChanges() - expect(hostComponent.control.value).toStrictEqual(null); - expect(component.classList.contains('ng-invalid')).toBe(false); - expect(compiledInput.classList.contains('invalid-input')).toBe(false); - }); + expect(hostComponent.control.value).toStrictEqual(null) + expect(component.classList.contains('ng-invalid')).toBe(false) + expect(compiledInput.classList.contains('invalid-input')).toBe(false) + }) it('should move to previous input element', () => { - const inputs = getAllInputs(); + const inputs = getAllInputs() - const firstInput = inputs[0]; - const secondInput = inputs[1]; + const firstInput = inputs[0] + const secondInput = inputs[1] - const firstInputSpy = spyOn(firstInput, 'focus'); - const secondInputSpy = spyOn(secondInput, 'focus'); + const firstInputSpy = spyOn(firstInput, 'focus') + const secondInputSpy = spyOn(secondInput, 'focus') - secondInput.focus(); - hostFixture.detectChanges(); + secondInput.focus() + hostFixture.detectChanges() - expect(secondInputSpy).toHaveBeenCalled(); + expect(secondInputSpy).toHaveBeenCalled() - secondInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 8 })); // backspace - moves to previous element - hostFixture.detectChanges(); + secondInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 8 })) // backspace - moves to previous element + hostFixture.detectChanges() - expect(firstInputSpy).toHaveBeenCalled(); - }); + expect(firstInputSpy).toHaveBeenCalled() + }) it('should move to next input element if previous has value', () => { - const inputs = getAllInputs(); + const inputs = getAllInputs() - const firstInput = inputs[0]; - const secondInput = inputs[1]; + const firstInput = inputs[0] + const secondInput = inputs[1] - const firstInputSpy = spyOn(firstInput, 'focus'); - const secondInputSpy = spyOn(secondInput, 'focus'); + const firstInputSpy = spyOn(firstInput, 'focus') + const secondInputSpy = spyOn(secondInput, 'focus') - firstInput.focus(); - firstInput.value = '2'; - hostFixture.detectChanges(); + firstInput.focus() + firstInput.value = '2' + hostFixture.detectChanges() - expect(firstInputSpy).toHaveBeenCalled(); + expect(firstInputSpy).toHaveBeenCalled() - firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 53 })); - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 53 })) + hostFixture.detectChanges() - expect(secondInputSpy).toHaveBeenCalled(); - }); + expect(secondInputSpy).toHaveBeenCalled() + }) it('should not move to next input element if previous input is empty', () => { - const inputs = getAllInputs(); + const inputs = getAllInputs() - const firstInput = inputs[0]; - const secondInput = inputs[1]; + const firstInput = inputs[0] + const secondInput = inputs[1] - const firstInputSpy = spyOn(firstInput, 'focus'); - const secondInputSpy = spyOn(secondInput, 'focus'); + const firstInputSpy = spyOn(firstInput, 'focus') + const secondInputSpy = spyOn(secondInput, 'focus') - expect(firstInput.value).toStrictEqual(''); // first input is empty + expect(firstInput.value).toStrictEqual('') // first input is empty - firstInput.focus(); - hostFixture.detectChanges(); + firstInput.focus() + hostFixture.detectChanges() - expect(firstInputSpy).toHaveBeenCalled(); + expect(firstInputSpy).toHaveBeenCalled() - firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 50 })); // 2 key number - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 50 })) // 2 key number + hostFixture.detectChanges() - expect(secondInputSpy).not.toHaveBeenCalled(); - }); + expect(secondInputSpy).not.toHaveBeenCalled() + }) it('should move to next input element if input is not empty', () => { - const inputs = getAllInputs(); + const inputs = getAllInputs() - const firstInput = inputs[0] as HTMLInputElement; - const secondInput = inputs[1] as HTMLInputElement; + const firstInput = inputs[0] as HTMLInputElement + const secondInput = inputs[1] as HTMLInputElement - const firstInputSpy = spyOn(firstInput, 'focus'); - const secondInputSpy = spyOn(secondInput, 'focus'); + const firstInputSpy = spyOn(firstInput, 'focus') + const secondInputSpy = spyOn(secondInput, 'focus') - firstInput.value = '1'; - expect(firstInput.value).toStrictEqual('1'); // first input is not empty + firstInput.value = '1' + expect(firstInput.value).toStrictEqual('1') // first input is not empty - firstInput.focus(); - hostFixture.detectChanges(); + firstInput.focus() + hostFixture.detectChanges() - expect(firstInputSpy).toHaveBeenCalled(); + expect(firstInputSpy).toHaveBeenCalled() - firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 50 })); // 2 key number - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 50 })) // 2 key number + hostFixture.detectChanges() - expect(secondInputSpy).toHaveBeenCalled(); - }); + expect(secondInputSpy).toHaveBeenCalled() + }) it('should substring value on specific keys for number codes', () => { - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - const firstInput = component.querySelector('input'); + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + const firstInput = component.querySelector('input') - firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 53 })); + firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 53 })) - firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })); // space key - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })) // space key + hostFixture.detectChanges() - expect(firstInput.value).toStrictEqual(''); // space key ignored - value is the same + expect(firstInput.value).toStrictEqual('') // space key ignored - value is the same - firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })); // tab key - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 9 })) // tab key + hostFixture.detectChanges() - expect(firstInput.value).toStrictEqual(''); // tab ignored - value is the same - }); + expect(firstInput.value).toStrictEqual('') // tab ignored - value is the same + }) it('should ignore tab key press', () => { - const inputs = getAllInputs(); + const inputs = getAllInputs() - const firstInput = inputs[0]; - const secondInput = inputs[1]; + const firstInput = inputs[0] + const secondInput = inputs[1] - const firstInputSpy = spyOn(firstInput, 'focus'); - const secondInputSpy = spyOn(secondInput, 'focus'); + const firstInputSpy = spyOn(firstInput, 'focus') + const secondInputSpy = spyOn(secondInput, 'focus') - expect(firstInput.value).toStrictEqual(''); + expect(firstInput.value).toStrictEqual('') - firstInput.focus(); - hostFixture.detectChanges(); + firstInput.focus() + hostFixture.detectChanges() - expect(firstInputSpy).toHaveBeenCalled(); + expect(firstInputSpy).toHaveBeenCalled() - firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 9 })); // tab key - hostFixture.detectChanges(); + firstInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 9 })) // tab key + hostFixture.detectChanges() - expect(secondInputSpy).not.toHaveBeenCalled(); - }); + expect(secondInputSpy).not.toHaveBeenCalled() + }) it('should blur out on last input if it has value', () => { - const allInputs = getAllInputs(); - const lastInput = allInputs[allInputs.length - 1]; + const allInputs = getAllInputs() + const lastInput = allInputs[allInputs.length - 1] - const lastInputBlurSpy = spyOn(lastInput, 'blur'); + const lastInputBlurSpy = spyOn(lastInput, 'blur') - expect(lastInput.value).toStrictEqual(''); + expect(lastInput.value).toStrictEqual('') - lastInput.value = '2'; - lastInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 39 })); - hostFixture.detectChanges(); + lastInput.value = '2' + lastInput.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 39 })) + hostFixture.detectChanges() - expect(lastInputBlurSpy).toHaveBeenCalled(); - }); -}); + expect(lastInputBlurSpy).toHaveBeenCalled() + }) +}) @Component({ template: ``, + >` }) class HostPasswordCodeComponent { - @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent; + @ViewChild(PassCodeComponent) passCodeComponent!: PassCodeComponent control = new FormControl({ value: null, - disabled: true, - }); + disabled: true + }) } describe('PassCodeComponent - type password + disabled', () => { - let hostComponent: HostPasswordCodeComponent; - let hostFixture: ComponentFixture; - const codeLength = 6; + let hostComponent: HostPasswordCodeComponent + let hostFixture: ComponentFixture + const codeLength = 6 const getAllInputs = (): HTMLInputElement[] => { - const compiled = hostFixture.debugElement.nativeElement; - const component = compiled.querySelector('ngx-pass-code'); - return component.querySelectorAll('input'); - }; + const compiled = hostFixture.debugElement.nativeElement + const component = compiled.querySelector('ngx-pass-code') + return component.querySelectorAll('input') + } beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ReactiveFormsModule, NgxPassCodeModule], - declarations: [HostPasswordCodeComponent], - }).compileComponents(); + declarations: [HostPasswordCodeComponent] + }).compileComponents() - hostFixture = TestBed.createComponent(HostPasswordCodeComponent); - hostComponent = hostFixture.componentInstance; - hostFixture.detectChanges(); - }); + hostFixture = TestBed.createComponent(HostPasswordCodeComponent) + hostComponent = hostFixture.componentInstance + hostFixture.detectChanges() + }) beforeEach(waitForAsync(() => { // async as initial value is set in timeout hostFixture.whenStable().then(() => { - hostFixture.detectChanges(); - }); - })); + hostFixture.detectChanges() + }) + })) afterEach(() => { - hostFixture.destroy(); - }); + hostFixture.destroy() + }) it('should create', () => { - expect(hostComponent).toBeTruthy(); - expect(hostComponent.passCodeComponent).toBeTruthy(); - expect(getAllInputs().length).toStrictEqual(codeLength); - }); + expect(hostComponent).toBeTruthy() + expect(hostComponent.passCodeComponent).toBeTruthy() + expect(getAllInputs().length).toStrictEqual(codeLength) + }) it('should set the initial value in the ui', () => { expect(hostComponent.passCodeComponent.passCodes.value).toStrictEqual( new Array(codeLength).fill(null) - ); - }); + ) + }) it('should enable/disable ui on control disable', () => { - expect(hostComponent.control.enabled).toStrictEqual(false); + expect(hostComponent.control.enabled).toStrictEqual(false) expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( false - ); + ) - hostComponent.control.enable(); + hostComponent.control.enable() expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( true - ); + ) - hostComponent.control.disable(); + hostComponent.control.disable() expect(hostComponent.passCodeComponent.passCodes.enabled).toStrictEqual( false - ); - }); -}); + ) + }) +}) diff --git a/libs/ngx-pass-code/src/lib/component/pass-code.component.ts b/libs/ngx-pass-code/src/lib/component/pass-code.component.ts index dd6b2b1..e68d7f4 100644 --- a/libs/ngx-pass-code/src/lib/component/pass-code.component.ts +++ b/libs/ngx-pass-code/src/lib/component/pass-code.component.ts @@ -4,160 +4,160 @@ import { Component, Input, OnDestroy, - OnInit, -} from '@angular/core'; + OnInit +} from '@angular/core' import { ControlValueAccessor, FormArray, FormControl, NgControl, ValidationErrors, - Validator, -} from '@angular/forms'; -import { distinctUntilChanged, map, Subject, takeUntil, tap } from 'rxjs'; + Validator +} from '@angular/forms' +import { distinctUntilChanged, map, Subject, takeUntil, tap } from 'rxjs' @Component({ selector: 'ngx-pass-code', templateUrl: './pass-code.component.html', styleUrls: ['./pass-code.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, + changeDetection: ChangeDetectionStrategy.OnPush }) export class PassCodeComponent implements OnInit, OnDestroy, ControlValueAccessor, Validator { - @Input() length = 0; - @Input() type: 'text' | 'number' | 'password' = 'text'; - @Input() uppercase = false; - @Input() autofocus = false; // set focus on first input - @Input() autoblur = false; // remove focus from last input when filled + @Input() length = 0 + @Input() type: 'text' | 'number' | 'password' = 'text' + @Input() uppercase = false + @Input() autofocus = false // set focus on first input + @Input() autoblur = false // remove focus from last input when filled - passCodes!: FormArray; - isCodeInvalid = false; // validation is triggered only if all controls are invalid + passCodes!: FormArray + isCodeInvalid = false // validation is triggered only if all controls are invalid - private initialized = false; - private unsubscribe$ = new Subject(); + private initialized = false + private unsubscribe$ = new Subject() // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange = (value: string | number | null) => {}; + onChange = (value: string | number | null) => {} // eslint-disable-next-line @typescript-eslint/no-empty-function - onTouched = () => {}; + onTouched = () => {} constructor( private controlDirective: NgControl, private cdRef: ChangeDetectorRef ) { - this.controlDirective.valueAccessor = this; + this.controlDirective.valueAccessor = this } ngOnInit(): void { this.passCodes = new FormArray( [...new Array(this.length)].map(() => new FormControl('')) - ); + ) - this.setSyncValidatorsFromParent(); - this.updateParentValidation(); - this.propagateViewToModel(); + this.setSyncValidatorsFromParent() + this.updateParentValidation() + this.propagateViewToModel() } ngOnDestroy(): void { - this.unsubscribe$.next(); - this.unsubscribe$.complete(); + this.unsubscribe$.next() + this.unsubscribe$.complete() } writeValue(value: string): void { - const stringifyTrimmedValue = value?.toString().trim(); + const stringifyTrimmedValue = value?.toString().trim() if (!this.initialized) { // issue - https://github.com/angular/angular/issues/29218 - have to know length property before writing any value setTimeout(() => { - this.initialized = true; - this.updateView(stringifyTrimmedValue); - }); + this.initialized = true + this.updateView(stringifyTrimmedValue) + }) } else { - this.updateView(stringifyTrimmedValue); + this.updateView(stringifyTrimmedValue) } } registerOnChange(fn: any): void { - this.onChange = fn; + this.onChange = fn } registerOnTouched(fn: any): void { - this.onTouched = fn; + this.onTouched = fn } setDisabledState(isDisabled: boolean): void { if (!this.initialized) { setTimeout(() => { - this.disableControls(isDisabled); - }); + this.disableControls(isDisabled) + }) - return; + return } - this.disableControls(isDisabled); + this.disableControls(isDisabled) } validate(): ValidationErrors | null { if (this.passCodes.valid) { - return null; + return null } const errors = this.passCodes.controls .map(control => control.errors) - .filter(error => error !== null); + .filter(error => error !== null) - return errors.length ? errors : null; + return errors.length ? errors : null } private setSyncValidatorsFromParent(): void { - const parentValidators = this.controlDirective.control?.validator; + const parentValidators = this.controlDirective.control?.validator if (!parentValidators) { - return; + return } this.passCodes.controls.forEach(control => { - control.setValidators(parentValidators); - }); - this.passCodes.updateValueAndValidity({ emitEvent: false }); + control.setValidators(parentValidators) + }) + this.passCodes.updateValueAndValidity({ emitEvent: false }) } private updateParentValidation(): void { - const parentControl = this.controlDirective.control; + const parentControl = this.controlDirective.control if (!parentControl) { - return; + return } - parentControl.setValidators(this.validate.bind(this)); - parentControl.updateValueAndValidity({ emitEvent: false }); + parentControl.setValidators(this.validate.bind(this)) + parentControl.updateValueAndValidity({ emitEvent: false }) } private updateView(value: string): void { - value ? this.setValue(value) : this.resetValue(); - this.updateCodeValidity(); + value ? this.setValue(value) : this.resetValue() + this.updateCodeValidity() } private setValue(value: string): void { if (this.type === 'number' && isNaN(parseInt(value))) { throw new TypeError( 'Provided value does not match provided type property number!' - ); + ) } - const splittedValue = value.substring(0, this.length).split(''); // remove chars after specified length and split + const splittedValue = value.substring(0, this.length).split('') // remove chars after specified length and split if (splittedValue.length < this.length) { - this.resetValue(); + this.resetValue() } - this.passCodes.patchValue(splittedValue, { emitEvent: false }); + this.passCodes.patchValue(splittedValue, { emitEvent: false }) } private resetValue(): void { - const nullValues = Array(this.length).fill(null); - this.passCodes.patchValue(nullValues, { emitEvent: false }); + const nullValues = Array(this.length).fill(null) + this.passCodes.patchValue(nullValues, { emitEvent: false }) } private propagateViewToModel(): void { @@ -165,43 +165,43 @@ export class PassCodeComponent .pipe( tap(() => this.updateCodeValidity()), map(codes => { - const code = codes.join(''); + const code = codes.join('') if (this.passCodes.invalid || !code) { - return null; + return null } if (this.type === 'number') { - return parseInt(code); + return parseInt(code) } - return this.uppercase ? code.toUpperCase() : code; + return this.uppercase ? code.toUpperCase() : code }), distinctUntilChanged(), takeUntil(this.unsubscribe$) ) - .subscribe((value: string | number | null) => this.onChange(value)); + .subscribe((value: string | number | null) => this.onChange(value)) } private updateCodeValidity(): void { - const allControlsAreInvalid = this.validate()?.['length'] === this.length; + const allControlsAreInvalid = this.validate()?.['length'] === this.length const allControlsAreDirty = this.passCodes.controls.every( control => control.dirty - ); + ) - this.isCodeInvalid = allControlsAreInvalid && allControlsAreDirty; + this.isCodeInvalid = allControlsAreInvalid && allControlsAreDirty - this.controlDirective.control?.updateValueAndValidity({ emitEvent: false }); - this.cdRef.markForCheck(); + this.controlDirective.control?.updateValueAndValidity({ emitEvent: false }) + this.cdRef.markForCheck() - this.cdRef.detectChanges(); + this.cdRef.detectChanges() } private disableControls(isDisabled: boolean): void { isDisabled ? this.passCodes.disable({ emitEvent: false }) - : this.passCodes.enable({ emitEvent: false }); + : this.passCodes.enable({ emitEvent: false }) - this.controlDirective.control?.updateValueAndValidity({ emitEvent: false }); + this.controlDirective.control?.updateValueAndValidity({ emitEvent: false }) } } diff --git a/libs/ngx-pass-code/src/lib/directives/autofocus-first-input.directive.ts b/libs/ngx-pass-code/src/lib/directives/autofocus-first-input.directive.ts index bf86d41..8856bb7 100644 --- a/libs/ngx-pass-code/src/lib/directives/autofocus-first-input.directive.ts +++ b/libs/ngx-pass-code/src/lib/directives/autofocus-first-input.directive.ts @@ -1,11 +1,11 @@ -import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core'; +import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core' @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector - selector: '[autofocusFirstInput]', + selector: '[autofocusFirstInput]' }) export class AutofocusFirstInputDirective implements AfterViewInit { - @Input() autofocus = false; + @Input() autofocus = false constructor(private elementRef: ElementRef) {} @@ -13,13 +13,13 @@ export class AutofocusFirstInputDirective implements AfterViewInit { if (this.autofocus) { const firstInput = this.elementRef.nativeElement.querySelector( 'input' - ) as HTMLInputElement; + ) as HTMLInputElement // wait for control value set so it can be selected and overridden on typing setTimeout(() => { - firstInput.focus(); - firstInput.select(); - }); + firstInput.focus() + firstInput.select() + }) } } } diff --git a/libs/ngx-pass-code/src/lib/directives/focus-next-previous-input.directive.ts b/libs/ngx-pass-code/src/lib/directives/focus-next-previous-input.directive.ts index 8c2a236..f6e739c 100644 --- a/libs/ngx-pass-code/src/lib/directives/focus-next-previous-input.directive.ts +++ b/libs/ngx-pass-code/src/lib/directives/focus-next-previous-input.directive.ts @@ -1,66 +1,66 @@ -import { Directive, HostListener, Input } from '@angular/core'; +import { Directive, HostListener, Input } from '@angular/core' @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector - selector: '[focusNextPreviousInput]', + selector: '[focusNextPreviousInput]' }) export class FocusNextPreviousInputDirective { - @Input() autoblur = false; + @Input() autoblur = false - private BACKSPACE_KEY = 8; - private TAB_KEY = 9; - private DELETE_KEY = 46; - private LEFT_ARROW_KEY = 37; - private RIGHT_ARROW_KEY = 39; - private SPACE_KEY = 32; + private BACKSPACE_KEY = 8 + private TAB_KEY = 9 + private DELETE_KEY = 46 + private LEFT_ARROW_KEY = 37 + private RIGHT_ARROW_KEY = 39 + private SPACE_KEY = 32 @HostListener('keyup', ['$event']) onKeyUp(e: any) { - e.preventDefault(); + e.preventDefault() if ( e.keyCode === this.LEFT_ARROW_KEY || e.keyCode === this.DELETE_KEY || e.keyCode === this.BACKSPACE_KEY ) { - this.goPrevious(e); - return; + this.goPrevious(e) + return } // allow jumping across if (e.keyCode === this.TAB_KEY) { - return; + return } if (e.srcElement.maxLength === e.srcElement.value.length) { - this.goNext(e); + this.goNext(e) } } private goPrevious(e: any): void { - const previousControl = e.srcElement.previousElementSibling; + const previousControl = e.srcElement.previousElementSibling if (previousControl) { - previousControl.focus(); - previousControl.select(); + previousControl.focus() + previousControl.select() } } private goNext(e: any): void { - const nextControl = e.srcElement.nextElementSibling; + const nextControl = e.srcElement.nextElementSibling if (nextControl) { - nextControl.focus(); - nextControl.select(); + nextControl.focus() + nextControl.select() } else if (this.autoblur) { - e.srcElement.blur(); + e.srcElement.blur() } } @HostListener('keydown', ['$event']) onKeyDown(e: any) { // prevent whitespace if (e.keyCode === this.SPACE_KEY) { - e.preventDefault(); - return; + e.preventDefault() + return } // assure only one number @@ -72,7 +72,7 @@ export class FocusNextPreviousInputDirective { e.keyCode !== this.LEFT_ARROW_KEY && e.keyCode !== this.TAB_KEY ) { - e.srcElement.value = e.srcElement.value.toString().substring(0, 0); + e.srcElement.value = e.srcElement.value.toString().substring(0, 0) } } } diff --git a/libs/ngx-pass-code/src/lib/directives/transform-uppercase.directive.ts b/libs/ngx-pass-code/src/lib/directives/transform-uppercase.directive.ts index 3764e6f..a4916ab 100644 --- a/libs/ngx-pass-code/src/lib/directives/transform-uppercase.directive.ts +++ b/libs/ngx-pass-code/src/lib/directives/transform-uppercase.directive.ts @@ -1,17 +1,17 @@ -import { Directive, ElementRef, Input, OnInit } from '@angular/core'; +import { Directive, ElementRef, Input, OnInit } from '@angular/core' @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector - selector: '[transformInputValue]', + selector: '[transformInputValue]' }) export class TransformInputValueDirective implements OnInit { - @Input() uppercase = false; + @Input() uppercase = false constructor(private el: ElementRef) {} ngOnInit(): void { this.uppercase ? (this.el.nativeElement.style.textTransform = 'uppercase') - : (this.el.nativeElement.style.textTransform = ''); + : (this.el.nativeElement.style.textTransform = '') } } diff --git a/libs/ngx-pass-code/src/lib/ngx-pass-code.module.ts b/libs/ngx-pass-code/src/lib/ngx-pass-code.module.ts index 91ff7ab..c2fa785 100644 --- a/libs/ngx-pass-code/src/lib/ngx-pass-code.module.ts +++ b/libs/ngx-pass-code/src/lib/ngx-pass-code.module.ts @@ -1,10 +1,10 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { PassCodeComponent } from './component/pass-code.component'; -import { AutofocusFirstInputDirective } from './directives/autofocus-first-input.directive'; -import { FocusNextPreviousInputDirective } from './directives/focus-next-previous-input.directive'; -import { TransformInputValueDirective } from './directives/transform-uppercase.directive'; +import { CommonModule } from '@angular/common' +import { NgModule } from '@angular/core' +import { ReactiveFormsModule } from '@angular/forms' +import { PassCodeComponent } from './component/pass-code.component' +import { AutofocusFirstInputDirective } from './directives/autofocus-first-input.directive' +import { FocusNextPreviousInputDirective } from './directives/focus-next-previous-input.directive' +import { TransformInputValueDirective } from './directives/transform-uppercase.directive' @NgModule({ imports: [CommonModule, ReactiveFormsModule], @@ -12,8 +12,8 @@ import { TransformInputValueDirective } from './directives/transform-uppercase.d PassCodeComponent, FocusNextPreviousInputDirective, TransformInputValueDirective, - AutofocusFirstInputDirective, + AutofocusFirstInputDirective ], - exports: [PassCodeComponent], + exports: [PassCodeComponent] }) export class NgxPassCodeModule {} diff --git a/libs/ngx-pass-code/src/test-setup.ts b/libs/ngx-pass-code/src/test-setup.ts index 1100b3e..90bc506 100644 --- a/libs/ngx-pass-code/src/test-setup.ts +++ b/libs/ngx-pass-code/src/test-setup.ts @@ -1 +1 @@ -import 'jest-preset-angular/setup-jest'; +import 'jest-preset-angular/setup-jest' diff --git a/package.json b/package.json index a9e1a9b..2387446 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "prepare": "husky install", "start": "nx serve", "build": "nx build", + "prettier:write": "prettier --write \"**/*.{ts,scss,html}\"", + "prettier:check": "prettier --check \"**/*.{ts,scss,html}\"", "deploy-page": "nx build --prod --output-path docs --base-href .", "configure-deploy": "nx generate ngx-deploy-npm:install", "ngx-pass-code:test:dev": "nx test ngx-pass-code --watchAll --coverage",