Skip to content

Commit

Permalink
feat(kit): Number allows to enter full width numbers (#864)
Browse files Browse the repository at this point in the history
  • Loading branch information
rikusen0335 authored Jan 7, 2024
1 parent 6b5704a commit b25db10
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {openNumberPage} from './utils';

describe('Number | Accepts full width numbers used by JP, CN or others', () => {
beforeEach(() => {
openNumberPage('thousandSeparator=_&precision=2');
});

describe('Invalid characters', () => {
it('accepts full width numbers', () => {
cy.get('@input')
.type('1 2 3 4 5')
.should('have.value', '12_345')
.should('have.prop', 'selectionStart', '12_345'.length)
.should('have.prop', 'selectionEnd', '12_345'.length);
});

it('accepts full width characters with minus', () => {
cy.get('@input')
.type('ー123456')
.should('have.value', '−123_456')
.should('have.prop', 'selectionStart', '−123_456'.length)
.should('have.prop', 'selectionEnd', '−123_456'.length);
});

it('rejects full width characters, not numbers', () => {
cy.get('@input')
.type('あいうえお12345こんにちは')
.should('have.value', '12_345')
.should('have.prop', 'selectionStart', '12_345'.length)
.should('have.prop', 'selectionEnd', '12_345'.length);
});
});
});
6 changes: 6 additions & 0 deletions projects/kit/src/lib/constants/unicode-characters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ export const CHAR_HYPHEN = '\u002D';
* Can be used as `−`. Don't confuse with {@link CHAR_HYPHEN}
*/
export const CHAR_MINUS = '\u2212';

/**
* {@link https://symbl.cc/en/30FC/ Katakana-Hiragana Prolonged Sound Mark}
* is used as prolonged sounds in Japanese.
*/
export const CHAR_JP_HYPHEN = '\u30FC';
12 changes: 9 additions & 3 deletions projects/kit/src/lib/masks/number/number-mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CHAR_EM_DASH,
CHAR_EN_DASH,
CHAR_HYPHEN,
CHAR_JP_HYPHEN,
CHAR_MINUS,
CHAR_NO_BREAK_SPACE,
} from '../../constants';
Expand All @@ -18,6 +19,7 @@ import {
} from './plugins';
import {
createDecimalZeroPaddingPostprocessor,
createFullWidthToHalfWidthPreprocessor,
createInitializationOnlyPreprocessor,
createMinMaxPostprocessor,
createNonRemovableCharsDeletionPreprocessor,
Expand Down Expand Up @@ -50,9 +52,12 @@ export function maskitoNumberOptionsGenerator({
prefix?: string;
postfix?: string;
} = {}): Required<MaskitoOptions> {
const pseudoMinuses = [CHAR_HYPHEN, CHAR_EN_DASH, CHAR_EM_DASH].filter(
char => char !== thousandSeparator && char !== decimalSeparator,
);
const pseudoMinuses = [
CHAR_HYPHEN,
CHAR_EN_DASH,
CHAR_EM_DASH,
CHAR_JP_HYPHEN,
].filter(char => char !== thousandSeparator && char !== decimalSeparator);
const validatedDecimalPseudoSeparators = validateDecimalPseudoSeparators({
decimalSeparator,
thousandSeparator,
Expand All @@ -75,6 +80,7 @@ export function maskitoNumberOptionsGenerator({
decimalPseudoSeparators: validatedDecimalPseudoSeparators,
pseudoMinuses,
}),
createFullWidthToHalfWidthPreprocessor(),
createPseudoCharactersPreprocessor(CHAR_MINUS, pseudoMinuses),
createPseudoCharactersPreprocessor(
decimalSeparator,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {MaskitoPreprocessor} from '@maskito/core';

import {toHalfWidthNumber} from '../utils/to-half-width-number';

/**
* Convert full width numbers like 1, 2 to half width numbers 1, 2
*/
export function createFullWidthToHalfWidthPreprocessor(): MaskitoPreprocessor {
return ({elementState, data}) => {
const {value, selection} = elementState;

return {
elementState: {
selection,
value: toHalfWidthNumber(value),
},
data: toHalfWidthNumber(data),
};
};
}
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,4 +1,5 @@
export * from './decimal-zero-padding-postprocessor';
export * from './fullwidth-to-halfwidth-preprocessor';
export * from './initialization-only-preprocessor';
export * from './leading-zeroes-validation-postprocessor';
export * from './min-max-postprocessor';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {toHalfWidthNumber} from '../to-half-width-number';

describe('`toHalfWidthNumber` utility converts full width numbers to half width numbers', () => {
const tests = [
// [full width value, half width value]
['1', '1'],
['2', '2'],
['3', '3'],
['4', '4'],
['5', '5'],
['6', '6'],
['7', '7'],
['8', '8'],
['9', '9'],
] as const;

tests.forEach(([fullWidthValue, halfWidthValue]) => {
it(`${fullWidthValue} => ${halfWidthValue}`, () => {
expect(toHalfWidthNumber(fullWidthValue)).toBe(halfWidthValue);
});
});

it('123456 => 123456', () => {
expect(toHalfWidthNumber('123456')).toBe('123456');
});

it('123456 (full width + half width mix) => 123456', () => {
expect(toHalfWidthNumber('123456')).toBe('123456');
});
});
10 changes: 10 additions & 0 deletions projects/kit/src/lib/masks/number/utils/to-half-width-number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Replace fullwidth numbers with half width number
* @param fullWidthNumber full width number
* @returns processed half width number
*/
export function toHalfWidthNumber(fullWidthNumber: string): string {
return fullWidthNumber.replace(/[0-9]/g, s =>
String.fromCharCode(s.charCodeAt(0) - 0xfee0),
);
}

0 comments on commit b25db10

Please sign in to comment.