-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fa5696c
commit 8ab42e7
Showing
10 changed files
with
362 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import { mask, unmask } from './' | ||
|
||
describe.only('mask', () => { | ||
test('should format 0.01 (number) to R$ 0,01', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: 0.01 }) | ||
expect(result).toEqual('R$ 0,01') | ||
}) | ||
|
||
test('should format 0.1 (number) to R$ 0,10', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: 0.1 }) | ||
expect(result).toEqual('R$ 0,10') | ||
}) | ||
|
||
test('should format 1 (number) to R$ 1,00', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: 1 }) | ||
expect(result).toEqual('R$ 1,00') | ||
}) | ||
|
||
test('should format 1.0 (number) to R$ 1,00', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: 1.0 }) | ||
expect(result).toEqual('R$ 1,00') | ||
}) | ||
|
||
test('should format -0.01 (number) to -R$ 0,01', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: -0.01 }) | ||
expect(result).toEqual('-R$ 0,01') | ||
}) | ||
|
||
test('should format -0.1 (number) to -R$ 0,10', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: -0.1 }) | ||
expect(result).toEqual('-R$ 0,10') | ||
}) | ||
|
||
test('should format -1 (number) to -R$ 1,00', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: -1 }) | ||
expect(result).toEqual('-R$ 1,00') | ||
}) | ||
|
||
test('should format -1.0 (number) to -R$ 1,00', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: -1.0 }) | ||
expect(result).toEqual('-R$ 1,00') | ||
}) | ||
|
||
test('should format 1234567.89 (number) to R$ 1.234.567,89', () => { | ||
const result = mask({ locale: 'pt-BR', currency: 'BRL', value: 1234567.89 }) | ||
expect(result).toEqual('R$ 1.234.567,89') | ||
}) | ||
|
||
test('should format 1234.56 (number) to $1,234.56', () => { | ||
const result = mask({ locale: 'en-US', currency: 'USD', value: 1234.56 }) | ||
expect(result).toEqual('$1,234.56') | ||
}) | ||
|
||
test('should format 1234.56 (number) to 1.234,56 €', () => { | ||
const result = mask({ locale: 'de-DE', currency: 'EUR', value: 1234.56 }) | ||
expect(result).toEqual('1.234,56 €') | ||
}) | ||
|
||
test('should format 1234 (number) to JPY ¥1234', () => { | ||
const result = mask({ locale: 'ja-JP', currency: 'JPY', value: 1234.56 }) | ||
expect(result).toEqual('¥1,235') | ||
}) | ||
}) | ||
|
||
describe.only('unmask', () => { | ||
test('should remove format 0.01 (number) to R$ 0,01', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: 'R$ 0,01', | ||
}) | ||
|
||
expect(result).toEqual(0.01) | ||
}) | ||
|
||
test('should remove format 0.1 (number) to R$ 0,10', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: 'R$ 0,10', | ||
}) | ||
|
||
expect(result).toEqual(0.1) | ||
}) | ||
|
||
test('should remove format 1 (number) to R$ 1,00', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: 'R$ 1,00', | ||
}) | ||
|
||
expect(result).toEqual(1) | ||
}) | ||
|
||
test('should remove format 1.0 (number) to R$ 1,00', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: 'R$ 1,00', | ||
}) | ||
|
||
expect(result).toEqual(1.0) | ||
}) | ||
|
||
test('should remove format -0.01 (number) to -R$ 0,01', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: '-R$ 0,01', | ||
}) | ||
|
||
expect(result).toEqual(-0.01) | ||
}) | ||
|
||
test('should remove format -0.1 (number) to -R$ 0,10', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: '-R$ 0,10', | ||
}) | ||
|
||
expect(result).toEqual(-0.1) | ||
}) | ||
|
||
test('should remove format -1 (number) to -R$ 1,00', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: '-R$ 1,00', | ||
}) | ||
|
||
expect(result).toEqual(-1) | ||
}) | ||
|
||
test('should remove format -1.0 (number) to -R$ 1,00', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: '-R$ 1,00', | ||
}) | ||
|
||
expect(result).toEqual(-1.0) | ||
}) | ||
|
||
test('should remove format 1234567.89 (number) to R$ 1.234.567,89', () => { | ||
const result = unmask({ | ||
locale: 'pt-BR', | ||
currency: 'BRL', | ||
value: 'R$ 1.234.567,89', | ||
}) | ||
|
||
expect(result).toEqual(1234567.89) | ||
}) | ||
|
||
test('should remove format 1234.56 (number) to $1,234.56', () => { | ||
const result = unmask({ | ||
locale: 'en-US', | ||
currency: 'USD', | ||
value: '$1,234.56', | ||
}) | ||
|
||
expect(result).toEqual(1234.56) | ||
}) | ||
|
||
test('should remove format 1234.56 (number) to 1.234,56 €', () => { | ||
const result = unmask({ | ||
locale: 'de-DE', | ||
currency: 'EUR', | ||
value: '1.234,56 €', | ||
}) | ||
|
||
expect(result).toEqual(1234.56) | ||
}) | ||
|
||
test('should remove format 1234 (number) to JPY ¥1234', () => { | ||
const result = unmask({ | ||
locale: 'ja-JP', | ||
currency: 'JPY', | ||
value: '¥1,234', | ||
}) | ||
|
||
expect(result).toEqual(1234) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
interface CurrncyMaskProps { | ||
locale: string | string[] | ||
currency: string | ||
value: number | bigint | ||
} | ||
|
||
export const mask = ({ locale, currency, value }: CurrncyMaskProps): string => { | ||
const { format } = new Intl.NumberFormat(`${locale}`, { | ||
style: 'currency', | ||
currency, | ||
}) | ||
|
||
return format(value) | ||
} | ||
|
||
export const unmask = ({ | ||
locale, | ||
currency, | ||
value, | ||
}: CurrncyMaskProps): number => { | ||
const formatter = new Intl.NumberFormat(locale, { | ||
style: 'currency', | ||
currency, | ||
}) | ||
|
||
const decimalPart = formatter | ||
.formatToParts(1.1) | ||
.find((item) => item.type === 'decimal') | ||
|
||
const decimalSeparator = decimalPart ? decimalPart.value : false | ||
const regex = new RegExp(`[^\-0-9${decimalSeparator}]`, 'g') | ||
const unformatted = `${value}`.replace(regex, '') | ||
|
||
return decimalSeparator && decimalSeparator !== '.' | ||
? parseFloat(unformatted.replace(decimalSeparator, '.')) | ||
: parseFloat(unformatted) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,4 @@ | ||
interface PatternOptions { | ||
// Placeholder option to represent remaining characters to be entered | ||
placeholder?: string | undefined | ||
} | ||
import * as currency from './currency' | ||
|
||
interface RegExpMapProps { | ||
[key: string]: RegExp | ||
} | ||
|
||
const regexMap: RegExpMapProps = { | ||
9: new RegExp(/[0-9]/), | ||
A: new RegExp(/[a-zA-Z]/), | ||
S: new RegExp(/[0-9a-zA-Z]/), | ||
} | ||
|
||
export const unMask = (value: string) => value.replace(/\W/g, '') | ||
|
||
export const masker = ( | ||
value: string, | ||
pattern: string, | ||
options?: PatternOptions | ||
) => { | ||
const patternCharList = pattern.split('') | ||
const unmaskedValue = unMask(String(value)) | ||
const output = [] | ||
|
||
let valueIndex = 0 | ||
|
||
for (let i = 0; i < patternCharList.length; i++) { | ||
const patternChar = pattern[i] | ||
const valueChar = unmaskedValue[valueIndex] | ||
const regex = regexMap[patternChar] | ||
|
||
if (valueChar === patternChar) { | ||
output[i] = valueChar | ||
valueIndex++ | ||
continue | ||
} | ||
|
||
if (!regex) { | ||
output[i] = patternChar | ||
continue | ||
} | ||
|
||
if (valueChar && regex.test(valueChar)) { | ||
output[i] = valueChar | ||
valueIndex++ | ||
continue | ||
} | ||
|
||
if (options?.placeholder) { | ||
output[i] = options.placeholder | ||
continue | ||
} | ||
|
||
if ( | ||
output.length < patternCharList.length && | ||
/\W/.test(output[output.length - 1]) | ||
) { | ||
output.pop() | ||
} | ||
|
||
break | ||
} | ||
|
||
return output.join('') | ||
} | ||
|
||
const multimasker = ( | ||
value: string, | ||
patterns: string[], | ||
options?: PatternOptions | ||
) => | ||
masker( | ||
value, | ||
patterns.reduce( | ||
(memo, pattern) => (value.length <= unMask(memo).length ? memo : pattern), | ||
patterns[0] | ||
), | ||
options | ||
) | ||
|
||
export const mask = ( | ||
value: string, | ||
pattern: string | string[], | ||
options?: PatternOptions | ||
): string => | ||
typeof pattern === 'string' | ||
? masker(value, pattern || '', options) | ||
: multimasker(value, pattern, options) | ||
export * from './masker' | ||
export { currency } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.