diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b802e2cc..be668fdf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,8 +23,11 @@ jobs: run: | bun i bun run build:lib + - name: Setup npm token + run: | + echo "//registry.npmjs.org/:_authToken=${{ secrets.npm_token }}" > dist/ngx-mask-lib/.npmrc - name: Publish library - run: bun run publish:lib + run: bun publish:lib env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} diff --git a/CHANGELOG.md b/CHANGELOG.md index 55662a37..8fb3311c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +# 18.0.1(2024-10-29) + +### Breaking Changes + +- rename "IConfig" to "NgxMaskConfig" +- rename "optionsConfig" to "NgxMaskOptions" +- change interface to type + +### Fix + +- Fix ([#1410](https://github.com/JsDaddy/ngx-mask/issues/1410)) + +# 17.1.8(2024-07-16) + +### Fix + +- Fix ([#1344](https://github.com/JsDaddy/ngx-mask/issues/1344)) +- Fix ([#1356](https://github.com/JsDaddy/ngx-mask/issues/1356)) + # 17.1.8(2024-07-16) ### Fix diff --git a/README.md b/README.md index 156cd1de..2727163a 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,9 @@ bootstrapApplication(AppComponent, { ### Passing your own mask config options ```typescript -import { IConfig } from 'ngx-mask' +import { NgxMaskConfig } from 'ngx-mask' -const maskConfig: Partial = { +const maskConfig: Partial = { validation: false, }; @@ -90,7 +90,7 @@ bootstrapApplication(AppComponent, { ### Using a function to configure: ```typescript -const maskConfigFunction: () => Partial = () => { +const maskConfigFunction: () => Partial = () => { return { validation: false, }; @@ -144,9 +144,9 @@ Import **ngx-mask** module in Angular app. ### With default mask config options ```typescript -import { NgxMaskModule, IConfig } from 'ngx-mask' +import { NgxMaskModule, NgxMaskConfig } from 'ngx-mask' -export const options: Partial | (() => Partial) = null; +export const options: Partial | (() => Partial) = null; @NgModule({ imports: [ @@ -158,9 +158,9 @@ export const options: Partial | (() => Partial) = null; ### Passing in your own mask config options ```typescript -import { NgxMaskModule, IConfig } from 'ngx-mask' +import { NgxMaskModule, NgxMaskConfig } from 'ngx-mask' -const maskConfig: Partial = { +const maskConfig: Partial = { validation: false, }; @@ -174,7 +174,7 @@ const maskConfig: Partial = { Or using a function to get the config: ```typescript -const maskConfigFunction: () => Partial = () => { +const maskConfigFunction: () => Partial = () => { return { validation: false, }; @@ -193,12 +193,6 @@ Then, just define masks in inputs. Text [documentation](https://github.com/JsDaddy/ngx-mask/blob/develop/USAGE.md) -## Setup hooks - -```bash -$ npm run init:hooks -``` - ## Contributing We would love some contributions! Check out this [document](https://github.com/JsDaddy/ngx-mask/blob/develop/CONTRIBUTING.md) to get started. diff --git a/angular.json b/angular.json index 077401fd..19f82bd1 100644 --- a/angular.json +++ b/angular.json @@ -26,8 +26,7 @@ "extractLicenses": false, "sourceMap": true, "optimization": false, - "namedChunks": true, - "polyfills": ["zone.js"] + "namedChunks": true }, "configurations": { "production": { diff --git a/bun.lockb b/bun.lockb index b1a2112e..de39f5a7 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/cypress.config.ts b/cypress.config.ts index 3a6c1093..03eb55c7 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'cypress'; export default defineConfig({ projectId: 'qhyo66', + component: { devServer: { framework: 'angular', @@ -9,5 +10,6 @@ export default defineConfig({ }, specPattern: 'projects/ngx-mask-lib/src/test/**/*.cy-spec.ts', }, + defaultCommandTimeout: 10000, }); diff --git a/eslint.config.js b/eslint.config.js index 29499b84..03e0fa85 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -51,6 +51,11 @@ module.exports = tseslint.config( // and treated as if they are HTML files (and therefore have the .html config below applied to them) processor: angular.processInlineTemplates, // Override specific rules for TypeScript files (these will take priority over the extended configs above) + languageOptions: { + parserOptions: { + project: ['./tsconfig.eslint.json'], + }, + }, rules: { '@angular-eslint/component-selector': [ 'error', @@ -68,25 +73,90 @@ module.exports = tseslint.config( type: 'attribute', }, ], - '@typescript-eslint/prefer-for-of': 'off', - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - }, - ], - '@typescript-eslint/no-empty-function': [ + '@typescript-eslint/consistent-type-definitions': ['error', 'type'], + '@typescript-eslint/ban-ts-comment': ['error', { minimumDescriptionLength: 10 }], + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-empty-object-type': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-wrapper-object-types': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + 'no-array-constructor': 'off', + 'no-useless-constructor': 'off', + 'no-return-await': 'error', + 'no-useless-catch': 'error', + 'no-unused-labels': 'error', + 'no-unneeded-ternary': 'error', + 'no-undef-init': 'error', + 'no-regex-spaces': 'error', + 'no-proto': 'error', + 'no-new-wrappers': 'error', + 'no-unused-private-class-members': 'error', + 'no-invalid-regexp': 'error', + curly: ['error', 'all'], + '@typescript-eslint/restrict-template-expressions': 'error', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/adjacent-overload-signatures': 'error', + 'no-console': ['warn'], + '@typescript-eslint/explicit-member-accessibility': 'error', + '@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true }], + 'no-unused-vars': 'off', + 'no-duplicate-imports': 'off', + '@typescript-eslint/no-invalid-void-type': 'off', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-require-imports': 'error', + '@typescript-eslint/indent': 0, + '@typescript-eslint/member-delimiter-style': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-use-before-define': 0, + 'prefer-const': 1, + 'prefer-spread': 1, + '@typescript-eslint/naming-convention': [ 'error', { - allow: ['arrowFunctions', 'functions', 'methods'], + selector: 'interface', + format: ['PascalCase'], + custom: { + regex: '^I[A-Z]', + match: true, + }, }, ], - '@typescript-eslint/no-explicit-any': [ + 'import/no-unresolved': 'off', + 'import/no-extraneous-dependencies': 'off', + 'import/prefer-default-export': 'off', + 'no-underscore-dangle': 'off', + 'class-methods-use-this': 'off', + 'lines-between-class-members': 'off', + 'no-return-assign': 'off', + 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }], + 'no-param-reassign': 'error', + 'no-undefined': 'error', + '@typescript-eslint/no-unused-expressions': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/consistent-type-assertions': [ 'error', { - ignoreRestArgs: true, + assertionStyle: 'as', }, ], + 'no-plusplus': ['off'], + '@typescript-eslint/unbound-method': 'off', + 'import/no-cycle': 'off', + 'import/extensions': 'off', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/consistent-type-exports': 'error', }, }, { diff --git a/package.json b/package.json index 759ef289..3cde2316 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "18.0.0", + "version": "18.0.1", "description": "Awesome ngx mask", "license": "MIT", "engines": { @@ -34,7 +34,7 @@ "pack:lib": "cd dist/ngx-mask-lib && npm pack", "precommit-msg": "echo 'Please wait while we do our pre-commit checks...' && exit 0", "prettier": "prettier './src/**/*.ts' './projects/**/*.ts' --write", - "publish:lib": "cd dist/ngx-mask-lib && npm publish", + "publish:lib": "cd dist/ngx-mask-lib && bun publish", "release:major": "bun run version:major && bun run build:lib && bun run pack:lib && bun run publish:lib", "release:minor": "bun run version:minor && bun run build:lib && bun run pack:lib && bun run publish:lib", "release:patch": "bun run version:patch && bun run build:lib && bun run pack:lib && bun run publish:lib", @@ -60,68 +60,69 @@ "url": "https://github.com/JsDaddy/ngx-mask.git" }, "dependencies": { - "@angular/animations": "18.1.1", - "@angular/common": "18.1.1", - "@angular/compiler": "18.1.1", - "@angular/core": "18.1.1", - "@angular/forms": "18.1.1", - "@angular/platform-browser": "18.1.1", - "@angular/platform-browser-dynamic": "18.1.1", - "@angular/router": "18.1.1", - "@types/jest": "^29.5.12", - "@types/mocha": "^10.0.7", + "@angular/animations": "18.2.9", + "@angular/common": "18.2.9", + "@angular/compiler": "18.2.9", + "@angular/core": "18.2.9", + "@angular/forms": "18.2.9", + "@angular/platform-browser": "18.2.9", + "@angular/platform-browser-dynamic": "18.2.9", + "@angular/router": "18.2.9", + "@types/jest": "^29.5.14", + "@types/mocha": "^10.0.9", "ajv": "^8.17.1", - "cypress": "^13.13.1", + "cypress": "^13.15.1", "highlight.js": "11.10.0", "ngx-highlightjs": "12.0.0", "rxjs": "7.8.1", - "semantic-release": "24.0.0", + "semantic-release": "24.2.0", "semantic-release-export-data": "^1.1.0", - "snyk": "^1.1292.1" + "snyk": "^1.1294.0" }, "devDependencies": { - "@angular-devkit/build-angular": "18.1.1", - "@angular-eslint/builder": "18.1.0", - "@angular-eslint/eslint-plugin": "18.1.0", - "@angular-eslint/eslint-plugin-template": "18.1.0", - "@angular-eslint/schematics": "18.1.0", - "@angular-eslint/template-parser": "18.1.0", - "@angular/cli": "18.1.1", - "@angular/compiler-cli": "18.1.1", - "@angular/language-service": "18.1.1", - "@commitlint/cli": "19.3.0", - "@commitlint/config-conventional": "19.2.2", + "@angular-devkit/build-angular": "18.2.10", + "@angular-eslint/builder": "18.4.0", + "@angular-eslint/eslint-plugin": "18.4.0", + "@angular-eslint/eslint-plugin-template": "18.4.0", + "@angular-eslint/schematics": "18.4.0", + "@angular-eslint/template-parser": "18.4.0", + "@angular/cli": "18.2.10", + "@angular/compiler-cli": "18.2.9", + "@angular/language-service": "18.2.9", + "@commitlint/cli": "19.5.0", + "@commitlint/config-conventional": "19.5.0", "@jscutlery/cypress-angular": "^0.9.22", "@types/highlight.js": "9.12.4", "@types/jasmine": "5.1.4", - "@types/node": "20.14.12", - "@typescript-eslint/eslint-plugin": "7.17.0", - "@typescript-eslint/parser": "7.17.0", - "@web/test-runner": "^0.18.2", - "angular-cli-ghpages": "2.0.1", + "@types/node": "22.8.1", + "@typescript-eslint/eslint-plugin": "8.11.0", + "@typescript-eslint/parser": "8.11.0", + "@web/test-runner": "^0.19.0", + "angular-cli-ghpages": "2.0.3", "angular-http-server": "1.12.0", - "eslint": "9.7.0", + "eslint": "9.13.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-json": "4.0.0", + "eslint-plugin-json": "4.0.1", "eslint-plugin-prettier": "5.2.1", - "jasmine-core": "5.2.0", + "jasmine-core": "5.4.0", "jasmine-spec-reporter": "7.0.0", - "lint-staged": "15.2.7", - "markdownlint-cli": "0.41.0", - "ng-packagr": "18.1.0", - "npm-check-updates": "^16.14.20", + "lint-staged": "15.2.10", + "markdownlint-cli": "0.42.0", + "ng-packagr": "18.2.1", + "npm-check-updates": "^17.1.8", "postcss-scss": "4.0.9", "prettier": "3.3.3", - "puppeteer": "22.13.1", - "stylelint": "16.7.0", + "puppeteer": "23.6.0", + "stylelint": "16.10.0", "stylelint-config-prettier": "9.0.5", "stylelint-config-recommended-scss": "14.1.0", "stylelint-prettier": "5.0.2", - "type-coverage": "^2.29.1", + "type-coverage": "^2.29.7", "typescript": "5.5.4", - "angular-eslint": "^18.1.0", - "typescript-eslint": "^7.17.0", - "tailwindcss": "^3.4.14" + "angular-eslint": "^18.4.0", + "typescript-eslint": "^8.11.0", + "tailwindcss": "^3.4.14", + "bun-types": "^1.1.33" }, "typeCoverage": { "atLeast": 92, diff --git a/projects/ngx-mask-lib/package.json b/projects/ngx-mask-lib/package.json index 4f80a05a..e61e1c4a 100644 --- a/projects/ngx-mask-lib/package.json +++ b/projects/ngx-mask-lib/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "18.0.0", + "version": "18.0.1", "description": "awesome ngx mask", "keywords": [ "ng2-mask", diff --git a/projects/ngx-mask-lib/src/lib/custom-keyboard-event.ts b/projects/ngx-mask-lib/src/lib/custom-keyboard-event.ts index 7c46a7e5..4b8c7e9d 100644 --- a/projects/ngx-mask-lib/src/lib/custom-keyboard-event.ts +++ b/projects/ngx-mask-lib/src/lib/custom-keyboard-event.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ declare let global: any; const commonjsGlobal = @@ -14,6 +13,7 @@ const commonjsGlobal = (function () { if (!commonjsGlobal.KeyboardEvent) { + // eslint-disable-next-line @typescript-eslint/no-empty-function commonjsGlobal.KeyboardEvent = function (_eventType: any, _init: any) {}; } })(); diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts b/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts index b466292f..7daf3429 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts @@ -1,57 +1,58 @@ import { inject, Injectable } from '@angular/core'; -import { NGX_MASK_CONFIG, IConfig } from './ngx-mask.config'; +import type { NgxMaskConfig } from './ngx-mask.config'; +import { NGX_MASK_CONFIG } from './ngx-mask.config'; import { MaskExpression } from './ngx-mask-expression.enum'; @Injectable() export class NgxMaskApplierService { - protected _config = inject(NGX_MASK_CONFIG); + protected _config = inject(NGX_MASK_CONFIG); - public dropSpecialCharacters: IConfig['dropSpecialCharacters'] = + public dropSpecialCharacters: NgxMaskConfig['dropSpecialCharacters'] = this._config.dropSpecialCharacters; - public hiddenInput: IConfig['hiddenInput'] = this._config.hiddenInput; + public hiddenInput: NgxMaskConfig['hiddenInput'] = this._config.hiddenInput; - public showTemplate!: IConfig['showTemplate']; + public showTemplate!: NgxMaskConfig['showTemplate']; - public clearIfNotMatch: IConfig['clearIfNotMatch'] = this._config.clearIfNotMatch; + public clearIfNotMatch: NgxMaskConfig['clearIfNotMatch'] = this._config.clearIfNotMatch; - public specialCharacters: IConfig['specialCharacters'] = this._config.specialCharacters; + public specialCharacters: NgxMaskConfig['specialCharacters'] = this._config.specialCharacters; - public patterns: IConfig['patterns'] = this._config.patterns; + public patterns: NgxMaskConfig['patterns'] = this._config.patterns; - public prefix: IConfig['prefix'] = this._config.prefix; + public prefix: NgxMaskConfig['prefix'] = this._config.prefix; - public suffix: IConfig['suffix'] = this._config.suffix; + public suffix: NgxMaskConfig['suffix'] = this._config.suffix; - public thousandSeparator: IConfig['thousandSeparator'] = this._config.thousandSeparator; + public thousandSeparator: NgxMaskConfig['thousandSeparator'] = this._config.thousandSeparator; - public decimalMarker: IConfig['decimalMarker'] = this._config.decimalMarker; + public decimalMarker: NgxMaskConfig['decimalMarker'] = this._config.decimalMarker; - public customPattern!: IConfig['patterns']; + public customPattern!: NgxMaskConfig['patterns']; - public showMaskTyped: IConfig['showMaskTyped'] = this._config.showMaskTyped; + public showMaskTyped: NgxMaskConfig['showMaskTyped'] = this._config.showMaskTyped; - public placeHolderCharacter: IConfig['placeHolderCharacter'] = + public placeHolderCharacter: NgxMaskConfig['placeHolderCharacter'] = this._config.placeHolderCharacter; - public validation: IConfig['validation'] = this._config.validation; + public validation: NgxMaskConfig['validation'] = this._config.validation; - public separatorLimit: IConfig['separatorLimit'] = this._config.separatorLimit; + public separatorLimit: NgxMaskConfig['separatorLimit'] = this._config.separatorLimit; - public allowNegativeNumbers: IConfig['allowNegativeNumbers'] = + public allowNegativeNumbers: NgxMaskConfig['allowNegativeNumbers'] = this._config.allowNegativeNumbers; - public leadZeroDateTime: IConfig['leadZeroDateTime'] = this._config.leadZeroDateTime; + public leadZeroDateTime: NgxMaskConfig['leadZeroDateTime'] = this._config.leadZeroDateTime; - public leadZero: IConfig['leadZero'] = this._config.leadZero; + public leadZero: NgxMaskConfig['leadZero'] = this._config.leadZero; - public apm: IConfig['apm'] = this._config.apm; + public apm: NgxMaskConfig['apm'] = this._config.apm; - public inputTransformFn: IConfig['inputTransformFn'] = this._config.inputTransformFn; + public inputTransformFn: NgxMaskConfig['inputTransformFn'] = this._config.inputTransformFn; - public outputTransformFn: IConfig['outputTransformFn'] = this._config.outputTransformFn; + public outputTransformFn: NgxMaskConfig['outputTransformFn'] = this._config.outputTransformFn; - public keepCharacterPositions: IConfig['keepCharacterPositions'] = + public keepCharacterPositions: NgxMaskConfig['keepCharacterPositions'] = this._config.keepCharacterPositions; private _shift = new Set(); @@ -74,7 +75,7 @@ export class NgxMaskApplierService { public applyMaskWithPattern( inputValue: string, - maskAndPattern: [string, IConfig['patterns']] + maskAndPattern: [string, NgxMaskConfig['patterns']] ): string { const [mask, customPattern] = maskAndPattern; this.customPattern = customPattern; @@ -87,7 +88,7 @@ export class NgxMaskApplierService { position = 0, justPasted = false, backspaced = false, - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-empty-function cb: (...args: any[]) => any = () => {} ): string { if (!maskExpression || typeof inputValue !== 'string') { @@ -99,203 +100,223 @@ export class NgxMaskApplierService { let backspaceShift = false; let shift = 1; let stepBack = false; - if (inputValue.slice(0, this.prefix.length) === this.prefix) { - inputValue = inputValue.slice(this.prefix.length, inputValue.length); + let processedValue = inputValue; + let processedPosition = position; + + if (processedValue.slice(0, this.prefix.length) === this.prefix) { + processedValue = processedValue.slice(this.prefix.length, processedValue.length); } - if (!!this.suffix && inputValue?.length > 0) { - inputValue = this.checkAndRemoveSuffix(inputValue); + if (!!this.suffix && processedValue.length > 0) { + processedValue = this.checkAndRemoveSuffix(processedValue); } - if (inputValue === '(' && this.prefix) { - inputValue = ''; + if (processedValue === '(' && this.prefix) { + processedValue = ''; } - const inputArray: string[] = inputValue.toString().split(MaskExpression.EMPTY_STRING); + const inputArray: string[] = processedValue.toString().split(MaskExpression.EMPTY_STRING); if ( this.allowNegativeNumbers && - inputValue.slice(cursor, cursor + 1) === MaskExpression.MINUS + processedValue.slice(cursor, cursor + 1) === MaskExpression.MINUS ) { - result += inputValue.slice(cursor, cursor + 1); + result += processedValue.slice(cursor, cursor + 1); } if (maskExpression === MaskExpression.IP) { - const valuesIP = inputValue.split(MaskExpression.DOT); + const valuesIP = processedValue.split(MaskExpression.DOT); this.ipError = this._validIP(valuesIP); + // eslint-disable-next-line no-param-reassign maskExpression = '099.099.099.099'; } const arr: string[] = []; - for (let i = 0; i < inputValue.length; i++) { - if (inputValue[i]?.match('\\d')) { - arr.push(inputValue[i] ?? MaskExpression.EMPTY_STRING); + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < processedValue.length; i++) { + if (processedValue[i]?.match('\\d')) { + arr.push(processedValue[i] ?? MaskExpression.EMPTY_STRING); } } if (maskExpression === MaskExpression.CPF_CNPJ) { this.cpfCnpjError = arr.length !== 11 && arr.length !== 14; if (arr.length > 11) { + // eslint-disable-next-line no-param-reassign maskExpression = '00.000.000/0000-00'; } else { + // eslint-disable-next-line no-param-reassign maskExpression = '000.000.000-00'; } } if (maskExpression.startsWith(MaskExpression.PERCENT)) { if ( - inputValue.match('[a-z]|[A-Z]') || + processedValue.match('[a-z]|[A-Z]') || // eslint-disable-next-line no-useless-escape - (inputValue.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,\/.]/) && !backspaced) + (processedValue.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,\/.]/) && !backspaced) ) { - inputValue = this._stripToDecimal(inputValue); + processedValue = this._stripToDecimal(processedValue); const precision: number = this.getPrecision(maskExpression); - inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker); + processedValue = this.checkInputPrecision( + processedValue, + precision, + this.decimalMarker + ); } const decimalMarker = typeof this.decimalMarker === 'string' ? this.decimalMarker : MaskExpression.DOT; if ( - inputValue.indexOf(decimalMarker) > 0 && - !this.percentage(inputValue.substring(0, inputValue.indexOf(decimalMarker))) + processedValue.indexOf(decimalMarker) > 0 && + !this.percentage(processedValue.substring(0, processedValue.indexOf(decimalMarker))) ) { - let base: string = inputValue.substring(0, inputValue.indexOf(decimalMarker) - 1); + let base: string = processedValue.substring( + 0, + processedValue.indexOf(decimalMarker) - 1 + ); if ( this.allowNegativeNumbers && - inputValue.slice(cursor, cursor + 1) === MaskExpression.MINUS && + processedValue.slice(cursor, cursor + 1) === MaskExpression.MINUS && !backspaced ) { - base = inputValue.substring(0, inputValue.indexOf(decimalMarker)); + base = processedValue.substring(0, processedValue.indexOf(decimalMarker)); } - inputValue = `${base}${inputValue.substring( - inputValue.indexOf(decimalMarker), - inputValue.length + processedValue = `${base}${processedValue.substring( + processedValue.indexOf(decimalMarker), + processedValue.length )}`; } let value = ''; + // eslint-disable-next-line @typescript-eslint/no-unused-expressions this.allowNegativeNumbers && - inputValue.slice(cursor, cursor + 1) === MaskExpression.MINUS - ? (value = `${MaskExpression.MINUS}${inputValue.slice(cursor + 1, cursor + inputValue.length)}`) - : (value = inputValue); + processedValue.slice(cursor, cursor + 1) === MaskExpression.MINUS + ? (value = `${MaskExpression.MINUS}${processedValue.slice(cursor + 1, cursor + processedValue.length)}`) + : (value = processedValue); if (this.percentage(value)) { - result = this._splitPercentZero(inputValue); + result = this._splitPercentZero(processedValue); } else { - result = this._splitPercentZero(inputValue.substring(0, inputValue.length - 1)); + result = this._splitPercentZero( + processedValue.substring(0, processedValue.length - 1) + ); } } else if (maskExpression.startsWith(MaskExpression.SEPARATOR)) { if ( - inputValue.match('[wа-яА-Я]') || - inputValue.match('[ЁёА-я]') || - inputValue.match('[a-z]|[A-Z]') || - inputValue.match(/[-@#!$%\\^&*()_£¬'+|~=`{}\]:";<>.?/]/) || - inputValue.match('[^A-Za-z0-9,]') + processedValue.match('[wа-яА-Я]') || + processedValue.match('[ЁёА-я]') || + processedValue.match('[a-z]|[A-Z]') || + processedValue.match(/[-@#!$%\\^&*()_£¬'+|~=`{}\]:";<>.?/]/) || + processedValue.match('[^A-Za-z0-9,]') ) { - inputValue = this._stripToDecimal(inputValue); + processedValue = this._stripToDecimal(processedValue); } + const precision: number = this.getPrecision(maskExpression); const decimalMarker = Array.isArray(this.decimalMarker) ? MaskExpression.DOT : this.decimalMarker; + if (precision === 0) { - inputValue = this.allowNegativeNumbers - ? inputValue.length > 2 && - inputValue[0] === MaskExpression.MINUS && - inputValue[1] === MaskExpression.NUMBER_ZERO && - inputValue[2] !== this.thousandSeparator && - inputValue[2] !== MaskExpression.COMMA && - inputValue[2] !== MaskExpression.DOT - ? '-' + inputValue.slice(2, inputValue.length) - : inputValue[0] === MaskExpression.NUMBER_ZERO && - inputValue.length > 1 && - inputValue[1] !== this.thousandSeparator && - inputValue[1] !== MaskExpression.COMMA && - inputValue[1] !== MaskExpression.DOT - ? inputValue.slice(1, inputValue.length) - : inputValue - : inputValue.length > 1 && - inputValue[0] === MaskExpression.NUMBER_ZERO && - inputValue[1] !== this.thousandSeparator && - inputValue[1] !== MaskExpression.COMMA && - inputValue[1] !== MaskExpression.DOT - ? inputValue.slice(1, inputValue.length) - : inputValue; + processedValue = this.allowNegativeNumbers + ? processedValue.length > 2 && + processedValue[0] === MaskExpression.MINUS && + processedValue[1] === MaskExpression.NUMBER_ZERO && + processedValue[2] !== this.thousandSeparator && + processedValue[2] !== MaskExpression.COMMA && + processedValue[2] !== MaskExpression.DOT + ? '-' + processedValue.slice(2, processedValue.length) + : processedValue[0] === MaskExpression.NUMBER_ZERO && + processedValue.length > 1 && + processedValue[1] !== this.thousandSeparator && + processedValue[1] !== MaskExpression.COMMA && + processedValue[1] !== MaskExpression.DOT + ? processedValue.slice(1, processedValue.length) + : processedValue + : processedValue.length > 1 && + processedValue[0] === MaskExpression.NUMBER_ZERO && + processedValue[1] !== this.thousandSeparator && + processedValue[1] !== MaskExpression.COMMA && + processedValue[1] !== MaskExpression.DOT + ? processedValue.slice(1, processedValue.length) + : processedValue; } else { - if (inputValue[0] === decimalMarker && inputValue.length > 1) { - inputValue = - MaskExpression.NUMBER_ZERO + inputValue.slice(0, inputValue.length + 1); + if (processedValue[0] === decimalMarker && processedValue.length > 1) { + processedValue = + MaskExpression.NUMBER_ZERO + + processedValue.slice(0, processedValue.length + 1); this.plusOnePosition = true; } if ( - inputValue[0] === MaskExpression.NUMBER_ZERO && - inputValue[1] !== decimalMarker && - inputValue[1] !== this.thousandSeparator + processedValue[0] === MaskExpression.NUMBER_ZERO && + processedValue[1] !== decimalMarker && + processedValue[1] !== this.thousandSeparator ) { - inputValue = - inputValue.length > 1 - ? inputValue.slice(0, 1) + + processedValue = + processedValue.length > 1 + ? processedValue.slice(0, 1) + decimalMarker + - inputValue.slice(1, inputValue.length + 1) - : inputValue; + processedValue.slice(1, processedValue.length + 1) + : processedValue; this.plusOnePosition = true; } if ( this.allowNegativeNumbers && - inputValue[0] === MaskExpression.MINUS && - (inputValue[1] === decimalMarker || - inputValue[1] === MaskExpression.NUMBER_ZERO) + processedValue[0] === MaskExpression.MINUS && + (processedValue[1] === decimalMarker || + processedValue[1] === MaskExpression.NUMBER_ZERO) ) { - inputValue = - inputValue[1] === decimalMarker && inputValue.length > 2 - ? inputValue.slice(0, 1) + + processedValue = + processedValue[1] === decimalMarker && processedValue.length > 2 + ? processedValue.slice(0, 1) + MaskExpression.NUMBER_ZERO + - inputValue.slice(1, inputValue.length) - : inputValue[1] === MaskExpression.NUMBER_ZERO && - inputValue.length > 2 && - inputValue[2] !== decimalMarker - ? inputValue.slice(0, 2) + + processedValue.slice(1, processedValue.length) + : processedValue[1] === MaskExpression.NUMBER_ZERO && + processedValue.length > 2 && + processedValue[2] !== decimalMarker + ? processedValue.slice(0, 2) + decimalMarker + - inputValue.slice(2, inputValue.length) - : inputValue; + processedValue.slice(2, processedValue.length) + : processedValue; this.plusOnePosition = true; } } if (backspaced) { - const inputValueAfterZero = inputValue.slice( - this._findFirstNonZeroDigitIndex(inputValue), - inputValue.length + const inputValueAfterZero = processedValue.slice( + this._findFirstNonZeroDigitIndex(processedValue), + processedValue.length ); const positionOfZeroOrDecimalMarker = - inputValue[position] === MaskExpression.NUMBER_ZERO || - inputValue[position] === decimalMarker; - const zeroIndexNumberZero = inputValue[0] === MaskExpression.NUMBER_ZERO; - const zeroIndexMinus = inputValue[0] === MaskExpression.MINUS; - const zeroIndexThousand = inputValue[0] === this.thousandSeparator; - const firstIndexDecimalMarker = inputValue[1] === decimalMarker; - const firstIndexNumberZero = inputValue[1] === MaskExpression.NUMBER_ZERO; - const secondIndexDecimalMarker = inputValue[2] === decimalMarker; + processedValue[processedPosition] === MaskExpression.NUMBER_ZERO || + processedValue[processedPosition] === decimalMarker; + const zeroIndexNumberZero = processedValue[0] === MaskExpression.NUMBER_ZERO; + const zeroIndexMinus = processedValue[0] === MaskExpression.MINUS; + const zeroIndexThousand = processedValue[0] === this.thousandSeparator; + const firstIndexDecimalMarker = processedValue[1] === decimalMarker; + const firstIndexNumberZero = processedValue[1] === MaskExpression.NUMBER_ZERO; + const secondIndexDecimalMarker = processedValue[2] === decimalMarker; if ( zeroIndexNumberZero && firstIndexDecimalMarker && positionOfZeroOrDecimalMarker && - position < 2 + processedPosition < 2 ) { - inputValue = inputValueAfterZero; + processedValue = inputValueAfterZero; } if ( zeroIndexMinus && firstIndexNumberZero && secondIndexDecimalMarker && positionOfZeroOrDecimalMarker && - position < 3 + processedPosition < 3 ) { - inputValue = MaskExpression.MINUS + inputValueAfterZero; + processedValue = MaskExpression.MINUS + inputValueAfterZero; } if ( inputValueAfterZero !== MaskExpression.MINUS && - ((position === 0 && (zeroIndexNumberZero || zeroIndexThousand)) || + ((processedPosition === 0 && (zeroIndexNumberZero || zeroIndexThousand)) || (this.allowNegativeNumbers && - position === 1 && + processedPosition === 1 && zeroIndexMinus && !firstIndexNumberZero)) ) { - inputValue = zeroIndexMinus + processedValue = zeroIndexMinus ? MaskExpression.MINUS + inputValueAfterZero : inputValueAfterZero; } @@ -326,12 +347,16 @@ export class NgxMaskApplierService { } const invalidCharRegexp = new RegExp('[' + invalidChars + ']'); - if (inputValue.match(invalidCharRegexp)) { - inputValue = inputValue.substring(0, inputValue.length - 1); + if (processedValue.match(invalidCharRegexp)) { + processedValue = processedValue.substring(0, processedValue.length - 1); } - inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker); - const strForSep: string = inputValue.replace( + processedValue = this.checkInputPrecision( + processedValue, + precision, + this.decimalMarker + ); + const strForSep: string = processedValue.replace( new RegExp(thousandSeparatorCharEscaped, 'g'), '' ); @@ -344,44 +369,55 @@ export class NgxMaskApplierService { ); const commaShift: number = - result.indexOf(MaskExpression.COMMA) - inputValue.indexOf(MaskExpression.COMMA); - const shiftStep: number = result.length - inputValue.length; + result.indexOf(MaskExpression.COMMA) - processedValue.indexOf(MaskExpression.COMMA); + const shiftStep: number = result.length - processedValue.length; - if (result[position - 1] === this.thousandSeparator && this.prefix && backspaced) { - position = position - 1; - } else if (shiftStep > 0 && result[position] !== this.thousandSeparator) { + if ( + (result[processedPosition - 1] === this.thousandSeparator || + result[processedPosition - this.prefix.length]) && + this.prefix && + backspaced + ) { + processedPosition = processedPosition - 1; + } else if (shiftStep > 0 && result[processedPosition] !== this.thousandSeparator) { backspaceShift = true; let _shift = 0; do { - this._shift.add(position + _shift); + this._shift.add(processedPosition + _shift); _shift++; } while (_shift < shiftStep); } else if ( - result[position - 1] === this.decimalMarker || + result[processedPosition - 1] === this.decimalMarker || shiftStep === -4 || shiftStep === -3 || - result[position] === this.thousandSeparator + result[processedPosition] === this.thousandSeparator ) { this._shift.clear(); - this._shift.add(position - 1); + this._shift.add(processedPosition - 1); } else if ( (commaShift !== 0 && - position > 0 && - !(result.indexOf(MaskExpression.COMMA) >= position && position > 3)) || - (!(result.indexOf(MaskExpression.DOT) >= position && position > 3) && + processedPosition > 0 && + !( + result.indexOf(MaskExpression.COMMA) >= processedPosition && + processedPosition > 3 + )) || + (!( + result.indexOf(MaskExpression.DOT) >= processedPosition && processedPosition > 3 + ) && shiftStep <= 0) ) { this._shift.clear(); backspaceShift = true; shift = shiftStep; - position += shiftStep; - this._shift.add(position); + processedPosition += shiftStep; + this._shift.add(processedPosition); } else { this._shift.clear(); } } else { for ( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion let i = 0, inputSymbol: string = inputArray[0]!; i < inputArray.length; i++, inputSymbol = inputArray[i] ?? MaskExpression.EMPTY_STRING @@ -438,7 +474,9 @@ export class NgxMaskApplierService { ) { if (maskExpression[cursor] === MaskExpression.HOURS) { if (this.apm ? Number(inputSymbol) > 9 : Number(inputSymbol) > 2) { - position = !this.leadZeroDateTime ? position + 1 : position; + processedPosition = !this.leadZeroDateTime + ? processedPosition + 1 + : processedPosition; cursor += 1; this._shiftStep(maskExpression, cursor, inputArray.length); i--; @@ -453,9 +491,9 @@ export class NgxMaskApplierService { this.apm ? (result.length === 1 && Number(result) > 1) || (result === '1' && Number(inputSymbol) > 2) || - (inputValue.slice(cursor - 1, cursor).length === 1 && - Number(inputValue.slice(cursor - 1, cursor)) > 2) || - (inputValue.slice(cursor - 1, cursor) === '1' && + (processedValue.slice(cursor - 1, cursor).length === 1 && + Number(processedValue.slice(cursor - 1, cursor)) > 2) || + (processedValue.slice(cursor - 1, cursor) === '1' && Number(inputSymbol) > 2) : (result === '2' && Number(inputSymbol) > 3) || ((result.slice(cursor - 2, cursor) === '2' || @@ -465,7 +503,7 @@ export class NgxMaskApplierService { Number(inputSymbol) > 3 && cursor > 10) ) { - position = position + 1; + processedPosition = processedPosition + 1; cursor += 1; i--; continue; @@ -476,7 +514,9 @@ export class NgxMaskApplierService { maskExpression[cursor] === MaskExpression.SECOND ) { if (Number(inputSymbol) > 5) { - position = !this.leadZeroDateTime ? position + 1 : position; + processedPosition = !this.leadZeroDateTime + ? processedPosition + 1 + : processedPosition; cursor += 1; this._shiftStep(maskExpression, cursor, inputArray.length); i--; @@ -487,18 +527,21 @@ export class NgxMaskApplierService { } } const daysCount = 31; - const inputValueCursor = inputValue[cursor] as string; - const inputValueCursorPlusOne = inputValue[cursor + 1] as string; - const inputValueCursorPlusTwo = inputValue[cursor + 2] as string; - const inputValueCursorMinusOne = inputValue[cursor - 1] as string; - const inputValueCursorMinusTwo = inputValue[cursor - 2] as string; - const inputValueSliceMinusThreeMinusOne = inputValue.slice( + const inputValueCursor = processedValue[cursor] as string; + const inputValueCursorPlusOne = processedValue[cursor + 1] as string; + const inputValueCursorPlusTwo = processedValue[cursor + 2] as string; + const inputValueCursorMinusOne = processedValue[cursor - 1] as string; + const inputValueCursorMinusTwo = processedValue[cursor - 2] as string; + const inputValueSliceMinusThreeMinusOne = processedValue.slice( cursor - 3, cursor - 1 ); - const inputValueSliceMinusOnePlusOne = inputValue.slice(cursor - 1, cursor + 1); - const inputValueSliceCursorPlusTwo = inputValue.slice(cursor, cursor + 2); - const inputValueSliceMinusTwoCursor = inputValue.slice(cursor - 2, cursor); + const inputValueSliceMinusOnePlusOne = processedValue.slice( + cursor - 1, + cursor + 1 + ); + const inputValueSliceCursorPlusTwo = processedValue.slice(cursor, cursor + 2); + const inputValueSliceMinusTwoCursor = processedValue.slice(cursor - 2, cursor); if (maskExpression[cursor] === MaskExpression.DAY) { const maskStartWithMonth = maskExpression.slice(0, 2) === MaskExpression.MONTHS; @@ -517,12 +560,16 @@ export class NgxMaskApplierService { this.specialCharacters.includes(inputValueCursorPlusTwo)) || this.specialCharacters.includes(inputValueCursor) : Number(inputValueSliceCursorPlusTwo) > daysCount || - this.specialCharacters.includes(inputValueCursorPlusOne)) + (this.specialCharacters.includes(inputValueCursorPlusOne) && + !backspaced)) ) { - position = !this.leadZeroDateTime ? position + 1 : position; + processedPosition = !this.leadZeroDateTime + ? processedPosition + 1 + : processedPosition; cursor += 1; this._shiftStep(maskExpression, cursor, inputArray.length); i--; + if (this.leadZeroDateTime) { result += '0'; } @@ -589,7 +636,9 @@ export class NgxMaskApplierService { day2monthInput || (day2monthInputDot && !this.leadZeroDateTime) ) { - position = !this.leadZeroDateTime ? position + 1 : position; + processedPosition = !this.leadZeroDateTime + ? processedPosition + 1 + : processedPosition; cursor += 1; this._shiftStep(maskExpression, cursor, inputArray.length); i--; @@ -687,7 +736,7 @@ export class NgxMaskApplierService { ) { result += maskExpression[maskExpression.length - 1]; } - let newPosition: number = position + 1; + let newPosition: number = processedPosition + 1; while (this._shift.has(newPosition)) { shift++; @@ -697,7 +746,7 @@ export class NgxMaskApplierService { let actualShift: number = justPasted && !maskExpression.startsWith(MaskExpression.SEPARATOR) ? cursor - : this._shift.has(position) + : this._shift.has(processedPosition) ? shift : 0; if (stepBack) { @@ -722,12 +771,12 @@ export class NgxMaskApplierService { } const isSpecialCharacterMaskFirstSymbol = - inputValue.length === 1 && + processedValue.length === 1 && this.specialCharacters.includes(maskExpression[0] as string) && - inputValue !== maskExpression[0]; + processedValue !== maskExpression[0]; if ( - !this._checkSymbolMask(inputValue, maskExpression[1] as string) && + !this._checkSymbolMask(processedValue, maskExpression[1] as string) && isSpecialCharacterMaskFirstSymbol ) { return ''; @@ -802,7 +851,7 @@ export class NgxMaskApplierService { res = res.replace(rgx, '$1' + thousandSeparatorChar + '$2'); } - if (precision === undefined) { + if (typeof precision === 'undefined') { return res + decimals; } else if (precision === 0) { return res; @@ -848,37 +897,47 @@ export class NgxMaskApplierService { private checkInputPrecision = ( inputValue: string, precision: number, - decimalMarker: IConfig['decimalMarker'] + decimalMarker: NgxMaskConfig['decimalMarker'] ): string => { + let processedInputValue = inputValue; + let processedDecimalMarker = decimalMarker; + if (precision < Infinity) { // TODO need think about decimalMarker - if (Array.isArray(decimalMarker)) { - const marker = decimalMarker.find((dm) => dm !== this.thousandSeparator); + if (Array.isArray(processedDecimalMarker)) { + const marker = processedDecimalMarker.find((dm) => dm !== this.thousandSeparator); - decimalMarker = marker ? marker : decimalMarker[0]; + processedDecimalMarker = marker ? marker : processedDecimalMarker[0]; } const precisionRegEx = new RegExp( - this._charToRegExpExpression(decimalMarker) + `\\d{${precision}}.*$` + this._charToRegExpExpression(processedDecimalMarker) + `\\d{${precision}}.*$` ); - const precisionMatch: RegExpMatchArray | null = inputValue.match(precisionRegEx); + const precisionMatch: RegExpMatchArray | null = + processedInputValue.match(precisionRegEx); const precisionMatchLength: number = (precisionMatch && precisionMatch[0]?.length) ?? 0; if (precisionMatchLength - 1 > precision) { const diff = precisionMatchLength - 1 - precision; - inputValue = inputValue.substring(0, inputValue.length - diff); + processedInputValue = processedInputValue.substring( + 0, + processedInputValue.length - diff + ); } if ( precision === 0 && this._compareOrIncludes( - inputValue[inputValue.length - 1], - decimalMarker, + processedInputValue[processedInputValue.length - 1], + processedDecimalMarker, this.thousandSeparator ) ) { - inputValue = inputValue.substring(0, inputValue.length - 1); + processedInputValue = processedInputValue.substring( + 0, + processedInputValue.length - 1 + ); } } - return inputValue; + return processedInputValue; }; private _stripToDecimal(str: string): string { diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.config.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.config.ts index 5bf14e3f..1732356b 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.config.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.config.ts @@ -5,7 +5,7 @@ export type InputTransformFn = (value: unknown) => string | number; export type OutputTransformFn = (value: string | number | undefined | null) => unknown; -export interface IConfig { +export type NgxMaskConfig = { suffix: string; prefix: string; thousandSeparator: string; @@ -17,7 +17,7 @@ export interface IConfig { shownMaskExpression: string; specialCharacters: string[] | readonly string[]; dropSpecialCharacters: boolean | string[] | readonly string[]; - hiddenInput: boolean | undefined; + hiddenInput: boolean; validation: boolean; separatorLimit: string; apm: boolean; @@ -37,14 +37,14 @@ export interface IConfig { symbol?: string; } >; -} +}; -export type optionsConfig = Partial; -export const NGX_MASK_CONFIG = new InjectionToken('ngx-mask config'); -export const NEW_CONFIG = new InjectionToken('new ngx-mask config'); -export const INITIAL_CONFIG = new InjectionToken('initial ngx-mask config'); +export type NgxMaskOptions = Partial; +export const NGX_MASK_CONFIG = new InjectionToken('ngx-mask config'); +export const NEW_CONFIG = new InjectionToken('new ngx-mask config'); +export const INITIAL_CONFIG = new InjectionToken('initial ngx-mask config'); -export const initialConfig: IConfig = { +export const initialConfig: NgxMaskConfig = { suffix: '', prefix: '', thousandSeparator: ' ', @@ -54,12 +54,11 @@ export const initialConfig: IConfig = { showMaskTyped: false, placeHolderCharacter: '_', dropSpecialCharacters: true, - hiddenInput: undefined, + hiddenInput: false, shownMaskExpression: '', separatorLimit: '', allowNegativeNumbers: false, validation: true, - specialCharacters: ['-', '/', '(', ')', '.', ':', ' ', '+', ',', '@', '[', ']', '"', "'"], leadZeroDateTime: false, apm: false, diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts index 2c1c6fac..67071323 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts @@ -1,25 +1,17 @@ import { DOCUMENT } from '@angular/common'; -import { - Directive, - EventEmitter, - HostListener, - Input, - OnChanges, - Output, - SimpleChanges, - inject, -} from '@angular/core'; -import { +import type { OnChanges, SimpleChanges } from '@angular/core'; +import { Directive, EventEmitter, HostListener, Input, Output, inject } from '@angular/core'; +import type { ControlValueAccessor, FormControl, - NG_VALIDATORS, - NG_VALUE_ACCESSOR, ValidationErrors, Validator, } from '@angular/forms'; +import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { CustomKeyboardEvent } from './custom-keyboard-event'; -import { IConfig, NGX_MASK_CONFIG, timeMasks, withoutValidation } from './ngx-mask.config'; +import type { CustomKeyboardEvent } from './custom-keyboard-event'; +import type { NgxMaskConfig } from './ngx-mask.config'; +import { NGX_MASK_CONFIG, timeMasks, withoutValidation } from './ngx-mask.config'; import { NgxMaskService } from './ngx-mask.service'; import { MaskExpression } from './ngx-mask-expression.enum'; @@ -44,53 +36,53 @@ import { MaskExpression } from './ngx-mask-expression.enum'; export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Validator { @Input('mask') public maskExpression: string | undefined | null = ''; - @Input() public specialCharacters: IConfig['specialCharacters'] = []; + @Input() public specialCharacters: NgxMaskConfig['specialCharacters'] = []; - @Input() public patterns: IConfig['patterns'] = {}; + @Input() public patterns: NgxMaskConfig['patterns'] = {}; - @Input() public prefix: IConfig['prefix'] = ''; + @Input() public prefix: NgxMaskConfig['prefix'] = ''; - @Input() public suffix: IConfig['suffix'] = ''; + @Input() public suffix: NgxMaskConfig['suffix'] = ''; - @Input() public thousandSeparator: IConfig['thousandSeparator'] = ' '; + @Input() public thousandSeparator: NgxMaskConfig['thousandSeparator'] = ' '; - @Input() public decimalMarker: IConfig['decimalMarker'] = '.'; + @Input() public decimalMarker: NgxMaskConfig['decimalMarker'] = '.'; - @Input() public dropSpecialCharacters: IConfig['dropSpecialCharacters'] | null = null; + @Input() public dropSpecialCharacters: NgxMaskConfig['dropSpecialCharacters'] | null = null; - @Input() public hiddenInput: IConfig['hiddenInput'] | null = null; + @Input() public hiddenInput: NgxMaskConfig['hiddenInput'] | null = null; - @Input() public showMaskTyped: IConfig['showMaskTyped'] | null = null; + @Input() public showMaskTyped: NgxMaskConfig['showMaskTyped'] | null = null; - @Input() public placeHolderCharacter: IConfig['placeHolderCharacter'] | null = null; + @Input() public placeHolderCharacter: NgxMaskConfig['placeHolderCharacter'] | null = null; - @Input() public shownMaskExpression: IConfig['shownMaskExpression'] | null = null; + @Input() public shownMaskExpression: NgxMaskConfig['shownMaskExpression'] | null = null; - @Input() public showTemplate: IConfig['showTemplate'] | null = null; + @Input() public showTemplate: NgxMaskConfig['showTemplate'] | null = null; - @Input() public clearIfNotMatch: IConfig['clearIfNotMatch'] | null = null; + @Input() public clearIfNotMatch: NgxMaskConfig['clearIfNotMatch'] | null = null; - @Input() public validation: IConfig['validation'] | null = null; + @Input() public validation: NgxMaskConfig['validation'] | null = null; - @Input() public separatorLimit: IConfig['separatorLimit'] | null = null; + @Input() public separatorLimit: NgxMaskConfig['separatorLimit'] | null = null; - @Input() public allowNegativeNumbers: IConfig['allowNegativeNumbers'] | null = null; + @Input() public allowNegativeNumbers: NgxMaskConfig['allowNegativeNumbers'] | null = null; - @Input() public leadZeroDateTime: IConfig['leadZeroDateTime'] | null = null; + @Input() public leadZeroDateTime: NgxMaskConfig['leadZeroDateTime'] | null = null; - @Input() public leadZero: IConfig['leadZero'] | null = null; + @Input() public leadZero: NgxMaskConfig['leadZero'] | null = null; - @Input() public triggerOnMaskChange: IConfig['triggerOnMaskChange'] | null = null; + @Input() public triggerOnMaskChange: NgxMaskConfig['triggerOnMaskChange'] | null = null; - @Input() public apm: IConfig['apm'] | null = null; + @Input() public apm: NgxMaskConfig['apm'] | null = null; - @Input() public inputTransformFn: IConfig['inputTransformFn'] | null = null; + @Input() public inputTransformFn: NgxMaskConfig['inputTransformFn'] | null = null; - @Input() public outputTransformFn: IConfig['outputTransformFn'] | null = null; + @Input() public outputTransformFn: NgxMaskConfig['outputTransformFn'] | null = null; - @Input() public keepCharacterPositions: IConfig['keepCharacterPositions'] | null = null; + @Input() public keepCharacterPositions: NgxMaskConfig['keepCharacterPositions'] | null = null; - @Output() public maskFilled: IConfig['maskFilled'] = new EventEmitter(); + @Output() public maskFilled: NgxMaskConfig['maskFilled'] = new EventEmitter(); private _maskValue = ''; @@ -115,11 +107,12 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida public _maskService = inject(NgxMaskService, { self: true }); - protected _config = inject(NGX_MASK_CONFIG); + protected _config = inject(NGX_MASK_CONFIG); - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-empty-function public onChange = (_: any) => {}; + // eslint-disable-next-line @typescript-eslint/no-empty-function public onTouch = () => {}; public ngOnChanges(changes: SimpleChanges): void { @@ -264,14 +257,16 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida } public validate({ value }: FormControl): ValidationErrors | null { + const processedValue: string = typeof value === 'number' ? String(value) : value; + if (!this._maskService.validation || !this._maskValue) { return null; } if (this._maskService.ipError) { - return this._createValidationError(value); + return this._createValidationError(processedValue); } if (this._maskService.cpfCnpjError) { - return this._createValidationError(value); + return this._createValidationError(processedValue); } if (this._maskValue.startsWith(MaskExpression.SEPARATOR)) { return null; @@ -283,10 +278,10 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida return null; } if (timeMasks.includes(this._maskValue)) { - return this._validateTime(value); + return this._validateTime(processedValue); } - if (value && value.toString().length >= 1) { + if (processedValue && processedValue.length >= 1) { let counterOfOpt = 0; if ( @@ -298,9 +293,9 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida this._maskValue.indexOf(MaskExpression.CURLY_BRACKETS_RIGHT) ); - return lengthInsideCurlyBrackets === String(value.length) + return lengthInsideCurlyBrackets === String(processedValue.length) ? null - : this._createValidationError(value); + : this._createValidationError(processedValue); } if (this._maskValue.startsWith(MaskExpression.PERCENT)) { return null; @@ -318,7 +313,7 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida } if ( this._maskValue.indexOf(key) !== -1 && - value.toString().length >= this._maskValue.indexOf(key) + processedValue.length >= this._maskValue.indexOf(key) ) { return null; } @@ -329,19 +324,16 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida } if ( (this._maskValue.indexOf(MaskExpression.SYMBOL_STAR) > 1 && - value.toString().length < - this._maskValue.indexOf(MaskExpression.SYMBOL_STAR)) || + processedValue.length < this._maskValue.indexOf(MaskExpression.SYMBOL_STAR)) || (this._maskValue.indexOf(MaskExpression.SYMBOL_QUESTION) > 1 && - value.toString().length < - this._maskValue.indexOf(MaskExpression.SYMBOL_QUESTION)) + processedValue.length < this._maskValue.indexOf(MaskExpression.SYMBOL_QUESTION)) ) { - return this._createValidationError(value); + return this._createValidationError(processedValue); } if ( this._maskValue.indexOf(MaskExpression.SYMBOL_STAR) === -1 || this._maskValue.indexOf(MaskExpression.SYMBOL_QUESTION) === -1 ) { - value = typeof value === 'number' ? String(value) : value; const array = this._maskValue.split('*'); const length: number = this._maskService.dropSpecialCharacters ? this._maskValue.length - @@ -352,8 +344,8 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida : this._maskValue.length - counterOfOpt; if (array.length === 1) { - if (value.toString().length < length) { - return this._createValidationError(value); + if (processedValue.length < length) { + return this._createValidationError(processedValue); } } if (array.length > 1) { @@ -361,13 +353,13 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida if ( lastIndexArray && this._maskService.specialCharacters.includes(lastIndexArray[0] as string) && - String(value).includes(lastIndexArray[0] ?? '') && + String(processedValue).includes(lastIndexArray[0] ?? '') && !this.dropSpecialCharacters ) { const special = value.split(lastIndexArray[0]); return special[special.length - 1].length === lastIndexArray.length - 1 ? null - : this._createValidationError(value); + : this._createValidationError(processedValue); } else if ( ((lastIndexArray && !this._maskService.specialCharacters.includes( @@ -375,11 +367,11 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida )) || !lastIndexArray || this._maskService.dropSpecialCharacters) && - value.length >= length - 1 + processedValue.length >= length - 1 ) { return null; } else { - return this._createValidationError(value); + return this._createValidationError(processedValue); } } } @@ -410,7 +402,9 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida public onModelChange(value: string | undefined | null | number): void { // on form reset we need to update the actualValue if ( - (value === MaskExpression.EMPTY_STRING || value === null || value === undefined) && + (value === MaskExpression.EMPTY_STRING || + value === null || + typeof value === 'undefined') && this._maskService.actualValue ) { this._maskService.actualValue = this._maskService.getActualValue( @@ -422,7 +416,9 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida @HostListener('input', ['$event']) public onInput(e: CustomKeyboardEvent): void { // If IME is composing text, we wait for the composed text. - if (this._isComposing) return; + if (this._isComposing) { + return; + } const el: HTMLInputElement = e.target as HTMLInputElement; const transformedValue = this._maskService.inputTransformFn(el.value); if (el.type !== 'number') { @@ -654,6 +650,7 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida el.setSelectionRange(positionToApply, positionToApply); this._position = null; } else { + // eslint-disable-next-line no-console console.warn( 'Ngx-mask writeValue work with string | number, your current value:', typeof transformedValue @@ -733,7 +730,6 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida el.selectionStart !== null && el.selectionStart === el.selectionEnd && el.selectionStart > this._maskService.prefix.length && - // eslint-disable-next-line (e as any).keyCode !== 38 ) { if (this._maskService.showMaskTyped && !this.keepCharacterPositions) { @@ -792,7 +788,9 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida if (this._isComposing) { // User finalize their choice from IME composition, so trigger onInput() for the composed text. - if (e.key === 'Enter') this.onCompositionEnd(e); + if (e.key === 'Enter') { + this.onCompositionEnd(e); + } return; } @@ -894,31 +892,30 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida /** It writes the value in the input */ public async writeValue(controlValue: unknown): Promise { - if (typeof controlValue === 'object' && controlValue !== null && 'value' in controlValue) { - if ('disable' in controlValue) { - this.setDisabledState(Boolean(controlValue.disable)); + let value = controlValue; + if (typeof value === 'object' && value !== null && 'value' in value) { + if ('disable' in value) { + this.setDisabledState(Boolean(value.disable)); } - controlValue = controlValue.value; + value = value.value; } - if (controlValue !== null) { - controlValue = this.inputTransformFn - ? this.inputTransformFn(controlValue) - : controlValue; + if (value !== null) { + value = this.inputTransformFn ? this.inputTransformFn(value) : value; } if ( - typeof controlValue === 'string' || - typeof controlValue === 'number' || - controlValue === null || - controlValue === undefined + typeof value === 'string' || + typeof value === 'number' || + value === null || + typeof value === 'undefined' ) { - if (controlValue === null || controlValue === undefined || controlValue === '') { + if (value === null || typeof value === 'undefined' || value === '') { this._maskService._currentValue = ''; this._maskService._previousValue = ''; } - let inputValue: string | number | null | undefined = controlValue; + let inputValue: string | number | null | undefined = value; if ( typeof inputValue === 'number' || this._maskValue.startsWith(MaskExpression.SEPARATOR) @@ -979,26 +976,26 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida (this._maskService.prefix || this._maskService.showMaskTyped)) ) { // Let the service we know we are writing value so that triggering onChange function won't happen during applyMask - typeof this.inputTransformFn !== 'function' - ? (this._maskService.writingValue = true) - : ''; - + if (typeof this.inputTransformFn !== 'function') { + this._maskService.writingValue = true; + } this._maskService.formElementProperty = [ 'value', this._maskService.applyMask(inputValue, this._maskService.maskExpression), ]; // Let the service know we've finished writing value - typeof this.inputTransformFn !== 'function' - ? (this._maskService.writingValue = false) - : ''; + if (typeof this.inputTransformFn !== 'function') { + this._maskService.writingValue = false; + } } else { this._maskService.formElementProperty = ['value', inputValue]; } this._inputValue = inputValue; } else { + // eslint-disable-next-line no-console console.warn( 'Ngx-mask writeValue work with string | number, your current value:', - typeof controlValue + typeof value ); } } @@ -1036,7 +1033,6 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida this._maskService.formElementProperty = ['disabled', isDisabled]; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _applyMask(): any { this._maskService.maskExpression = this._maskService._repeatPatternSymbols( this._maskValue || '' diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.pipe.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.pipe.ts index 3f75e487..0e141dc5 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.pipe.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.pipe.ts @@ -1,6 +1,8 @@ -import { inject, Pipe, PipeTransform } from '@angular/core'; +import type { PipeTransform } from '@angular/core'; +import { inject, Pipe } from '@angular/core'; -import { IConfig, NGX_MASK_CONFIG } from './ngx-mask.config'; +import type { NgxMaskConfig } from './ngx-mask.config'; +import { NGX_MASK_CONFIG } from './ngx-mask.config'; import { NgxMaskService } from './ngx-mask.service'; import { MaskExpression } from './ngx-mask-expression.enum'; @@ -10,7 +12,7 @@ import { MaskExpression } from './ngx-mask-expression.enum'; standalone: true, }) export class NgxMaskPipe implements PipeTransform { - private readonly defaultOptions = inject(NGX_MASK_CONFIG); + private readonly defaultOptions = inject(NGX_MASK_CONFIG); private readonly _maskService = inject(NgxMaskService); @@ -21,8 +23,10 @@ export class NgxMaskPipe implements PipeTransform { public transform( value: string | number, mask: string, - { patterns, ...config }: Partial = {} as Partial + { patterns, ...config }: Partial = {} as Partial ): string { + let processedValue: string | number = value; + const currentConfig = { maskExpression: mask, ...this.defaultOptions, @@ -32,28 +36,32 @@ export class NgxMaskPipe implements PipeTransform { ...patterns, }, }; - Object.entries(currentConfig).forEach(([key, value]) => { - //eslint-disable-next-line @typescript-eslint/no-explicit-any - (this._maskService as any)[key] = value; + + Object.entries(currentConfig).forEach(([key, val]) => { + (this._maskService as any)[key] = val; }); + if (mask.includes('||')) { - if (mask.split('||').length > 1) { - this._maskExpressionArray = mask.split('||').sort((a: string, b: string) => { - return a.length - b.length; - }); - this._setMask(value as string); - return this._maskService.applyMask(`${value}`, this.mask); + const maskParts = mask.split('||'); + if (maskParts.length > 1) { + this._maskExpressionArray = maskParts.sort( + (a: string, b: string) => a.length - b.length + ); + this._setMask(processedValue as string); + return this._maskService.applyMask(`${processedValue}`, this.mask); } else { this._maskExpressionArray = []; - return this._maskService.applyMask(`${value}`, this.mask); + return this._maskService.applyMask(`${processedValue}`, this.mask); } } + if (mask.includes(MaskExpression.CURLY_BRACKETS_LEFT)) { return this._maskService.applyMask( - `${value}`, + `${processedValue}`, this._maskService._repeatPatternSymbols(mask) ); } + if (mask.startsWith(MaskExpression.SEPARATOR)) { if (config.decimalMarker) { this._maskService.decimalMarker = config.decimalMarker; @@ -65,30 +73,42 @@ export class NgxMaskPipe implements PipeTransform { this._maskService.leadZero = config.leadZero; } - value = String(value); + processedValue = String(processedValue); const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker(); + if (!Array.isArray(this._maskService.decimalMarker)) { - value = + processedValue = this._maskService.decimalMarker !== localeDecimalMarker - ? value.replace(localeDecimalMarker, this._maskService.decimalMarker) - : value; + ? (processedValue as string).replace( + localeDecimalMarker, + this._maskService.decimalMarker + ) + : processedValue; } + if ( this._maskService.leadZero && - value && + processedValue && this._maskService.dropSpecialCharacters !== false ) { - value = this._maskService._checkPrecision(mask, value as string); + processedValue = this._maskService._checkPrecision(mask, processedValue as string); } + if (this._maskService.decimalMarker === MaskExpression.COMMA) { - value = value.toString().replace(MaskExpression.DOT, MaskExpression.COMMA); + processedValue = (processedValue as string).replace( + MaskExpression.DOT, + MaskExpression.COMMA + ); } + this._maskService.isNumberValue = true; } - if (value === null || value === undefined) { + + if (processedValue === null || typeof processedValue === 'undefined') { return this._maskService.applyMask('', mask); } - return this._maskService.applyMask(`${value}`, mask); + + return this._maskService.applyMask(`${processedValue}`, mask); } private _setMask(value: string) { diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.providers.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.providers.ts index 8d7a5724..30f4c7d5 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.providers.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.providers.ts @@ -1,27 +1,23 @@ -import { EnvironmentProviders, inject, makeEnvironmentProviders, Provider } from '@angular/core'; +import type { EnvironmentProviders, Provider } from '@angular/core'; +import { inject, makeEnvironmentProviders } from '@angular/core'; -import { - NGX_MASK_CONFIG, - INITIAL_CONFIG, - initialConfig, - NEW_CONFIG, - optionsConfig, -} from './ngx-mask.config'; +import type { NgxMaskOptions } from './ngx-mask.config'; +import { NGX_MASK_CONFIG, INITIAL_CONFIG, initialConfig, NEW_CONFIG } from './ngx-mask.config'; import { NgxMaskService } from './ngx-mask.service'; /** * @internal */ -function _configFactory(): optionsConfig { - const initConfig = inject(INITIAL_CONFIG); - const configValue = inject optionsConfig)>(NEW_CONFIG); +function _configFactory(): NgxMaskOptions { + const initConfig = inject(INITIAL_CONFIG); + const configValue = inject NgxMaskOptions)>(NEW_CONFIG); return configValue instanceof Function ? { ...initConfig, ...configValue() } : { ...initConfig, ...configValue }; } -export function provideNgxMask(configValue?: optionsConfig | (() => optionsConfig)): Provider[] { +export function provideNgxMask(configValue?: NgxMaskOptions | (() => NgxMaskOptions)): Provider[] { return [ { provide: NEW_CONFIG, @@ -40,7 +36,7 @@ export function provideNgxMask(configValue?: optionsConfig | (() => optionsConfi } export function provideEnvironmentNgxMask( - configValue?: optionsConfig | (() => optionsConfig) + configValue?: NgxMaskOptions | (() => NgxMaskOptions) ): EnvironmentProviders { return makeEnvironmentProviders(provideNgxMask(configValue)); } diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts index 55fa078a..64f3090f 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts @@ -1,7 +1,8 @@ import { ElementRef, inject, Injectable, Renderer2 } from '@angular/core'; import { DOCUMENT } from '@angular/common'; -import { NGX_MASK_CONFIG, IConfig } from './ngx-mask.config'; +import type { NgxMaskConfig } from './ngx-mask.config'; +import { NGX_MASK_CONFIG } from './ngx-mask.config'; import { NgxMaskApplierService } from './ngx-mask-applier.service'; import { MaskExpression } from './ngx-mask-expression.enum'; @@ -36,14 +37,14 @@ export class NgxMaskService extends NgxMaskApplierService { private _end!: number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-empty-function public onChange = (_: any) => {}; public readonly _elementRef = inject(ElementRef, { optional: true }); private readonly document = inject(DOCUMENT); - protected override _config = inject(NGX_MASK_CONFIG); + protected override _config = inject(NGX_MASK_CONFIG); private readonly _renderer = inject(Renderer2, { optional: true }); @@ -53,7 +54,7 @@ export class NgxMaskService extends NgxMaskApplierService { position = 0, justPasted = false, backspaced = false, - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-empty-function cb: (...args: any[]) => any = () => {} ): string { if (!maskExpression) { @@ -78,17 +79,17 @@ export class NgxMaskService extends NgxMaskApplierService { ? (inputValue[this.selStart] ?? MaskExpression.EMPTY_STRING) : MaskExpression.EMPTY_STRING; let newInputValue = ''; - if (this.hiddenInput !== undefined && !this.writingValue) { + let newPosition = position; + if (this.hiddenInput && !this.writingValue) { let actualResult: string[] = inputValue && inputValue.length === 1 ? inputValue.split(MaskExpression.EMPTY_STRING) : this.actualValue.split(MaskExpression.EMPTY_STRING); - // eslint-disable @typescript-eslint/no-unused-expressions - if (typeof this.selStart === 'object' && typeof this.selEnd === 'object') { this.selStart = Number(this.selStart); this.selEnd = Number(this.selEnd); } else { + // eslint-disable-next-line no-unused-expressions,@typescript-eslint/no-unused-expressions inputValue !== MaskExpression.EMPTY_STRING && actualResult.length ? typeof this.selStart === 'number' && typeof this.selEnd === 'number' ? inputValue.length > actualResult.length @@ -103,12 +104,9 @@ export class NgxMaskService extends NgxMaskApplierService { : null : (actualResult = []); } - if (this.showMaskTyped) { - if (!this.hiddenInput) { - inputValue = this.removeMask(inputValue); - } + if (this.showMaskTyped && !this.hiddenInput) { + newInputValue = this.removeMask(inputValue); } - // eslint-enable @typescript-eslint/no-unused-expressions newInputValue = this.actualValue.length && actualResult.length <= inputValue.length ? this.shiftTypedSymbols(actualResult.join(MaskExpression.EMPTY_STRING)) @@ -120,18 +118,24 @@ export class NgxMaskService extends NgxMaskApplierService { if ( backspaced && this.specialCharacters.indexOf( - this.maskExpression[position] ?? MaskExpression.EMPTY_STRING + this.maskExpression[newPosition] ?? MaskExpression.EMPTY_STRING ) !== -1 && this.showMaskTyped && !this.prefix ) { newInputValue = this._currentValue; } - if (this.deletedSpecialCharacter && position) { - if (this.specialCharacters.includes(this.actualValue.slice(position, position + 1))) { - position = position + 1; - } else if (maskExpression.slice(position - 1, position + 1) !== MaskExpression.MONTHS) { - position = position - 2; + if (this.deletedSpecialCharacter && newPosition) { + if ( + this.specialCharacters.includes( + this.actualValue.slice(newPosition, newPosition + 1) + ) + ) { + newPosition = newPosition + 1; + } else if ( + maskExpression.slice(newPosition - 1, newPosition + 1) !== MaskExpression.MONTHS + ) { + newPosition = newPosition - 2; } this.deletedSpecialCharacter = false; @@ -141,7 +145,7 @@ export class NgxMaskService extends NgxMaskApplierService { this.placeHolderCharacter.length === 1 && !this.leadZeroDateTime ) { - inputValue = this.removeMask(inputValue); + newInputValue = this.removeMask(inputValue); } if (this.maskChanged) { @@ -170,7 +174,7 @@ export class NgxMaskService extends NgxMaskApplierService { const result: string = super.applyMask( newInputValue, maskExpression, - position, + newPosition, justPasted, backspaced, cb @@ -205,6 +209,7 @@ export class NgxMaskService extends NgxMaskApplierService { (this._previousValue === this._currentValue && justPasted); } + // eslint-disable-next-line no-unused-expressions,@typescript-eslint/no-unused-expressions this._emitValue ? this.writingValue && this.triggerOnMaskChange ? requestAnimationFrame(() => this.formControlResult(result)) @@ -250,7 +255,7 @@ export class NgxMaskService extends NgxMaskApplierService { position: number, justPasted: boolean, backspaced: boolean, - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-empty-function cb: (...args: any[]) => any = () => {} ): void { const formElement = this._elementRef?.nativeElement; @@ -426,6 +431,7 @@ export class NgxMaskService extends NgxMaskApplierService { return `${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}`; } const arr: string[] = []; + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < inputVal.length; i++) { const value = inputVal[i] ?? MaskExpression.EMPTY_STRING; if (!value) { @@ -467,6 +473,7 @@ export class NgxMaskService extends NgxMaskApplierService { return cpf; } const arr: string[] = []; + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < inputVal.length; i++) { const value = inputVal[i] ?? MaskExpression.EMPTY_STRING; if (!value) { @@ -524,6 +531,7 @@ export class NgxMaskService extends NgxMaskApplierService { */ private formControlResult(inputValue: string): void { if (this.writingValue || (!this.triggerOnMaskChange && this.maskChanged)) { + // eslint-disable-next-line no-unused-expressions,@typescript-eslint/no-unused-expressions this.triggerOnMaskChange && this.maskChanged ? this.onChange( this.outputTransformFn( @@ -652,28 +660,30 @@ export class NgxMaskService extends NgxMaskApplierService { } public _checkSymbols(result: string): string | number | undefined | null { - if (result === MaskExpression.EMPTY_STRING) { - return result; + let processedResult = result; + + if (processedResult === MaskExpression.EMPTY_STRING) { + return processedResult; } if ( this.maskExpression.startsWith(MaskExpression.PERCENT) && this.decimalMarker === MaskExpression.COMMA ) { - result = result.replace(MaskExpression.COMMA, MaskExpression.DOT); + processedResult = processedResult.replace(MaskExpression.COMMA, MaskExpression.DOT); } const separatorPrecision: number | null = this._retrieveSeparatorPrecision( this.maskExpression ); const separatorValue: string = this._replaceDecimalMarkerToDot( - this._retrieveSeparatorValue(result) + this._retrieveSeparatorValue(processedResult) ); if (!this.isNumberValue) { return separatorValue; } if (separatorPrecision) { - if (result === this.decimalMarker) { + if (processedResult === this.decimalMarker) { return null; } if (this.separatorLimit.length > 14) { @@ -711,18 +721,19 @@ export class NgxMaskService extends NgxMaskApplierService { public _checkPrecision(separatorExpression: string, separatorValue: string): number | string { const separatorPrecision = separatorExpression.slice(10, 11); + let value = separatorValue; if ( separatorExpression.indexOf('2') > 0 || (this.leadZero && Number(separatorPrecision) > 0) ) { if (this.decimalMarker === MaskExpression.COMMA && this.leadZero) { - separatorValue = separatorValue.replace(',', '.'); + value = value.replace(',', '.'); } return this.leadZero - ? Number(separatorValue).toFixed(Number(separatorPrecision)) - : Number(separatorValue).toFixed(2); + ? Number(value).toFixed(Number(separatorPrecision)) + : Number(value).toFixed(2); } - return this.numberToString(separatorValue); + return this.numberToString(value); } public _repeatPatternSymbols(maskExp: string): string { diff --git a/projects/ngx-mask-lib/src/test/add-prefix.spec.ts b/projects/ngx-mask-lib/src/test/add-prefix.spec.ts index e1e52029..5694b87d 100644 --- a/projects/ngx-mask-lib/src/test/add-prefix.spec.ts +++ b/projects/ngx-mask-lib/src/test/add-prefix.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/add-suffix.spec.ts b/projects/ngx-mask-lib/src/test/add-suffix.spec.ts index 059d4c37..420767c8 100644 --- a/projects/ngx-mask-lib/src/test/add-suffix.spec.ts +++ b/projects/ngx-mask-lib/src/test/add-suffix.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/allow-negative-numbers.spec.ts b/projects/ngx-mask-lib/src/test/allow-negative-numbers.spec.ts index 4d6e666f..2e105b52 100644 --- a/projects/ngx-mask-lib/src/test/allow-negative-numbers.spec.ts +++ b/projects/ngx-mask-lib/src/test/allow-negative-numbers.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts index 2e7526e6..b072e0af 100644 --- a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts +++ b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts @@ -1,5 +1,6 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { DebugElement } from '@angular/core'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; +import type { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; @@ -512,7 +513,7 @@ describe('Directive: Mask', () => { component.form.setValue('1111a'); equal('1111a', '1111', fixture); expect(component.form.value).toBe('1111'); - component.mask = undefined; + component.mask = null; expect(component.form.value).toBe('1111'); }); @@ -769,11 +770,11 @@ describe('Directive: Mask', () => { equal('123456-1234567891/1234', '123456-1234567891/1234', fixture); }); - it('setValue undefined should return undefined ', () => { + it('setValue undefined should return null', () => { component.mask = '0000'; equal('1234', '1234', fixture); - component.form.setValue(undefined); - expect(component.form.value).toBe(undefined); + component.form.setValue(null); + expect(component.form.value).toBe(null); }); it('after resetValue should show in model same value', () => { diff --git a/projects/ngx-mask-lib/src/test/clear-if-not-match-the-mask.spec.ts b/projects/ngx-mask-lib/src/test/clear-if-not-match-the-mask.spec.ts index 0cc3d635..bc318931 100644 --- a/projects/ngx-mask-lib/src/test/clear-if-not-match-the-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/clear-if-not-match-the-mask.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/complete-mask.spec.ts b/projects/ngx-mask-lib/src/test/complete-mask.spec.ts index 9b986861..89cae0a4 100644 --- a/projects/ngx-mask-lib/src/test/complete-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/complete-mask.spec.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; diff --git a/projects/ngx-mask-lib/src/test/copy-paste.spec.ts b/projects/ngx-mask-lib/src/test/copy-paste.spec.ts index 97272731..45dd458f 100644 --- a/projects/ngx-mask-lib/src/test/copy-paste.spec.ts +++ b/projects/ngx-mask-lib/src/test/copy-paste.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts b/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts index e08e3be0..305bf1bf 100644 --- a/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts +++ b/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts @@ -50,11 +50,20 @@ describe('Test Date Hh:m0', () => { }, imports: [CypressTestMaskModule], }); - cy.get('#masked').type('77').should('have.prop', 'selectionStart', 3); + cy.get('#masked') + .type('77') + .should('have.prop', 'selectionStart', 3) + .should('have.value', '7/7'); cy.get('#masked').clear(); - cy.get('#masked').type('777').should('have.prop', 'selectionStart', 4); + cy.get('#masked') + .type('777') + .should('have.prop', 'selectionStart', 5) + .should('have.value', '7/7/7'); cy.get('#masked').clear(); - cy.get('#masked').type('1177').should('have.prop', 'selectionStart', 6); + cy.get('#masked') + .type('1177') + .should('have.prop', 'selectionStart', 6) + .should('have.value', '11/7/7'); }); it('Mask M0/d0/0000 check cursor', () => { @@ -64,11 +73,20 @@ describe('Test Date Hh:m0', () => { }, imports: [CypressTestMaskModule], }); - cy.get('#masked').type('88').should('have.prop', 'selectionStart', 3); + cy.get('#masked') + .type('88') + .should('have.prop', 'selectionStart', 3) + .should('have.value', '8/8'); cy.get('#masked').clear(); - cy.get('#masked').type('777').should('have.prop', 'selectionStart', 4); + cy.get('#masked') + .type('777') + .should('have.prop', 'selectionStart', 5) + .should('have.value', '7/7/7'); cy.get('#masked').clear(); - cy.get('#masked').type('1177').should('have.prop', 'selectionStart', 6); + cy.get('#masked') + .type('1177') + .should('have.prop', 'selectionStart', 6) + .should('have.value', '11/7/7'); }); it('Mask 0000/M0/d0 check cursor', () => { @@ -328,7 +346,7 @@ describe('Test Date Hh:m0', () => { imports: [CypressTestMaskModule], }); - cy.get('#masked').type('111111111111').should('have.value', '+11111111111'); + cy.get('#masked').type('11111111111').should('have.value', '+11111111111'); cy.get('#masked') .type('{backspace}') .should('have.value', '(111) 111-1111') diff --git a/projects/ngx-mask-lib/src/test/custom-date.spec.ts b/projects/ngx-mask-lib/src/test/custom-date.spec.ts index 42b15cf5..0cbfe9e5 100644 --- a/projects/ngx-mask-lib/src/test/custom-date.spec.ts +++ b/projects/ngx-mask-lib/src/test/custom-date.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/custom-patterns.spec.ts b/projects/ngx-mask-lib/src/test/custom-patterns.spec.ts index e2d2c0f6..565b2336 100644 --- a/projects/ngx-mask-lib/src/test/custom-patterns.spec.ts +++ b/projects/ngx-mask-lib/src/test/custom-patterns.spec.ts @@ -1,11 +1,13 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal } from './utils/test-functions.component'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; -import { IConfig, initialConfig } from 'ngx-mask'; +import type { NgxMaskConfig } from 'ngx-mask'; +import { initialConfig } from 'ngx-mask'; describe('Directive: Mask (Custom patterns)', () => { let fixture: ComponentFixture; @@ -42,7 +44,7 @@ describe('Directive: Mask (Provide custom patterns)', () => { B: { pattern: new RegExp('[a-zA-Z]'), optional: true }, }; - const ngxMaskConfigValue: Partial = { + const ngxMaskConfigValue: Partial = { patterns: { ...initialConfig.patterns, ...ngxMaskCustomPatterns }, }; @@ -86,7 +88,7 @@ describe('Directive: Mask (Provide custom patterns with symbol *)', () => { '*': { pattern: new RegExp('[a-zA-Z0-9]') }, }; - const ngxMaskConfigValue: Partial = { + const ngxMaskConfigValue: Partial = { patterns: { ...initialConfig.patterns, ...ngxMaskCustomPatterns }, }; @@ -133,7 +135,7 @@ describe('Directive: Mask (Provide custom patterns with symbol f and F)', () => let fixture: ComponentFixture; let component: TestMaskComponent; - const ngxMaskConfig: IConfig = { + const ngxMaskConfig: NgxMaskConfig = { ...initialConfig, patterns: { f: { @@ -188,7 +190,7 @@ describe('Directive: Mask (Provide custom patterns with symbol B optional)', () B: { pattern: new RegExp('[0-9,;]'), optional: true }, }; - const ngxMaskConfigValue: Partial = { + const ngxMaskConfigValue: Partial = { patterns: { ...initialConfig.patterns, ...ngxMaskCustomPatterns }, }; diff --git a/projects/ngx-mask-lib/src/test/custom-symbol-regexp.spec.ts b/projects/ngx-mask-lib/src/test/custom-symbol-regexp.spec.ts index 0b8b6c5e..0ac1bb90 100644 --- a/projects/ngx-mask-lib/src/test/custom-symbol-regexp.spec.ts +++ b/projects/ngx-mask-lib/src/test/custom-symbol-regexp.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/default-config.spec.ts b/projects/ngx-mask-lib/src/test/default-config.spec.ts index 21ffe063..8806d780 100644 --- a/projects/ngx-mask-lib/src/test/default-config.spec.ts +++ b/projects/ngx-mask-lib/src/test/default-config.spec.ts @@ -1,12 +1,13 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule, FormControl } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { provideEnvironmentNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; -import { optionsConfig } from '../lib/ngx-mask.config'; +import type { NgxMaskOptions } from '../lib/ngx-mask.config'; function createComponentWithDefaultConfig( - defaultConfig?: optionsConfig + defaultConfig?: NgxMaskOptions ): ComponentFixture { TestBed.configureTestingModule({ declarations: [TestMaskComponent], diff --git a/projects/ngx-mask-lib/src/test/delete.cy-spec.ts b/projects/ngx-mask-lib/src/test/delete.cy-spec.ts index ecd7e960..c711933f 100644 --- a/projects/ngx-mask-lib/src/test/delete.cy-spec.ts +++ b/projects/ngx-mask-lib/src/test/delete.cy-spec.ts @@ -304,7 +304,7 @@ describe('Directive: Mask (Delete)', () => { .should('have.value', '$ 1,234,567,890') .type('{leftArrow}'.repeat(3)) .type('{backspace}') - .should('have.prop', 'selectionStart', 10); + .should('have.prop', 'selectionStart', 11); }); it('should backspace with separator and prefix', () => { @@ -322,7 +322,7 @@ describe('Directive: Mask (Delete)', () => { .should('have.value', '$ 1.234.567.890') .type('{leftArrow}'.repeat(3)) .type('{backspace}') - .should('have.prop', 'selectionStart', 10); + .should('have.prop', 'selectionStart', 11); }); it('should backspace with showMaskTyped and leadZeroDateTime', () => { @@ -338,7 +338,7 @@ describe('Directive: Mask (Delete)', () => { cy.get('#masked') .type('12310000') .should('have.value', '12-31-0000') - .type('{backspace}'.repeat(8)) + .type('{backspace}'.repeat(10)) .should('have.value', '__-__-____'); }); @@ -355,7 +355,7 @@ describe('Directive: Mask (Delete)', () => { cy.get('#masked') .type('12310000') .should('have.value', '12/31/0000') - .type('{backspace}'.repeat(8)) + .type('{backspace}'.repeat(10)) .should('have.value', '__/__/____'); }); @@ -372,7 +372,7 @@ describe('Directive: Mask (Delete)', () => { cy.get('#masked') .type('12310000') .should('have.value', '12:31:0000') - .type('{backspace}'.repeat(8)) + .type('{backspace}'.repeat(10)) .should('have.value', '__:__:____'); }); @@ -602,4 +602,37 @@ describe('Directive: Mask (Delete)', () => { .type('{backspace}') .should('have.value', '4'); }); + + it('should backspace with mask Hh:m0', () => { + cy.mount(CypressTestMaskComponent, { + componentProperties: { + mask: 'Hh:m0', + showMaskTyped: true, + }, + imports: [CypressTestMaskModule], + }); + + cy.get('#masked') + .type('1234') + .should('have.value', '12:34') + .type('{backspace}'.repeat(4)) + .should('have.value', '__:__'); + }); + + it('should backspace with mask Hh:m0 and leadZeroDateTime', () => { + cy.mount(CypressTestMaskComponent, { + componentProperties: { + mask: 'Hh:m0', + showMaskTyped: true, + leadZeroDateTime: true, + }, + imports: [CypressTestMaskModule], + }); + + cy.get('#masked') + .type('344') + .should('have.value', '03:44') + .type('{backspace}'.repeat(5)) + .should('have.value', '__:__'); + }); }); diff --git a/projects/ngx-mask-lib/src/test/delete.spec.ts b/projects/ngx-mask-lib/src/test/delete.spec.ts index 53dccc64..62b6ebaa 100644 --- a/projects/ngx-mask-lib/src/test/delete.spec.ts +++ b/projects/ngx-mask-lib/src/test/delete.spec.ts @@ -1,6 +1,7 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; @@ -163,7 +164,9 @@ describe('Directive: Mask (Delete)', () => { keyCode: 8, target: inputTarget, - preventDefault: () => {}, + preventDefault: () => { + void 0; + }, }); debugElement.triggerEventHandler('input', { target: inputTarget }); expect(inputTarget.selectionStart).toEqual(2); @@ -186,7 +189,9 @@ describe('Directive: Mask (Delete)', () => { keyCode: 8, target: inputTarget, - preventDefault: () => {}, + preventDefault: () => { + void 0; + }, }); debugElement.triggerEventHandler('input', { target: inputTarget }); expect(inputTarget.selectionStart).toEqual(3); @@ -209,7 +214,9 @@ describe('Directive: Mask (Delete)', () => { keyCode: 8, target: inputTarget, - preventDefault: () => {}, + preventDefault: () => { + void 0; + }, }); debugElement.triggerEventHandler('input', { target: inputTarget }); expect(inputTarget.selectionStart).toEqual(2); @@ -232,7 +239,9 @@ describe('Directive: Mask (Delete)', () => { keyCode: 8, target: inputTarget, - preventDefault: () => {}, + preventDefault: () => { + void 0; + }, }); debugElement.triggerEventHandler('input', { target: inputTarget }); expect(inputTarget.selectionStart).toEqual(3); diff --git a/projects/ngx-mask-lib/src/test/drop-special-charaters.spec.ts b/projects/ngx-mask-lib/src/test/drop-special-charaters.spec.ts index 1d32980b..0827887e 100644 --- a/projects/ngx-mask-lib/src/test/drop-special-charaters.spec.ts +++ b/projects/ngx-mask-lib/src/test/drop-special-charaters.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/dynamic.spec.ts b/projects/ngx-mask-lib/src/test/dynamic.spec.ts index 49b944b7..eb436594 100644 --- a/projects/ngx-mask-lib/src/test/dynamic.spec.ts +++ b/projects/ngx-mask-lib/src/test/dynamic.spec.ts @@ -1,9 +1,10 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; import { equal } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/export-as.spec.ts b/projects/ngx-mask-lib/src/test/export-as.spec.ts index c8882c47..09df4b99 100644 --- a/projects/ngx-mask-lib/src/test/export-as.spec.ts +++ b/projects/ngx-mask-lib/src/test/export-as.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { Component, ViewChild } from '@angular/core'; diff --git a/projects/ngx-mask-lib/src/test/inputTransformFn.spec.ts b/projects/ngx-mask-lib/src/test/inputTransformFn.spec.ts index 52a34bae..a8e5a35e 100644 --- a/projects/ngx-mask-lib/src/test/inputTransformFn.spec.ts +++ b/projects/ngx-mask-lib/src/test/inputTransformFn.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/mask.pipe.spec.ts b/projects/ngx-mask-lib/src/test/mask.pipe.spec.ts index a2e6cdf3..6cb7c216 100644 --- a/projects/ngx-mask-lib/src/test/mask.pipe.spec.ts +++ b/projects/ngx-mask-lib/src/test/mask.pipe.spec.ts @@ -1,7 +1,8 @@ import { TestBed } from '@angular/core/testing'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskPipe } from '../lib/ngx-mask.pipe'; -import { IConfig, NgxMaskDirective } from 'ngx-mask'; +import type { NgxMaskConfig } from 'ngx-mask'; +import { NgxMaskDirective } from 'ngx-mask'; describe('Pipe: Mask', () => { let maskPipe: NgxMaskPipe; @@ -33,7 +34,7 @@ describe('Pipe: Mask', () => { }); it('should custom pattern', () => { - const patterns: IConfig['patterns'] = { + const patterns: NgxMaskConfig['patterns'] = { P: { pattern: new RegExp('\\d'), }, @@ -171,7 +172,7 @@ describe('Pipe: Mask', () => { }); it('should work with custom pattern and hideInput', () => { - const SSN_PATTERNS: IConfig['patterns'] = { + const SSN_PATTERNS: NgxMaskConfig['patterns'] = { 0: { pattern: new RegExp('\\d') }, A: { pattern: new RegExp('\\d'), symbol: '●' }, }; diff --git a/projects/ngx-mask-lib/src/test/percent.spec.ts b/projects/ngx-mask-lib/src/test/percent.spec.ts index ffae64ae..46a8a688 100644 --- a/projects/ngx-mask-lib/src/test/percent.spec.ts +++ b/projects/ngx-mask-lib/src/test/percent.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/place-holder-character.spec.ts b/projects/ngx-mask-lib/src/test/place-holder-character.spec.ts index 5e16f54c..92f19ef3 100644 --- a/projects/ngx-mask-lib/src/test/place-holder-character.spec.ts +++ b/projects/ngx-mask-lib/src/test/place-holder-character.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts b/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts index b5672603..fd20bf1d 100644 --- a/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/secure-mask.spec.ts b/projects/ngx-mask-lib/src/test/secure-mask.spec.ts index 4cd3e2e3..a6e02619 100644 --- a/projects/ngx-mask-lib/src/test/secure-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/secure-mask.spec.ts @@ -1,11 +1,12 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal, typeTest } from './utils/test-functions.component'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; describe('Directive: Mask (Secure)', () => { diff --git a/projects/ngx-mask-lib/src/test/separator-non-en-locale.spec.ts b/projects/ngx-mask-lib/src/test/separator-non-en-locale.spec.ts index 1bbe3a43..75391381 100644 --- a/projects/ngx-mask-lib/src/test/separator-non-en-locale.spec.ts +++ b/projects/ngx-mask-lib/src/test/separator-non-en-locale.spec.ts @@ -1,5 +1,7 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { DebugElement, LOCALE_ID } from '@angular/core'; +import type { ComponentFixture } from '@angular/core/testing'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; +import type { DebugElement } from '@angular/core'; +import { LOCALE_ID } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal, typeTest } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/separator.spec.ts b/projects/ngx-mask-lib/src/test/separator.spec.ts index b0994ced..1e6df6a1 100644 --- a/projects/ngx-mask-lib/src/test/separator.spec.ts +++ b/projects/ngx-mask-lib/src/test/separator.spec.ts @@ -1,6 +1,7 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal, typeTest } from './utils/test-functions.component'; @@ -1724,7 +1725,6 @@ describe('Separator: Mask', () => { fixture.detectChanges(); inputElement.setSelectionRange(2, 2); - inputElement.selectionStart; expect(inputElement.selectionStart).toBe(2); const backspaceEvent = new KeyboardEvent('keydown', { @@ -1753,7 +1753,6 @@ describe('Separator: Mask', () => { fixture.detectChanges(); inputElement.setSelectionRange(2, 2); - inputElement.selectionStart; expect(inputElement.selectionStart).toBe(2); const backspaceEvent = new KeyboardEvent('keydown', { @@ -1782,7 +1781,6 @@ describe('Separator: Mask', () => { fixture.detectChanges(); inputElement.setSelectionRange(2, 2); - inputElement.selectionStart; expect(inputElement.selectionStart).toBe(2); const backspaceEvent = new KeyboardEvent('keydown', { diff --git a/projects/ngx-mask-lib/src/test/show-mask-typed.spec.ts b/projects/ngx-mask-lib/src/test/show-mask-typed.spec.ts index 1c765a69..28b9e2d8 100644 --- a/projects/ngx-mask-lib/src/test/show-mask-typed.spec.ts +++ b/projects/ngx-mask-lib/src/test/show-mask-typed.spec.ts @@ -1,11 +1,12 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { equal } from './utils/test-functions.component'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; describe('Directive: Mask', () => { diff --git a/projects/ngx-mask-lib/src/test/test-sufix.spec.ts b/projects/ngx-mask-lib/src/test/test-sufix.spec.ts index 5a89fe59..baec7b6e 100644 --- a/projects/ngx-mask-lib/src/test/test-sufix.spec.ts +++ b/projects/ngx-mask-lib/src/test/test-sufix.spec.ts @@ -1,5 +1,6 @@ -import { DebugElement } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { DebugElement } from '@angular/core'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/time-mask.spec.ts b/projects/ngx-mask-lib/src/test/time-mask.spec.ts index 42019a6b..5355a101 100644 --- a/projects/ngx-mask-lib/src/test/time-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/time-mask.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; diff --git a/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts b/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts index 70b34e6e..2d84f3ea 100644 --- a/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts +++ b/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts @@ -1,11 +1,12 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; import { TestMaskComponent } from './utils/test-component.component'; import { provideNgxMask } from '../lib/ngx-mask.providers'; import { NgxMaskDirective } from '../lib/ngx-mask.directive'; -import { DebugElement } from '@angular/core'; +import type { DebugElement } from '@angular/core'; import { equal } from './utils/test-functions.component'; describe('Directive: Mask (Trigger on mask change)', () => { diff --git a/projects/ngx-mask-lib/src/test/type-number.spec.ts b/projects/ngx-mask-lib/src/test/type-number.spec.ts index c2cd5041..b82144f1 100644 --- a/projects/ngx-mask-lib/src/test/type-number.spec.ts +++ b/projects/ngx-mask-lib/src/test/type-number.spec.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { NgxMaskDirective, provideNgxMask } from 'ngx-mask'; import { equal } from './utils/test-functions.component'; diff --git a/projects/ngx-mask-lib/src/test/utils/cypress-test-component.component.ts b/projects/ngx-mask-lib/src/test/utils/cypress-test-component.component.ts index eff3a7a5..c3b6f7d8 100644 --- a/projects/ngx-mask-lib/src/test/utils/cypress-test-component.component.ts +++ b/projects/ngx-mask-lib/src/test/utils/cypress-test-component.component.ts @@ -1,7 +1,8 @@ import { Component, inject, Input } from '@angular/core'; import { FormControl } from '@angular/forms'; import { scan, startWith } from 'rxjs'; -import { IConfig, NGX_MASK_CONFIG } from 'ngx-mask'; +import type { NgxMaskConfig } from 'ngx-mask'; +import { NGX_MASK_CONFIG } from 'ngx-mask'; @Component({ selector: 'jsdaddy-open-source-test', @@ -33,7 +34,7 @@ import { IConfig, NGX_MASK_CONFIG } from 'ngx-mask'; `, }) export class CypressTestMaskComponent { - protected _config = inject(NGX_MASK_CONFIG); + protected _config = inject(NGX_MASK_CONFIG); @Input() public mask = ''; @Input() public hiddenInput = false; @@ -71,6 +72,6 @@ export class CypressTestMaskComponent { public readonly counter$ = this.form.valueChanges.pipe( startWith(0), - scan((_, __, index) => ++index) + scan((acc) => acc + 1, 0) ); } diff --git a/projects/ngx-mask-lib/src/test/utils/cypress-test-trigger-on-mask-change.component.ts b/projects/ngx-mask-lib/src/test/utils/cypress-test-trigger-on-mask-change.component.ts index eaf79213..4215ac72 100644 --- a/projects/ngx-mask-lib/src/test/utils/cypress-test-trigger-on-mask-change.component.ts +++ b/projects/ngx-mask-lib/src/test/utils/cypress-test-trigger-on-mask-change.component.ts @@ -1,4 +1,5 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import type { OnDestroy, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; import { Subject, takeUntil } from 'rxjs'; diff --git a/projects/ngx-mask-lib/src/test/utils/test-component.component.ts b/projects/ngx-mask-lib/src/test/utils/test-component.component.ts index 9cdcacc8..194ec9e8 100644 --- a/projects/ngx-mask-lib/src/test/utils/test-component.component.ts +++ b/projects/ngx-mask-lib/src/test/utils/test-component.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectorRef, Component, inject } from '@angular/core'; import { FormControl } from '@angular/forms'; - -import { IConfig } from '../../lib/ngx-mask.config'; +import type { NgxMaskConfig } from 'ngx-mask'; @Component({ selector: 'jsdaddy-open-source-test', @@ -34,51 +33,51 @@ import { IConfig } from '../../lib/ngx-mask.config'; `, }) export class TestMaskComponent { - public mask!: string | undefined; + public mask!: string | null | undefined; public form: FormControl = new FormControl(); - public dropSpecialCharacters: IConfig['dropSpecialCharacters'] | undefined; + public dropSpecialCharacters: NgxMaskConfig['dropSpecialCharacters'] | undefined; - public clearIfNotMatch: IConfig['clearIfNotMatch'] | undefined; + public clearIfNotMatch: NgxMaskConfig['clearIfNotMatch'] | undefined; - public patterns: IConfig['patterns'] | undefined; + public patterns: NgxMaskConfig['patterns'] | undefined; - public prefix: IConfig['prefix'] = ''; + public prefix: NgxMaskConfig['prefix'] = ''; - public thousandSeparator: IConfig['thousandSeparator'] | undefined; + public thousandSeparator: NgxMaskConfig['thousandSeparator'] | undefined; - public decimalMarker: IConfig['decimalMarker'] | undefined; + public decimalMarker: NgxMaskConfig['decimalMarker'] | undefined; - public suffix: IConfig['suffix'] = ''; + public suffix: NgxMaskConfig['suffix'] = ''; - public specialCharacters: IConfig['specialCharacters'] | undefined; + public specialCharacters: NgxMaskConfig['specialCharacters'] | undefined; - public keepCharacterPositions: IConfig['keepCharacterPositions'] | undefined; + public keepCharacterPositions: NgxMaskConfig['keepCharacterPositions'] | undefined; - public showMaskTyped: IConfig['showMaskTyped'] | undefined; + public showMaskTyped: NgxMaskConfig['showMaskTyped'] | undefined; - public placeHolderCharacter: IConfig['placeHolderCharacter'] | undefined; + public placeHolderCharacter: NgxMaskConfig['placeHolderCharacter'] | undefined; - public hiddenInput: IConfig['hiddenInput'] | undefined; + public hiddenInput: NgxMaskConfig['hiddenInput'] | undefined; - public separatorLimit: IConfig['separatorLimit'] = ''; + public separatorLimit: NgxMaskConfig['separatorLimit'] = ''; - public allowNegativeNumbers: IConfig['allowNegativeNumbers'] | undefined; + public allowNegativeNumbers: NgxMaskConfig['allowNegativeNumbers'] | undefined; - public leadZeroDateTime: IConfig['leadZeroDateTime'] | undefined; + public leadZeroDateTime: NgxMaskConfig['leadZeroDateTime'] | undefined; - public leadZero: IConfig['leadZero'] | undefined; + public leadZero: NgxMaskConfig['leadZero'] | undefined; - public triggerOnMaskChange: IConfig['triggerOnMaskChange'] | undefined; + public triggerOnMaskChange: NgxMaskConfig['triggerOnMaskChange'] | undefined; - public validation: IConfig['validation'] | undefined; + public validation: NgxMaskConfig['validation'] | undefined; - public apm: IConfig['apm'] | undefined; + public apm: NgxMaskConfig['apm'] | undefined; - public inputTransformFn: IConfig['inputTransformFn'] | undefined; + public inputTransformFn: NgxMaskConfig['inputTransformFn'] | undefined; - public outputTransformFn: IConfig['outputTransformFn'] | undefined; + public outputTransformFn: NgxMaskConfig['outputTransformFn'] | undefined; public cdr = inject(ChangeDetectorRef); } diff --git a/projects/ngx-mask-lib/src/test/utils/test-functions.component.ts b/projects/ngx-mask-lib/src/test/utils/test-functions.component.ts index 1bc088c7..c55bb246 100644 --- a/projects/ngx-mask-lib/src/test/utils/test-functions.component.ts +++ b/projects/ngx-mask-lib/src/test/utils/test-functions.component.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any export function typeTest(inputValue: string, fixture: any): string { fixture.detectChanges(); @@ -10,7 +9,6 @@ export function typeTest(inputValue: string, fixture: any): string { return fixture.nativeElement.querySelector('input').value; } -// eslint-disable-next-line @typescript-eslint/no-explicit-any export function equal(value: string, expectedValue: string, fixture: any, async = false): void { typeTest(value, fixture); diff --git a/projects/ngx-mask-lib/src/test/validation.spec.ts b/projects/ngx-mask-lib/src/test/validation.spec.ts index 1fea7a8f..cc65a35e 100644 --- a/projects/ngx-mask-lib/src/test/validation.spec.ts +++ b/projects/ngx-mask-lib/src/test/validation.spec.ts @@ -1,4 +1,5 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { ComponentFixture } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { Component } from '@angular/core'; import { ReactiveFormsModule, FormControl, Validators } from '@angular/forms'; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5c3ec560..12c7f28e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -6,12 +6,7 @@ import { ComDocs, ComExamples } from 'src/assets/content/common-cases'; import { OthDocs, OthExamples } from 'src/assets/content/other'; import { OptionsComponent } from './options/options.component'; import { HeaderComponent } from '@open-source/header/header.component'; -import { - IComDoc, - IListItem, - IMaskOptions, - TExample, -} from '@open-source/accordion/content.interfaces'; +import type { ComDoc, ListItem, MaskOptions, TExample } from '@open-source/accordion/content.types'; import { SubHeaderComponent } from '@open-source/sub-header/sub-header.component'; import { AccordionComponent } from '@open-source/accordion/accordion.component'; import { FooterComponent } from '@open-source/footer/footer.component'; @@ -39,10 +34,10 @@ declare const VERSION: string; providers: [{ provide: VersionToken, useValue: VERSION }], }) export class AppComponent { - public docs = signal(ComDocs); - public examples = signal<(TExample | { _pipe: string })[]>(ComExamples); + public docs = signal(ComDocs); + public examples = signal<(TExample | { _pipe: string })[]>(ComExamples); - public readonly lists: IListItem[] = lists; + public readonly lists: ListItem[] = lists; public readonly githubMaskLink = LinkPath.NGX_MASK; public readonly title = 'Ngx-Mask'; public readonly subtitle = 'Angular plugin to make masks on form fields and html elements'; diff --git a/src/app/options/options.component.html b/src/app/options/options.component.html index efeaf2a0..f656d1c5 100644 --- a/src/app/options/options.component.html +++ b/src/app/options/options.component.html @@ -25,7 +25,7 @@ >
-                        
+                        
                         Input vector
                     
