From 0bf5c93064885ed394f526d14ad23c3f8beb9e8e Mon Sep 17 00:00:00 2001
From: Andrii Kamaldinov <129040945+andriikamaldinov1@users.noreply.github.com>
Date: Tue, 5 Nov 2024 18:25:59 +0200
Subject: [PATCH] fix(ref: no-ref): fix issues (#1447)
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
* fix(ref: no-ref): fix issues
---
.github/workflows/publish.yml | 4 +-
.github/workflows/quality-check.yml | 2 +-
CHANGELOG.md | 10 +
package.json | 2 +-
projects/ngx-mask-lib/package.json | 2 +-
.../src/lib/ngx-mask-expression.enum.ts | 1 +
.../src/lib/ngx-mask.directive.ts | 18 +-
.../ngx-mask-lib/src/lib/ngx-mask.service.ts | 12 +-
.../ngx-mask-lib/src/test/basic-logic.spec.ts | 52 ++
.../ngx-mask-lib/src/test/cursor.cy-spec.ts | 193 --------
.../ngx-mask-lib/src/test/delete.cy-spec.ts | 263 ----------
.../test/keep-character-position.cy-spec.ts | 43 ++
.../src/test/separator.cy-spec.ts | 460 ++++++++++++++++++
.../ngx-mask-lib/src/test/separator.spec.ts | 38 ++
.../ngx-mask-lib/src/test/validation.spec.ts | 59 +++
src/assets/content/common-cases.ts | 17 +
16 files changed, 712 insertions(+), 464 deletions(-)
create mode 100644 projects/ngx-mask-lib/src/test/separator.cy-spec.ts
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 0add2295..6a223369 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -8,6 +8,8 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.get_version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
@@ -34,7 +36,7 @@ jobs:
id: get_version
run: |
VERSION=$(node -p "require('./dist/ngx-mask-lib/package.json').version")
- echo "version=$VERSION" >> $GITHUB_OUTPUT
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
slack_notification:
needs:
diff --git a/.github/workflows/quality-check.yml b/.github/workflows/quality-check.yml
index 97b5d7bc..f423ddfe 100644
--- a/.github/workflows/quality-check.yml
+++ b/.github/workflows/quality-check.yml
@@ -21,4 +21,4 @@ jobs:
- name: Check quality
run: |
bun i
- bash .github/workflows/scripts/quality.sh
\ No newline at end of file
+ bash .github/workflows/scripts/quality.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6667c655..0a18fc93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+# 18.0.3(2024-11-05)
+
+### Fix
+
+- Fix ([#1372](https://github.com/JsDaddy/ngx-mask/issues/1372))
+- Fix ([#1441](https://github.com/JsDaddy/ngx-mask/issues/1441))
+- Fix ([#1442](https://github.com/JsDaddy/ngx-mask/issues/1442))
+- Fix ([#1440](https://github.com/JsDaddy/ngx-mask/issues/1440))
+- Fix ([#1409](https://github.com/JsDaddy/ngx-mask/issues/1409))
+
# 18.0.2(2024-11-01)
### Fix
diff --git a/package.json b/package.json
index 6b9529d7..8a20bd64 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ngx-mask",
- "version": "18.0.2",
+ "version": "18.0.3",
"description": "Awesome ngx mask",
"license": "MIT",
"engines": {
diff --git a/projects/ngx-mask-lib/package.json b/projects/ngx-mask-lib/package.json
index a018296e..fcdab315 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.2",
+ "version": "18.0.3",
"description": "awesome ngx mask",
"keywords": [
"ng2-mask",
diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask-expression.enum.ts b/projects/ngx-mask-lib/src/lib/ngx-mask-expression.enum.ts
index c9c2916b..3aadf5ab 100644
--- a/projects/ngx-mask-lib/src/lib/ngx-mask-expression.enum.ts
+++ b/projects/ngx-mask-lib/src/lib/ngx-mask-expression.enum.ts
@@ -12,6 +12,7 @@ export const enum MaskExpression {
HOURS_HOUR = 'Hh',
SECONDS = 's0',
HOURS_MINUTES_SECONDS = 'Hh:m0:s0',
+ EMAIL_MASK = 'A*@A*.A*',
HOURS_MINUTES = 'Hh:m0',
MINUTES_SECONDS = 'm0:s0',
DAYS_MONTHS_YEARS = 'd0/M0/0000',
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 4c8b77ac..4ab0e2a0 100644
--- a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts
+++ b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts
@@ -280,7 +280,15 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
if (timeMasks.includes(this._maskValue)) {
return this._validateTime(processedValue);
}
+ if (this._maskValue === MaskExpression.EMAIL_MASK) {
+ const emailPattern = /^[^@]+@[^@]+\.[^@]+$/;
+ if (!emailPattern.test(processedValue) && processedValue) {
+ return this._createValidationError(processedValue);
+ } else {
+ return null;
+ }
+ }
if (processedValue && processedValue.length >= 1) {
let counterOfOpt = 0;
@@ -461,7 +469,11 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
const selStart = Number(this._maskService.selStart) - prefixLength;
const selEnd = Number(this._maskService.selEnd) - prefixLength;
- if (this._code === MaskExpression.BACKSPACE) {
+ const backspaceOrDelete =
+ this._code === MaskExpression.BACKSPACE ||
+ this._code === MaskExpression.DELETE;
+
+ if (backspaceOrDelete) {
if (!selectRangeBackspace) {
if (this._maskService.selStart === prefixLength) {
this._maskService.actualValue = `${this.prefix}${this._maskService.maskIsShown.slice(0, selEnd)}${this._inputValue.split(this.prefix).join('')}`;
@@ -505,8 +517,9 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
this._maskService.actualValue = `${part1}${this._maskService.placeHolderCharacter}${part2}`;
}
}
+ position = this._code === MaskExpression.DELETE ? position + 1 : position;
}
- if (this._code !== MaskExpression.BACKSPACE) {
+ if (!backspaceOrDelete) {
if (!checkSymbols && !checkSpecialCharacter && selectRangeBackspace) {
position = Number(el.selectionStart) - 1;
} else if (
@@ -996,6 +1009,7 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
if (typeof this.inputTransformFn !== 'function') {
this._maskService.writingValue = true;
}
+
this._maskService.formElementProperty = [
'value',
this._maskService.applyMask(inputValue, this._maskService.maskExpression),
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 777e43bb..1de853eb 100644
--- a/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts
+++ b/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts
@@ -206,6 +206,7 @@ export class NgxMaskService extends NgxMaskApplierService {
this._emitValue =
this._previousValue !== this._currentValue ||
this.maskChanged ||
+ this.writingValue ||
(this._previousValue === this._currentValue && justPasted);
}
@@ -215,6 +216,7 @@ export class NgxMaskService extends NgxMaskApplierService {
? requestAnimationFrame(() => this.formControlResult(result))
: this.formControlResult(result)
: '';
+
if (!this.showMaskTyped || (this.showMaskTyped && this.hiddenInput)) {
if (this.hiddenInput) {
if (backspaced) {
@@ -530,6 +532,10 @@ export class NgxMaskService extends NgxMaskApplierService {
* @param inputValue the current form input value
*/
private formControlResult(inputValue: string): void {
+ if (this.writingValue && !inputValue) {
+ this.onChange('');
+ return;
+ }
if (this.writingValue || (!this.triggerOnMaskChange && this.maskChanged)) {
// eslint-disable-next-line no-unused-expressions,@typescript-eslint/no-unused-expressions
this.triggerOnMaskChange && this.maskChanged
@@ -583,9 +589,11 @@ export class NgxMaskService extends NgxMaskApplierService {
) {
return value;
}
- if (String(value).length > 16 && this.separatorLimit.length > 14) {
+
+ if (String(value).length > 14 && this.maskExpression.startsWith(MaskExpression.SEPARATOR)) {
return String(value);
}
+
const num = Number(value);
if (this.maskExpression.startsWith(MaskExpression.SEPARATOR) && Number.isNaN(num)) {
const val = String(value).replace(',', '.');
@@ -686,7 +694,7 @@ export class NgxMaskService extends NgxMaskApplierService {
if (processedResult === this.decimalMarker) {
return null;
}
- if (this.separatorLimit.length > 14) {
+ if (separatorValue.length > 14) {
return String(separatorValue);
}
return this._checkPrecision(this.maskExpression, separatorValue);
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 b072e0af..24cc97f6 100644
--- a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts
+++ b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts
@@ -969,4 +969,56 @@ describe('Directive: Mask', () => {
expect(component.form.dirty).toBe(false);
});
+
+ it('mask sepator.2 after setValue should be dont dirty', () => {
+ component.mask = 'separator.0';
+ component.form.setValue('2002');
+
+ expect(component.form.dirty).toBe(false);
+ });
+
+ it('should return empty string in formControl mask SSS-SSS-SSS', () => {
+ component.mask = 'SSS-SSS-SSS';
+ component.form.setValue('978-1-93624-386-0');
+ const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
+ const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
+ spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);
+ fixture.detectChanges();
+
+ expect(inputTarget.value).toBe('');
+ });
+
+ it('should return empty string in formControl mask AAA-AAA-AAA', () => {
+ component.mask = 'AAA-AAA-AAA';
+ component.form.setValue('978-123-936');
+ const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
+ const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
+ spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);
+ fixture.detectChanges();
+
+ expect(inputTarget.value).toBe('');
+ });
+
+ it('should return empty string in formControl mask (000) 000-000', () => {
+ component.mask = '(000) 000-000';
+ component.form.setValue('978-123-936');
+ const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
+ const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
+ spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);
+ fixture.detectChanges();
+
+ expect(inputTarget.value).toBe('');
+ });
+
+ it('should return empty string in formControl mask (000) 000-000 with prefix +7', () => {
+ component.mask = '(000) 000-000';
+ component.prefix = '+7 ';
+ component.form.setValue('978-123-936');
+ const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
+ const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
+ spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);
+ fixture.detectChanges();
+
+ expect(inputTarget.value).toBe('');
+ });
});
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 e433c013..a83b43b1 100644
--- a/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts
+++ b/projects/ngx-mask-lib/src/test/cursor.cy-spec.ts
@@ -176,108 +176,6 @@ describe('Test Date Hh:m0', () => {
.clear();
});
- it('Mask separator.2 check cursor with value 100.0', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: '.',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('1000')
- .type('{leftArrow}')
- .type('.')
- .should('have.value', '100.0')
- .should('have.prop', 'selectionStart', 4);
- });
-
- it('Mask separator.2 check cursor with value 1.00', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: '.',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('1000')
- .type('{leftArrow}'.repeat(3))
- .type('.')
- .should('have.value', '1.00')
- .should('have.prop', 'selectionStart', 2);
- });
-
- it('Mask separator.2 check cursor with value 123456789.20', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: '.',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('123456789.20')
- .type('{leftArrow}'.repeat(4))
- .type('.')
- .should('have.value', '12,345,678.9')
- .should('have.prop', 'selectionStart', 11);
- });
-
- it('Mask separator.2 check cursor with value 100.0', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: ',',
- thousandSeparator: '.',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('1000')
- .type('{leftArrow}')
- .type(',')
- .should('have.value', '100,0')
- .should('have.prop', 'selectionStart', 4);
- });
-
- it('Mask separator.2 check cursor with value 1.00', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: ',',
- thousandSeparator: '.',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('1000')
- .type('{leftArrow}'.repeat(3))
- .type(',')
- .should('have.value', '1,00')
- .should('have.prop', 'selectionStart', 2);
- });
-
- it('Mask separator.2 check cursor with value 123456789.20', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: ',',
- thousandSeparator: '.',
- },
- imports: [CypressTestMaskModule],
- });
- cy.get('#masked')
- .type('123456789,20')
- .type('{leftArrow}'.repeat(4))
- .type(',')
- .should('have.value', '12.345.678,9')
- .should('have.prop', 'selectionStart', 11);
- });
-
it('Mask d0/M0/0000 should set cursor on right position', () => {
cy.mount(CypressTestMaskComponent, {
componentProperties: {
@@ -381,95 +279,4 @@ describe('Test Date Hh:m0', () => {
cy.get('#masked').type('111').should('have.value', '(11) 1');
cy.get('#masked').type('{backspace}').should('have.prop', 'selectionStart', 4);
});
-
- it('when decimalMarker doenst set should have right position cursor thousandSeparator = .', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: '.',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('12345678,00')
-
- .should('have.value', '12.345.678,00')
- .type('{leftArrow}'.repeat(3))
- .type('{backspace}'.repeat(3))
- .should('have.value', '12.345,00');
- });
-
- it('when decimalMarker doenst set should have right position cursor thousandSeparator = ,', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('12345678.00')
-
- .should('have.value', '12,345,678.00')
- .type('{leftArrow}'.repeat(3))
- .type('{backspace}'.repeat(3))
- .should('have.value', '12,345.00');
- });
-
- it('should place cursor after backspace with separatorLimit = 10 in correct position', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- separatorLimit: '10',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('12.10')
- .should('have.value', '12.10')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '12')
- .should('have.prop', 'selectionStart', 2);
- });
-
- it('should place cursor after backspace with separatorLimit = 100 in correct position', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- separatorLimit: '100',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('123.10')
- .should('have.value', '123.10')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '123')
- .should('have.prop', 'selectionStart', 3);
- });
-
- it('should place cursor after backspace with separatorLimit = 1000 in correct position', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: ',',
- separatorLimit: '1000',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('1234.10')
- .should('have.value', '1,234.10')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '1,234')
- .should('have.prop', 'selectionStart', 5);
- });
});
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 c711933f..2b3a12b1 100644
--- a/projects/ngx-mask-lib/src/test/delete.cy-spec.ts
+++ b/projects/ngx-mask-lib/src/test/delete.cy-spec.ts
@@ -289,42 +289,6 @@ describe('Directive: Mask (Delete)', () => {
.should('have.value', '+32 __ ___ __ __');
});
- it('should backspace with separator and prefix', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: ',',
- prefix: '$ ',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('1234567890')
- .should('have.value', '$ 1,234,567,890')
- .type('{leftArrow}'.repeat(3))
- .type('{backspace}')
- .should('have.prop', 'selectionStart', 11);
- });
-
- it('should backspace with separator and prefix', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: '.',
- prefix: '$ ',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('1234567890')
- .should('have.value', '$ 1.234.567.890')
- .type('{leftArrow}'.repeat(3))
- .type('{backspace}')
- .should('have.prop', 'selectionStart', 11);
- });
-
it('should backspace with showMaskTyped and leadZeroDateTime', () => {
cy.mount(CypressTestMaskComponent, {
componentProperties: {
@@ -376,233 +340,6 @@ describe('Directive: Mask (Delete)', () => {
.should('have.value', '__:__:____');
});
- it('should correct work after backspace separator.6 decimalMarker . thousandSeparator ,', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.6',
- decimalMarker: '.',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('0.000001')
- .should('have.value', '0.000001')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '0.00001')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '0.0001')
- .type('{backspace}')
- .should('have.value', '1');
- });
-
- it('should correct work after backspace separator.2 decimalMarker . thousandSeparator ,', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: '.',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('0.01')
- .should('have.value', '0.01')
- .type('{leftArrow}')
- .type('{backspace}')
- .should('have.value', '0.1')
- .type('{leftArrow}')
- .type('{backspace}')
- .should('have.value', '1');
- });
-
- it('should correct work after backspace separator.2 decimalMarker . thousandSeparator , allowNegative', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- decimalMarker: '.',
- thousandSeparator: ',',
- allowNegativeNumbers: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('-0.01')
- .should('have.value', '-0.01')
- .type('{leftArrow}')
- .type('{backspace}')
- .should('have.value', '-0.1')
- .type('{leftArrow}')
- .type('{backspace}')
- .should('have.value', '-1');
- });
-
- it('should correct work after backspace separator.3 decimalMarker . thousandSeparator , allowNegative', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.3',
- decimalMarker: '.',
- thousandSeparator: ',',
- allowNegativeNumbers: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('-0.014')
- .should('have.value', '-0.014')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '-0.14')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '-14');
- });
-
- it('should correct work after backspace separator.3 leadZero allowNegative', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.3',
- allowNegativeNumbers: true,
- leadZero: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('-0.1')
- .should('have.value', '-0.1')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '-1')
- .type('{backspace}')
- .should('have.value', '-');
- });
-
- it('should correct work after backspace separator', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('0.33')
- .should('have.value', '0.33')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '33');
- });
-
- it('should correct work after backspace separator leadZero', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator',
- leadZero: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('0.33')
- .should('have.value', '0.33')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '33');
- });
-
- it('should correct work after backspace separator allowNegativeNumbers', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator',
- allowNegativeNumbers: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('-0.33')
- .should('have.value', '-0.33')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '-33');
- });
-
- it('should correct work after backspace separator leadZero', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator',
- leadZero: true,
- allowNegativeNumbers: true,
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('-0.33')
- .should('have.value', '-0.33')
- .type('{leftArrow}'.repeat(2))
- .type('{backspace}')
- .should('have.value', '-33');
- });
-
- it('should correct work after backspace separator.2 when first digit .', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: '.',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('50004')
- .should('have.value', '50.004')
- .type('{leftArrow}'.repeat(5))
- .type('{backspace}')
- .should('have.value', '4');
- });
-
- it('should correct work after backspace separator.2 when first digit ,', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: ',',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('50004')
- .should('have.value', '50,004')
- .type('{leftArrow}'.repeat(5))
- .type('{backspace}')
- .should('have.value', '4');
- });
-
- it('should correct work after backspace separator.2 when first digit whitespace', () => {
- cy.mount(CypressTestMaskComponent, {
- componentProperties: {
- mask: 'separator.2',
- thousandSeparator: ' ',
- },
- imports: [CypressTestMaskModule],
- });
-
- cy.get('#masked')
- .type('50004')
- .should('have.value', '50 004')
- .type('{leftArrow}'.repeat(5))
- .type('{backspace}')
- .should('have.value', '4');
- });
-
it('should backspace with mask Hh:m0', () => {
cy.mount(CypressTestMaskComponent, {
componentProperties: {
diff --git a/projects/ngx-mask-lib/src/test/keep-character-position.cy-spec.ts b/projects/ngx-mask-lib/src/test/keep-character-position.cy-spec.ts
index 00448085..bfba7384 100644
--- a/projects/ngx-mask-lib/src/test/keep-character-position.cy-spec.ts
+++ b/projects/ngx-mask-lib/src/test/keep-character-position.cy-spec.ts
@@ -207,4 +207,47 @@ describe('Directive: Mask (Delete)', () => {
.type('{backspace}'.repeat(2))
.should('have.value', '12/__/567 test');
});
+
+ it('should delete character from del', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: '000-000-000',
+ keepCharacterPositions: true,
+ showMaskTyped: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('123456789')
+ .type('{leftArrow}'.repeat(11))
+ .type('{del}'.repeat(11))
+ .should('have.value', '___-___-___');
+
+ cy.get('#masked').clear();
+ cy.get('#masked')
+ .type('123456789')
+ .type('{leftArrow}'.repeat(4))
+ .type('{del}')
+ .should('have.value', '123-456-789')
+ .should('have.prop', 'selectionStart', 8);
+ });
+
+ it('should delete character from del', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: '0000 0000 0000 0000',
+ keepCharacterPositions: true,
+ showMaskTyped: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('1234567891011121')
+ .type('{leftArrow}'.repeat(5))
+ .type('{del}')
+ .should('have.value', '1234 5678 9101 1121')
+ .should('have.prop', 'selectionStart', 15);
+ });
});
diff --git a/projects/ngx-mask-lib/src/test/separator.cy-spec.ts b/projects/ngx-mask-lib/src/test/separator.cy-spec.ts
new file mode 100644
index 00000000..d7176ed8
--- /dev/null
+++ b/projects/ngx-mask-lib/src/test/separator.cy-spec.ts
@@ -0,0 +1,460 @@
+import { CypressTestMaskModule } from './utils/cypress-test.module';
+import { CypressTestMaskComponent } from './utils/cypress-test-component.component';
+
+describe('Test Date Hh:m0', () => {
+ it('Mask separator.2 check cursor with value 100.0', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('1000')
+ .type('{leftArrow}')
+ .type('.')
+ .should('have.value', '100.0')
+ .should('have.prop', 'selectionStart', 4);
+ });
+
+ it('Mask separator.2 check cursor with value 1.00', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('1000')
+ .type('{leftArrow}'.repeat(3))
+ .type('.')
+ .should('have.value', '1.00')
+ .should('have.prop', 'selectionStart', 2);
+ });
+
+ it('Mask separator.2 check cursor with value 123456789.20', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('123456789.20')
+ .type('{leftArrow}'.repeat(4))
+ .type('.')
+ .should('have.value', '12,345,678.9')
+ .should('have.prop', 'selectionStart', 11);
+ });
+
+ it('Mask separator.2 check cursor with value 100.0', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: ',',
+ thousandSeparator: '.',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('1000')
+ .type('{leftArrow}')
+ .type(',')
+ .should('have.value', '100,0')
+ .should('have.prop', 'selectionStart', 4);
+ });
+
+ it('Mask separator.2 check cursor with value 1.00', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: ',',
+ thousandSeparator: '.',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('1000')
+ .type('{leftArrow}'.repeat(3))
+ .type(',')
+ .should('have.value', '1,00')
+ .should('have.prop', 'selectionStart', 2);
+ });
+
+ it('Mask separator.2 check cursor with value 123456789.20', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: ',',
+ thousandSeparator: '.',
+ },
+ imports: [CypressTestMaskModule],
+ });
+ cy.get('#masked')
+ .type('123456789,20')
+ .type('{leftArrow}'.repeat(4))
+ .type(',')
+ .should('have.value', '12.345.678,9')
+ .should('have.prop', 'selectionStart', 11);
+ });
+
+ it('when decimalMarker doenst set should have right position cursor thousandSeparator = .', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: '.',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('12345678,00')
+
+ .should('have.value', '12.345.678,00')
+ .type('{leftArrow}'.repeat(3))
+ .type('{backspace}'.repeat(3))
+ .should('have.value', '12.345,00');
+ });
+
+ it('when decimalMarker doenst set should have right position cursor thousandSeparator = ,', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('12345678.00')
+
+ .should('have.value', '12,345,678.00')
+ .type('{leftArrow}'.repeat(3))
+ .type('{backspace}'.repeat(3))
+ .should('have.value', '12,345.00');
+ });
+
+ it('should place cursor after backspace with separatorLimit = 10 in correct position', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ separatorLimit: '10',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('12.10')
+ .should('have.value', '12.10')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '12')
+ .should('have.prop', 'selectionStart', 2);
+ });
+
+ it('should place cursor after backspace with separatorLimit = 100 in correct position', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ separatorLimit: '100',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('123.10')
+ .should('have.value', '123.10')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '123')
+ .should('have.prop', 'selectionStart', 3);
+ });
+
+ it('should place cursor after backspace with separatorLimit = 1000 in correct position', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: ',',
+ separatorLimit: '1000',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('1234.10')
+ .should('have.value', '1,234.10')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '1,234')
+ .should('have.prop', 'selectionStart', 5);
+ });
+
+ it('should backspace with separator and prefix', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: ',',
+ prefix: '$ ',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('1234567890')
+ .should('have.value', '$ 1,234,567,890')
+ .type('{leftArrow}'.repeat(3))
+ .type('{backspace}')
+ .should('have.prop', 'selectionStart', 11);
+ });
+
+ it('should backspace with separator and prefix', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: '.',
+ prefix: '$ ',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('1234567890')
+ .should('have.value', '$ 1.234.567.890')
+ .type('{leftArrow}'.repeat(3))
+ .type('{backspace}')
+ .should('have.prop', 'selectionStart', 11);
+ });
+
+ it('should correct work after backspace separator.6 decimalMarker . thousandSeparator ,', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.6',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('0.000001')
+ .should('have.value', '0.000001')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '0.00001')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '0.0001')
+ .type('{backspace}')
+ .should('have.value', '1');
+ });
+
+ it('should correct work after backspace separator.2 decimalMarker . thousandSeparator ,', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('0.01')
+ .should('have.value', '0.01')
+ .type('{leftArrow}')
+ .type('{backspace}')
+ .should('have.value', '0.1')
+ .type('{leftArrow}')
+ .type('{backspace}')
+ .should('have.value', '1');
+ });
+
+ it('should correct work after backspace separator.2 decimalMarker . thousandSeparator , allowNegative', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ allowNegativeNumbers: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('-0.01')
+ .should('have.value', '-0.01')
+ .type('{leftArrow}')
+ .type('{backspace}')
+ .should('have.value', '-0.1')
+ .type('{leftArrow}')
+ .type('{backspace}')
+ .should('have.value', '-1');
+ });
+
+ it('should correct work after backspace separator.3 decimalMarker . thousandSeparator , allowNegative', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.3',
+ decimalMarker: '.',
+ thousandSeparator: ',',
+ allowNegativeNumbers: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('-0.014')
+ .should('have.value', '-0.014')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '-0.14')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '-14');
+ });
+
+ it('should correct work after backspace separator.3 leadZero allowNegative', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.3',
+ allowNegativeNumbers: true,
+ leadZero: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('-0.1')
+ .should('have.value', '-0.1')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '-1')
+ .type('{backspace}')
+ .should('have.value', '-');
+ });
+
+ it('should correct work after backspace separator', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('0.33')
+ .should('have.value', '0.33')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '33');
+ });
+
+ it('should correct work after backspace separator leadZero', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator',
+ leadZero: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('0.33')
+ .should('have.value', '0.33')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '33');
+ });
+
+ it('should correct work after backspace separator allowNegativeNumbers', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator',
+ allowNegativeNumbers: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('-0.33')
+ .should('have.value', '-0.33')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '-33');
+ });
+
+ it('should correct work after backspace separator leadZero', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator',
+ leadZero: true,
+ allowNegativeNumbers: true,
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('-0.33')
+ .should('have.value', '-0.33')
+ .type('{leftArrow}'.repeat(2))
+ .type('{backspace}')
+ .should('have.value', '-33');
+ });
+
+ it('should correct work after backspace separator.2 when first digit .', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: '.',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('50004')
+ .should('have.value', '50.004')
+ .type('{leftArrow}'.repeat(5))
+ .type('{backspace}')
+ .should('have.value', '4');
+ });
+
+ it('should correct work after backspace separator.2 when first digit ,', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: ',',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('50004')
+ .should('have.value', '50,004')
+ .type('{leftArrow}'.repeat(5))
+ .type('{backspace}')
+ .should('have.value', '4');
+ });
+
+ it('should correct work after backspace separator.2 when first digit whitespace', () => {
+ cy.mount(CypressTestMaskComponent, {
+ componentProperties: {
+ mask: 'separator.2',
+ thousandSeparator: ' ',
+ },
+ imports: [CypressTestMaskModule],
+ });
+
+ cy.get('#masked')
+ .type('50004')
+ .should('have.value', '50 004')
+ .type('{leftArrow}'.repeat(5))
+ .type('{backspace}')
+ .should('have.value', '4');
+ });
+});
diff --git a/projects/ngx-mask-lib/src/test/separator.spec.ts b/projects/ngx-mask-lib/src/test/separator.spec.ts
index 970bd8dd..93529b7a 100644
--- a/projects/ngx-mask-lib/src/test/separator.spec.ts
+++ b/projects/ngx-mask-lib/src/test/separator.spec.ts
@@ -1835,4 +1835,42 @@ describe('Separator: Mask', () => {
fixture.detectChanges();
expect(inputTarget.value).toBe('10.1000000000');
}));
+
+ it('should support big numbers with separator', () => {
+ component.mask = 'separator';
+
+ equal('12345678910111215', '12 345 678 910 111 215', fixture);
+ expect(component.form.value).toBe('12345678910111215');
+ equal('12345678910111215.9999', '12 345 678 910 111 215.9999', fixture);
+ expect(component.form.value).toBe('12345678910111215.9999');
+ });
+
+ it('should support big numbers with separator 2', () => {
+ component.mask = 'separator.2';
+
+ equal('12345678910111215', '12 345 678 910 111 215', fixture);
+ expect(component.form.value).toBe('12345678910111215');
+ equal('12345678910111215.9999', '12 345 678 910 111 215.99', fixture);
+ expect(component.form.value).toBe('12345678910111215.99');
+ });
+
+ it('should support big numbers with separator 2 thousand =.', () => {
+ component.mask = 'separator.2';
+ component.thousandSeparator = '.';
+
+ equal('12345678910111215', '12.345.678.910.111.215', fixture);
+ expect(component.form.value).toBe('12345678910111215');
+ equal('12345678910111215,99', '12.345.678.910.111.215,99', fixture);
+ expect(component.form.value).toBe('12345678910111215.99');
+ });
+
+ it('should support big numbers with separator 2 thousand =,', () => {
+ component.mask = 'separator.2';
+ component.thousandSeparator = ',';
+
+ equal('12345678910111215', '12,345,678,910,111,215', fixture);
+ expect(component.form.value).toBe('12345678910111215');
+ equal('12345678910111215.9999', '12,345,678,910,111,215.99', fixture);
+ expect(component.form.value).toBe('12345678910111215.99');
+ });
});
diff --git a/projects/ngx-mask-lib/src/test/validation.spec.ts b/projects/ngx-mask-lib/src/test/validation.spec.ts
index cc65a35e..6ce0fdd9 100644
--- a/projects/ngx-mask-lib/src/test/validation.spec.ts
+++ b/projects/ngx-mask-lib/src/test/validation.spec.ts
@@ -87,6 +87,23 @@ export class TestValidatorDropSpecialCharacters {
public dropSpecialCharacters = [' '];
}
+@Component({
+ selector: 'jsdaddy-open-source-test',
+ template: `
+
+ `,
+})
+// eslint-disable-next-line @angular-eslint/component-class-suffix
+export class TestValidatorEmailMask {
+ public form: FormControl = new FormControl('', Validators.required);
+ public mask = 'A*@A*.A*';
+ public dropSpecialCharacters = false;
+}
+
describe('Directive: Mask (Validation)', () => {
describe('Global validation true, validation attribute on input not specified', () => {
let fixture: ComponentFixture;
@@ -422,4 +439,46 @@ describe('Directive: Mask (Validation)', () => {
expect(component.form.valid).toBe(true);
});
});
+
+ describe('Global validation true, email mask', () => {
+ let fixture: ComponentFixture;
+ let component: TestValidatorEmailMask;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [TestValidatorEmailMask],
+ imports: [ReactiveFormsModule, NgxMaskDirective],
+ providers: [provideNgxMask({ validation: true })],
+ });
+ fixture = TestBed.createComponent(TestValidatorEmailMask);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('email Mask should validated correct', () => {
+ component.mask = 'A*@A*.A*';
+ component.dropSpecialCharacters = false;
+
+ equal('validate', 'validate', fixture);
+ expect(component.form.valid).toBe(false);
+
+ equal('validate@', 'validate@', fixture);
+ expect(component.form.valid).toBe(false);
+
+ equal('validate@some', 'validate@some', fixture);
+ expect(component.form.valid).toBe(false);
+
+ equal('validate@some.', 'validate@some.', fixture);
+ expect(component.form.valid).toBe(false);
+
+ equal('validate@some.e', 'validate@some.e', fixture);
+ expect(component.form.valid).toBe(true);
+
+ equal('validate@some.eu', 'validate@some.eu', fixture);
+ expect(component.form.valid).toBe(true);
+
+ equal('validate@some.com', 'validate@some.com', fixture);
+ expect(component.form.valid).toBe(true);
+ });
+ });
});
diff --git a/src/assets/content/common-cases.ts b/src/assets/content/common-cases.ts
index 70d807f5..b775d193 100644
--- a/src/assets/content/common-cases.ts
+++ b/src/assets/content/common-cases.ts
@@ -63,6 +63,13 @@ export const ComDocs: ComDoc[] = [
id: 8,
anchor: 'email-mask',
},
+ {
+ header: 'Email mask with validation',
+ text: '',
+ code: ``,
+ id: 8,
+ anchor: 'email-mask',
+ },
{
header: 'Allow negative numbers to mask',
text: 'You can allow negative numbers',
@@ -142,8 +149,18 @@ export const ComExamples: TExample[] = [
{
_placeholder: 'Valid email',
_mask: 'A*@A*.SSS',
+ _validation: true,
+ _dropSpecialCharacters: false,
control: { form: new UntypedFormControl(''), model: '' },
},
+ {
+ _placeholder: 'Valid email',
+ _validation: true,
+ _dropSpecialCharacters: false,
+ _mask: 'A*@A*.A*',
+ control: { form: new UntypedFormControl(''), model: '' },
+ },
+
{
_placeholder: 'allowNegativeNumbers mask',
_allowNegativeNumbers: true,