From 4ae0010ef2149694d22d7ae9eb8c9880120c8c75 Mon Sep 17 00:00:00 2001 From: Nikita Barsukov Date: Tue, 25 Apr 2023 13:00:49 +0300 Subject: [PATCH] fix(kit): `Number` fails to trim leading zeroes after deleting of leading digit (#268) --- .../kit/number/number-zero-integer-part.cy.ts | 4 +- .../kit/src/lib/masks/number/number-mask.ts | 5 +- ...leading-zeroes-validation-postprocessor.ts | 47 ++++++++++++------- ...ng-zeroes-validation-postprocessor.spec.ts | 2 +- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/projects/demo-integrations/cypress/tests/kit/number/number-zero-integer-part.cy.ts b/projects/demo-integrations/cypress/tests/kit/number/number-zero-integer-part.cy.ts index 57b591b1c..3d9dde35a 100644 --- a/projects/demo-integrations/cypress/tests/kit/number/number-zero-integer-part.cy.ts +++ b/projects/demo-integrations/cypress/tests/kit/number/number-zero-integer-part.cy.ts @@ -88,9 +88,7 @@ describe('Number | Zero integer part', () => { .should('have.prop', 'selectionEnd', '0'.length); }); - // TODO: BUG! - // https://github.com/Tinkoff/maskito/issues/266 - it.skip('1|-000-000 => Backspace => 0', () => { + it('1|-000-000 => Backspace => 0', () => { openNumberPage('thousandSeparator=_&precision=2'); cy.get('@input') diff --git a/projects/kit/src/lib/masks/number/number-mask.ts b/projects/kit/src/lib/masks/number/number-mask.ts index c994cd089..b851ba0e1 100644 --- a/projects/kit/src/lib/masks/number/number-mask.ts +++ b/projects/kit/src/lib/masks/number/number-mask.ts @@ -72,7 +72,10 @@ export function maskitoNumberOptionsGenerator({ createZeroPrecisionPreprocessor(precision, decimalSeparator), ), postprocessor: maskitoPipe( - createLeadingZeroesValidationPostprocessor(decimalSeparator), + createLeadingZeroesValidationPostprocessor( + decimalSeparator, + thousandSeparator, + ), createMaxValidationPostprocessor({decimalSeparator, max}), maskitoPrefixPostprocessorGenerator(prefix), maskitoPostfixPostprocessorGenerator(postfix), diff --git a/projects/kit/src/lib/masks/number/processors/leading-zeroes-validation-postprocessor.ts b/projects/kit/src/lib/masks/number/processors/leading-zeroes-validation-postprocessor.ts index 64fd85c70..5204175f9 100644 --- a/projects/kit/src/lib/masks/number/processors/leading-zeroes-validation-postprocessor.ts +++ b/projects/kit/src/lib/masks/number/processors/leading-zeroes-validation-postprocessor.ts @@ -1,5 +1,7 @@ import {MaskitoOptions} from '@maskito/core'; +import {escapeRegExp} from '../../../utils'; + /** * It removes repeated leading zeroes for integer part. * @example 0,|00005 => Backspace => |5 @@ -9,7 +11,35 @@ import {MaskitoOptions} from '@maskito/core'; */ export function createLeadingZeroesValidationPostprocessor( decimalSeparator: string, + thousandSeparator: string, ): NonNullable { + const trimLeadingZeroes = (value: string): string => { + const escapedThousandSeparator = escapeRegExp(thousandSeparator); + + return value + .replace( + // all leading zeroes followed by another zero + new RegExp(`^(\\D+)?[0${escapedThousandSeparator}]+(?=0)`), + '$1', + ) + .replace( + // zero followed by not-zero digit + new RegExp(`^(\\D+)?[0${escapedThousandSeparator}]+(?=[1-9])`), + '$1', + ); + }; + + const countTrimmedZeroesBefore = (value: string, index: number): number => { + const valueBefore = value.slice(0, index); + const followedByZero = value.slice(index).startsWith('0'); + + return ( + valueBefore.length - + trimLeadingZeroes(valueBefore).length + + (followedByZero ? 1 : 0) + ); + }; + return ({value, selection}) => { const [from, to] = selection; const hasDecimalSeparator = value.includes(decimalSeparator); @@ -32,20 +62,3 @@ export function createLeadingZeroesValidationPostprocessor( }; }; } - -function trimLeadingZeroes(value: string): string { - return value - .replace(/^(\D+)?0+(?=0)/, '$1') // all leading zeroes followed by another zero - .replace(/^(\D+)?0+(?=[1-9])/, '$1'); // zero followed by not-zero digit -} - -function countTrimmedZeroesBefore(value: string, index: number): number { - const valueBefore = value.slice(0, index); - const followedByZero = value.slice(index).startsWith('0'); - - return ( - valueBefore.length - - trimLeadingZeroes(valueBefore).length + - (followedByZero ? 1 : 0) - ); -} diff --git a/projects/kit/src/lib/masks/number/processors/tests/leading-zeroes-validation-postprocessor.spec.ts b/projects/kit/src/lib/masks/number/processors/tests/leading-zeroes-validation-postprocessor.spec.ts index f6a552ca5..cd1adf762 100644 --- a/projects/kit/src/lib/masks/number/processors/tests/leading-zeroes-validation-postprocessor.spec.ts +++ b/projects/kit/src/lib/masks/number/processors/tests/leading-zeroes-validation-postprocessor.spec.ts @@ -1,7 +1,7 @@ import {createLeadingZeroesValidationPostprocessor} from '../leading-zeroes-validation-postprocessor'; describe('createLeadingZeroesValidationPostprocessor', () => { - const processor = createLeadingZeroesValidationPostprocessor(','); + const processor = createLeadingZeroesValidationPostprocessor(',', ''); const DYMMY_INITIAL_STATE = {value: '', selection: [0, 0]} as const; const process = (