diff --git a/src/app/options/options.component.ts b/src/app/options/options.component.ts index efb90475..16d8b5b8 100644 --- a/src/app/options/options.component.ts +++ b/src/app/options/options.component.ts @@ -3,7 +3,6 @@ import { JsonPipe, NgOptimizedImage, NgTemplateOutlet } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { initialConfig, NgxMaskDirective, NgxMaskPipe } from 'ngx-mask'; import { HighlightModule } from 'ngx-highlightjs'; -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; import { AssetPipe } from '@libraries/asset/asset.pipe'; import { IsEmptyPipe } from '@open-source/is-empty/is-empty.pipe'; import { ColorPipe } from '@open-source/color/color.pipe'; @@ -12,6 +11,7 @@ import { ScrollService } from '@open-source/scroll/scroll.service'; import { AccordionService } from '@open-source/accordion/accordion.service'; import { OpenSourcePath } from '@open-source/path/open-source.path'; import { toSignal } from '@angular/core/rxjs-interop'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; @Component({ selector: 'jsdaddy-open-source-options', @@ -35,8 +35,8 @@ import { toSignal } from '@angular/core/rxjs-interop'; ], }) export class OptionsComponent { - public cardDocs = input(); - public cardExamples = input<(TExample | { _pipe: string })[]>(); + public cardDocs = input(); + public cardExamples = input<(TExample | { _pipe: string })[]>(); public cards = viewChildren>('cards', { read: ElementRef, diff --git a/src/assets/content/common-cases.ts b/src/assets/content/common-cases.ts index 35944de0..70d807f5 100644 --- a/src/assets/content/common-cases.ts +++ b/src/assets/content/common-cases.ts @@ -1,7 +1,7 @@ import { UntypedFormControl } from '@angular/forms'; -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; -export const ComDocs: IComDoc[] = [ +export const ComDocs: ComDoc[] = [ { header: 'Date', text: '', @@ -100,7 +100,7 @@ export const ComDocs: IComDoc[] = [ }, ]; -export const ComExamples: TExample[] = [ +export const ComExamples: TExample[] = [ { _placeholder: 'Date', _mask: 'd0/M0/0000', diff --git a/src/assets/content/lists.ts b/src/assets/content/lists.ts index ebd643f6..88f0ebc7 100644 --- a/src/assets/content/lists.ts +++ b/src/assets/content/lists.ts @@ -1,6 +1,6 @@ -import { IListItem } from '@open-source/accordion/content.interfaces'; +import type { ListItem } from '@open-source/accordion/content.types'; -export const lists: IListItem[] = [ +export const lists: ListItem[] = [ { header: 'Common cases', id: 1, diff --git a/src/assets/content/optional.ts b/src/assets/content/optional.ts index 529fcc46..8f7255ce 100644 --- a/src/assets/content/optional.ts +++ b/src/assets/content/optional.ts @@ -1,7 +1,7 @@ import { UntypedFormControl } from '@angular/forms'; -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; -export const OptDocs: IComDoc[] = [ +export const OptDocs: ComDoc[] = [ { header: 'Prefix (string)', text: 'You can add prefix to you masked value', @@ -81,7 +81,7 @@ export const OptDocs: IComDoc[] = [ }, ]; -export const OptExamples: TExample[] = [ +export const OptExamples: TExample[] = [ { _placeholder: 'prefix', _prefix: '+7', diff --git a/src/assets/content/other.ts b/src/assets/content/other.ts index 772d0bb9..54176dda 100644 --- a/src/assets/content/other.ts +++ b/src/assets/content/other.ts @@ -1,7 +1,7 @@ import { UntypedFormControl } from '@angular/forms'; -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; -export const OthDocs: IComDoc[] = [ +export const OthDocs: ComDoc[] = [ { header: 'Secure input', text: 'You can hide symbols in input field and get the actual value in formcontrol', @@ -42,7 +42,7 @@ export const OthDocs: IComDoc[] = [ }, ]; -export const OthExamples: (TExample | { _pipe: string })[] = [ +export const OthExamples: (TExample | { _pipe: string })[] = [ { _placeholder: 'Secure input', _hiddenInput: true, diff --git a/src/assets/content/parser-and-formatter.ts b/src/assets/content/parser-and-formatter.ts index 97a687ac..b9f29108 100644 --- a/src/assets/content/parser-and-formatter.ts +++ b/src/assets/content/parser-and-formatter.ts @@ -1,7 +1,7 @@ -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; import { UntypedFormControl } from '@angular/forms'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; -export const ParserAndFormatterDocs: IComDoc[] = [ +export const ParserAndFormatterDocs: ComDoc[] = [ { header: 'toUpperCase', text: 'You can hide symbols in input field and get the actual value in formcontrol', @@ -99,7 +99,7 @@ export const ParserAndFormatterDocs: IComDoc[] = [ }, ]; -export const FormatAndParserExamples: TExample[] = [ +export const FormatAndParserExamples: TExample[] = [ { _placeholder: 'S*', _mask: 'S*', diff --git a/src/assets/content/separators.ts b/src/assets/content/separators.ts index 1ce75f60..6faf570e 100644 --- a/src/assets/content/separators.ts +++ b/src/assets/content/separators.ts @@ -1,7 +1,7 @@ import { UntypedFormControl } from '@angular/forms'; -import { IComDoc, IMaskOptions, TExample } from '@open-source/accordion/content.interfaces'; +import type { ComDoc, MaskOptions, TExample } from '@open-source/accordion/content.types'; -export const SepDocs: IComDoc[] = [ +export const SepDocs: ComDoc[] = [ { header: 'Thousand separator', text: 'You can divide your input by thousands', @@ -39,7 +39,7 @@ export const SepDocs: IComDoc[] = [ }, ]; -export const SepExamples: TExample[] = [ +export const SepExamples: TExample[] = [ { _placeholder: 'Separator', _mask: 'separator', diff --git a/src/libraries b/src/libraries index 732a29a7..339053d4 160000 --- a/src/libraries +++ b/src/libraries @@ -1 +1 @@ -Subproject commit 732a29a701b8b29990f1d6c7cb5c9add02206940 +Subproject commit 339053d4cd781ffede25ca6049defbedd69c67b5 diff --git a/src/main.ts b/src/main.ts index 678e5a89..010e7965 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,11 @@ import { provideHttpClient } from '@angular/common/http'; import { BaseHttpService } from '@libraries/base-http/base-http.service'; import { DOMAIN } from '@libraries/token/token'; import { GithubStarsService } from '@libraries/github/github-stars.service'; +import { provideExperimentalZonelessChangeDetection } from '@angular/core'; bootstrapApplication(AppComponent, { providers: [ + provideExperimentalZonelessChangeDetection(), GithubStarsService, provideHttpClient(), { @@ -28,4 +30,5 @@ bootstrapApplication(AppComponent, { }, }, ], + // eslint-disable-next-line no-console }).catch((err) => console.error(err)); diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 00000000..05fc0437 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*.ts"] +} diff --git a/tsconfig.json b/tsconfig.json index 2cffed9f..7ab3eef1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,7 +28,8 @@ "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "useDefineForClassFields": false, - "skipLibCheck": true + "skipLibCheck": true, + "noImplicitAny": true }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false,