Skip to content

Commit

Permalink
fix(kit): Number with decimalZeroPadding=true should erase everyt…
Browse files Browse the repository at this point in the history
…hing on `.00` (#1207)
  • Loading branch information
nsbarsukov authored Apr 23, 2024
1 parent 08bb9b3 commit d72f225
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,65 @@ describe('Number | decimalZeroPadding', () => {
.should('have.prop', 'selectionEnd', '$42.24'.length);
});
});

describe('conditions for empty textfield', () => {
beforeEach(() => {
openNumberPage(
'thousandSeparator=_&precision=2&decimalZeroPadding=true&minusSign=-',
);
});

it('0.42| => Backspace x3 => 0|.00 => Backspace => Empty', () => {
cy.get('@input')
.type('0.42')
.should('have.value', '0.42')
.type('{backspace}'.repeat(3))
.should('have.value', '0.00')
.should('have.a.prop', 'selectionStart', 1)
.should('have.a.prop', 'selectionEnd', 1)
.type('{backspace}')
.should('have.value', '');
});

it('-.42| => Backspace x2 => -.|00 => Backspace => -', () => {
cy.get('@input')
.type('-0.42')
.should('have.value', '-0.42')
.type('{moveToStart}')
.type('{rightArrow}'.repeat(2))
.type('{backspace}')
.should('have.value', '-.42')
.type('{moveToEnd}')
.type('{backspace}')
.should('have.value', '-.40')
.type('{backspace}')
.should('have.value', '-.00')
.should('have.a.prop', 'selectionStart', 2)
.should('have.a.prop', 'selectionEnd', 2)
.type('{backspace}')
.should('have.value', '-')
.should('have.a.prop', 'selectionStart', 1)
.should('have.a.prop', 'selectionEnd', 1);
});

it('5|.00 => Backspace => Empty', () => {
cy.get('@input')
.type('5')
.should('have.value', '5.00')
.should('have.a.prop', 'selectionStart', 1)
.should('have.a.prop', 'selectionEnd', 1)
.type('{backspace}')
.should('have.value', '');
});

it('-5|.00 => Backspace => -', () => {
cy.get('@input')
.type('-5')
.should('have.value', '-5.00')
.should('have.a.prop', 'selectionStart', 2)
.should('have.a.prop', 'selectionEnd', 2)
.type('{backspace}')
.should('have.value', '-');
});
});
});
2 changes: 2 additions & 0 deletions projects/kit/src/lib/masks/number/number-mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
createRepeatedDecimalSeparatorPreprocessor,
createThousandSeparatorPostprocessor,
createZeroPrecisionPreprocessor,
emptyPostprocessor,
} from './processors';
import {generateMaskExpression, validateDecimalPseudoSeparators} from './utils';

