Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release #1445

Merged
merged 9 commits into from
Nov 1, 2024
12 changes: 12 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ jobs:
run: bun publish:lib
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
- name: Extract version
id: get_version
run: |
VERSION=$(node -p "require('./dist/ngx-mask-lib/package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT

slack_notification:
needs:
Expand Down Expand Up @@ -59,6 +64,13 @@ jobs:
"text": "Project: `${{ github.event.repository.name }}`"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Version: `${{ needs.build.outputs.version || 'TBA' }}`"
}
},
{
"type": "section",
"text": {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quality-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ jobs:
- name: Check quality
run: |
bun i
bash .github/workflows/scripts/quality.sh
bash .github/workflows/scripts/quality.sh
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 18.0.2(2024-11-01)

### Fix

- Fix ([#1427](https://github.com/JsDaddy/ngx-mask/issues/1427))
- Fix ([#1405](https://github.com/JsDaddy/ngx-mask/issues/1405))
- Fix ([#1426](https://github.com/JsDaddy/ngx-mask/issues/1426))
- Fix ([#1406](https://github.com/JsDaddy/ngx-mask/issues/1406))
- Fix ([#1420](https://github.com/JsDaddy/ngx-mask/issues/1420))
- Fix ([#1416](https://github.com/JsDaddy/ngx-mask/issues/1416))

# 18.0.1(2024-10-29)

### Breaking Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-mask",
"version": "18.0.1",
"version": "18.0.2",
"description": "Awesome ngx mask",
"license": "MIT",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-mask-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-mask",
"version": "18.0.1",
"version": "18.0.2",
"description": "awesome ngx mask",
"keywords": [
"ng2-mask",
Expand Down
16 changes: 12 additions & 4 deletions projects/ngx-mask-lib/src/lib/ngx-mask-applier.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ export class NgxMaskApplierService {

const precision: number = this.getPrecision(maskExpression);
const decimalMarker = Array.isArray(this.decimalMarker)
? MaskExpression.DOT
? this.thousandSeparator === MaskExpression.DOT
? MaskExpression.COMMA
: MaskExpression.DOT
: this.decimalMarker;

if (precision === 0) {
Expand Down Expand Up @@ -371,6 +373,8 @@ export class NgxMaskApplierService {
const commaShift: number =
result.indexOf(MaskExpression.COMMA) - processedValue.indexOf(MaskExpression.COMMA);
const shiftStep: number = result.length - processedValue.length;
const backspacedDecimalMarkerWithSeparatorLimit =
backspaced && result.length < inputValue.length && this.separatorLimit;

if (
(result[processedPosition - 1] === this.thousandSeparator ||
Expand All @@ -379,15 +383,18 @@ export class NgxMaskApplierService {
backspaced
) {
processedPosition = processedPosition - 1;
} else if (shiftStep > 0 && result[processedPosition] !== this.thousandSeparator) {
} else if (
(shiftStep > 0 && result[processedPosition] !== this.thousandSeparator) ||
backspacedDecimalMarkerWithSeparatorLimit
) {
backspaceShift = true;
let _shift = 0;
do {
this._shift.add(processedPosition + _shift);
_shift++;
} while (_shift < shiftStep);
} else if (
result[processedPosition - 1] === this.decimalMarker ||
result[processedPosition - 1] === this.thousandSeparator ||
shiftStep === -4 ||
shiftStep === -3 ||
result[processedPosition] === this.thousandSeparator
Expand Down Expand Up @@ -821,6 +828,7 @@ export class NgxMaskApplierService {
) => {
let x: string[] = [];
let decimalChar = '';

if (Array.isArray(decimalChars)) {
const regExp = new RegExp(
decimalChars.map((v) => ('[\\^$.|?*+()'.indexOf(v) >= 0 ? `\\${v}` : v)).join('|')
Expand Down Expand Up @@ -870,7 +878,7 @@ export class NgxMaskApplierService {
return !isNaN(value) && value >= 0 && value <= 100;
};

private getPrecision = (maskExpression: string): number => {
public getPrecision = (maskExpression: string): number => {
const x: string[] = maskExpression.split(MaskExpression.DOT);
if (x.length > 1) {
return Number(x[x.length - 1]);
Expand Down
39 changes: 28 additions & 11 deletions projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,25 +687,35 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
public onBlur(e: CustomKeyboardEvent): void {
if (this._maskValue) {
const el: HTMLInputElement = e.target as HTMLInputElement;
if (this.leadZero && el.value.length > 0 && typeof this.decimalMarker === 'string') {
if (
this._maskService.leadZero &&
el.value.length > 0 &&
typeof this._maskService.decimalMarker === 'string'
) {
const maskExpression = this._maskService.maskExpression;
const precision = Number(
this._maskService.maskExpression.slice(
maskExpression.length - 1,
maskExpression.length
)
);

if (precision > 0) {
el.value = this.suffix ? el.value.split(this.suffix).join('') : el.value;
const decimalPart = el.value.split(this.decimalMarker)[1] as string;
el.value = el.value.includes(this.decimalMarker)
el.value = this._maskService.suffix
? el.value.split(this._maskService.suffix).join('')
: el.value;
const decimalPart = el.value.split(
this._maskService.decimalMarker
)[1] as string;

el.value = el.value.includes(this._maskService.decimalMarker)
? el.value +
MaskExpression.NUMBER_ZERO.repeat(precision - decimalPart.length) +
this.suffix
this._maskService.suffix
: el.value +
this.decimalMarker +
this._maskService.decimalMarker +
MaskExpression.NUMBER_ZERO.repeat(precision) +
this.suffix;
this._maskService.suffix;
this._maskService.actualValue = el.value;
}
}
Expand Down Expand Up @@ -771,7 +781,14 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
((el.selectionStart as number) || (el.selectionEnd as number)) <=
this._maskService.prefix.length
) {
el.selectionStart = this._maskService.prefix.length;
const specialCharactersAtTheStart =
this._maskService.maskExpression.match(
new RegExp(
`^[${this._maskService.specialCharacters.map((c) => `\\${c}`).join('')}]+`
)
)?.[0].length || 0;

el.selectionStart = this._maskService.prefix.length + specialCharactersAtTheStart;
return;
}
/** select only inserted text */
Expand Down Expand Up @@ -903,7 +920,6 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
if (value !== null) {
value = this.inputTransformFn ? this.inputTransformFn(value) : value;
}

if (
typeof value === 'string' ||
typeof value === 'number' ||
Expand Down Expand Up @@ -943,10 +959,11 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida
inputValue as string
);
}

if (
this.decimalMarker === MaskExpression.COMMA ||
this._maskService.decimalMarker === MaskExpression.COMMA ||
(Array.isArray(this._maskService.decimalMarker) &&
this.thousandSeparator === MaskExpression.DOT)
this._maskService.thousandSeparator === MaskExpression.DOT)
) {
inputValue = inputValue
.toString()
Expand Down
3 changes: 2 additions & 1 deletion projects/ngx-mask-lib/src/lib/ngx-mask.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,9 @@ export class NgxMaskService extends NgxMaskApplierService {
}

public _checkPrecision(separatorExpression: string, separatorValue: string): number | string {
const separatorPrecision = separatorExpression.slice(10, 11);
const separatorPrecision = this.getPrecision(separatorExpression);
let value = separatorValue;

if (
separatorExpression.indexOf('2') > 0 ||
(this.leadZero && Number(separatorPrecision) > 0)
Expand Down
91 changes: 91 additions & 0 deletions projects/ngx-mask-lib/src/test/cursor.cy-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,4 +381,95 @@ 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);
});
});
34 changes: 34 additions & 0 deletions projects/ngx-mask-lib/src/test/default-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,38 @@ describe('Default config', () => {
expect(fixture.nativeElement.querySelector('input').value).toBe('1.234,56');
});
});

it('default config overriden - decimalMarker and thousandSeparator and leadZero', () => {
const fixture = createComponentWithDefaultConfig({
thousandSeparator: '.',
decimalMarker: ',',
leadZero: true,
separatorLimit: '100',
});
const component = fixture.componentInstance;
component.mask = 'separator.2';

component.form = new FormControl(123);
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
expect(fixture.nativeElement.querySelector('input').value).toBe('123,00');
});
});

it('default config overriden - decimalMarker and thousandSeparator and leadZero and suffix', () => {
const fixture = createComponentWithDefaultConfig({
suffix: ' €',
thousandSeparator: ' ',
decimalMarker: ',',
leadZero: true,
});
const component = fixture.componentInstance;
component.mask = 'separator.2';

component.form = new FormControl(15000.33);
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
expect(fixture.nativeElement.querySelector('input').value).toBe('15 000,33 €');
});
});
});
40 changes: 40 additions & 0 deletions projects/ngx-mask-lib/src/test/separator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1795,4 +1795,44 @@ describe('Separator: Mask', () => {
expect(inputElement.value).toBe('1 234 567.89');
expect(inputElement.selectionStart).toBe(1);
});

it('should show correct value with separator.9', fakeAsync(() => {
component.mask = 'separator.9';
component.decimalMarker = '.';
component.leadZero = true;
component.separatorLimit = '10';
fixture.detectChanges();

const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);

equal('1', '1', fixture);
equal('12', '12', fixture);

component.form.setValue(10.1);
tick();
fixture.detectChanges();
expect(inputTarget.value).toBe('10.100000000');
}));

it('should show correct value with separator.10', fakeAsync(() => {
component.mask = 'separator.10';
component.decimalMarker = '.';
component.leadZero = true;
component.separatorLimit = '10';
fixture.detectChanges();

const debugElement: DebugElement = fixture.debugElement.query(By.css('input'));
const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement;
spyOnProperty(document, 'activeElement').and.returnValue(inputTarget);

equal('1', '1', fixture);
equal('12', '12', fixture);

component.form.setValue(10.1);
tick();
fixture.detectChanges();
expect(inputTarget.value).toBe('10.1000000000');
}));
});
Loading
Loading