Expand Down Expand Up @@ -152,6 +153,7 @@ export function maskitoNumberOptionsGenerator({
prefix,
postfix,
}),
emptyPostprocessor({prefix, postfix, decimalSeparator}),
],
plugins: [
createLeadingZeroesValidationPlugin({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type {MaskitoPostprocessor} from '@maskito/core';

import {extractAffixes} from '../../../utils';
import {toNumberParts} from '../utils';

/**
* Make textfield empty if there is no integer part and all decimal digits are zeroes.
* @example 0|,00 => Backspace => Empty.
* @example -0|,00 => Backspace => -.
* @example ,42| => Backspace x2 => ,|00 => Backspace => Empty
*/
export function emptyPostprocessor({
prefix,
postfix,
decimalSeparator,
}: {
prefix: string;
postfix: string;
decimalSeparator: string;
}): MaskitoPostprocessor {
return ({value, selection}) => {
const [caretIndex] = selection;
const {cleanValue, extractedPrefix, extractedPostfix} = extractAffixes(value, {
prefix,
postfix,
});
const {minus, integerPart, decimalPart} = toNumberParts(
cleanValue,
decimalSeparator,
);

if (
!integerPart &&
!Number(decimalPart) &&
caretIndex === (minus + extractedPrefix).length
) {
return {
selection,
value: extractedPrefix + minus + extractedPostfix,
};
}

return {value, selection};
};
}
1 change: 1 addition & 0 deletions projects/kit/src/lib/masks/number/processors/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './affixes-filter-preprocessor';
export * from './decimal-zero-padding-postprocessor';
export * from './empty-postprocessor';
export * from './initialization-only-preprocessor';
export * from './leading-zeroes-validation-postprocessor';
export * from './min-max-postprocessor';
Expand Down
1 change: 1 addition & 0 deletions projects/kit/src/lib/masks/number/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './generate-mask-expression';
export * from './parse-number';
export * from './stringify-number-without-exp';
export * from './to-number-parts';
export * from './validate-decimal-pseudo-separators';
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
CHAR_EM_DASH,
CHAR_EN_DASH,
CHAR_HYPHEN,
CHAR_JP_HYPHEN,
CHAR_MINUS,
} from '../../../../constants';
import {toNumberParts} from '../to-number-parts';

describe('toNumberParts', () => {
[',', '.'].forEach(decimalSeparator => {
describe(`decimalSeparator = ${decimalSeparator}`, () => {
it('empty string => empty parts', () => {
expect(toNumberParts('', decimalSeparator)).toEqual({
minus: '',
integerPart: '',
decimalPart: '',
});
});

it(`123${decimalSeparator}45 => {minus: "", integerPart: "123", decimalPart: "45"}`, () => {
expect(
toNumberParts(`123${decimalSeparator}45`, decimalSeparator),
).toEqual({
minus: '',
integerPart: '123',
decimalPart: '45',
});
});

it(`-123${decimalSeparator}45 => {minus: "-", integerPart: "123", decimalPart: "45"}`, () => {
expect(
toNumberParts(`-123${decimalSeparator}45`, decimalSeparator),
).toEqual({
minus: '-',
integerPart: '123',
decimalPart: '45',
});
});

it('123 => {minus: "", integerPart: "123", decimalPart: ""}', () => {
expect(toNumberParts('123', decimalSeparator)).toEqual({
minus: '',
integerPart: '123',
decimalPart: '',
});
});

it('-123 => {minus: "-", integerPart: "123", decimalPart: ""}', () => {
expect(toNumberParts('-123', decimalSeparator)).toEqual({
minus: '-',
integerPart: '123',
decimalPart: '',
});
});

it(`${decimalSeparator}45 => {minus: "", integerPart: "", decimalPart: "45"}`, () => {
expect(toNumberParts(`${decimalSeparator}45`, decimalSeparator)).toEqual({
minus: '',
integerPart: '',
decimalPart: '45',
});
});

it(`-${decimalSeparator}45 => {minus: "-", integerPart: "", decimalPart: "45"}`, () => {
expect(toNumberParts(`-${decimalSeparator}45`, decimalSeparator)).toEqual(
{
minus: '-',
integerPart: '',
decimalPart: '45',
},
);
});

it('- => {minus: "-", integerPart: "", decimalPart: ""}', () => {
expect(toNumberParts('-', decimalSeparator)).toEqual({
minus: '-',
integerPart: '',
decimalPart: '',
});
});
});
});

it('different minus signs', () => {
[CHAR_MINUS, CHAR_HYPHEN, CHAR_EN_DASH, CHAR_EM_DASH, CHAR_JP_HYPHEN].forEach(
minus => {
expect(toNumberParts(`${minus}123.45`, '.')).toEqual({
minus,
integerPart: '123',
decimalPart: '45',
});
},
);
});
});
12 changes: 12 additions & 0 deletions projects/kit/src/lib/masks/number/utils/to-number-parts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const EXTRACT_MINUS_RE = /(\D)?(.*)/;

export function toNumberParts(
value: string,
decimalSeparator: string,
): {minus: string; integerPart: string; decimalPart: string} {
const [integerWithMinus = '', decimalPart = ''] = value.split(decimalSeparator);
const [, minus = '', integerPart = ''] =
integerWithMinus.match(EXTRACT_MINUS_RE) || [];

return {minus, integerPart, decimalPart};
}

0 comments on commit d72f225

Please sign in to comment.