@transferwise/comparison-components 22.1.3 → 22.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -2
- package/dist/es/{ComparisonTableHeroContainer-d9ad65c4.js → ComparisonTableHeroContainer-de132861.js} +2 -2
- package/dist/es/{ComparisonTableHeroContainer-d9ad65c4.js.map → ComparisonTableHeroContainer-de132861.js.map} +1 -1
- package/dist/es/{ErrorTemplate-7db673bd.js → ErrorTemplate-4cd72347.js} +2 -2
- package/dist/es/{ErrorTemplate-7db673bd.js.map → ErrorTemplate-4cd72347.js.map} +1 -1
- package/dist/es/{ProviderComparisonTable-ad9f0690.js → ProviderComparisonTable-99cc4186.js} +2 -2
- package/dist/es/{ProviderComparisonTable-ad9f0690.js.map → ProviderComparisonTable-99cc4186.js.map} +1 -1
- package/dist/es/{ReceiveAmount-4ca0b7e8.js → ReceiveAmount-504a3f01.js} +2 -2
- package/dist/es/{ReceiveAmount-4ca0b7e8.js.map → ReceiveAmount-504a3f01.js.map} +1 -1
- package/dist/es/TravelMoney-b9c1a100.js +2 -0
- package/dist/es/{TravelMoney-984ec2de.js.map → TravelMoney-b9c1a100.js.map} +1 -1
- package/dist/es/comparison/index.js +1 -1
- package/dist/es/comparison-table/index.js +1 -1
- package/dist/es/comparison-table-hero/index.js +1 -1
- package/dist/es/{index-2651b4fb.js → index-12e593f4.js} +2 -2
- package/dist/es/{index-2651b4fb.js.map → index-12e593f4.js.map} +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/parseAmount-b0a195e6.js +2 -0
- package/dist/es/{useDebounce-05bd2742.js.map → parseAmount-b0a195e6.js.map} +1 -1
- package/dist/es/provider-comparison-table/index.js +1 -1
- package/dist/es/provider-comparison-widget/index.js +1 -1
- package/dist/es/provider-comparison-widget/index.js.map +1 -1
- package/dist/es/travel-money/index.js +1 -1
- package/dist/umd/comparison-components.css +1 -1
- package/dist/umd/comparison-components.js +7 -7
- package/dist/umd/comparison-components.js.map +1 -1
- package/dist/umd/provider-comparison-widget/provider-comparison-widget.js +6 -6
- package/dist/umd/provider-comparison-widget/provider-comparison-widget.js.map +1 -1
- package/dist/umd/travel-money/travel-money.js +6 -6
- package/dist/umd/travel-money/travel-money.js.map +1 -1
- package/package.json +1 -1
- package/src/common/parseAmount/index.js +1 -0
- package/src/common/parseAmount/parseAmount.spec.ts +36 -0
- package/src/common/parseAmount/parseAmount.ts +81 -0
- package/src/provider-comparison-widget/__test__/AmountInput.spec.jsx +6 -7
- package/src/provider-comparison-widget/components/AmountInput.jsx +1 -1
- package/src/travel-money/components/AmountInput.jsx +1 -1
- package/dist/es/TravelMoney-984ec2de.js +0 -2
- package/dist/es/useDebounce-05bd2742.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/comparison-components",
|
|
3
|
-
"version": "22.1.
|
|
3
|
+
"version": "22.1.4",
|
|
4
4
|
"description": "Display a comparison table of providers given a route and amount.",
|
|
5
5
|
"homepage": "https://wise.com/gb/compare/",
|
|
6
6
|
"main": "dist/umd/comparison-components.js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseAmount as default } from './parseAmount';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { parseAmount } from './parseAmount';
|
|
2
|
+
|
|
3
|
+
describe('Number formatting', () => {
|
|
4
|
+
it('parses localized numbers', () => {
|
|
5
|
+
[
|
|
6
|
+
['1234.56', 'en-GB'],
|
|
7
|
+
['1,23,4.56', 'en-US'],
|
|
8
|
+
].forEach(([number, locale]) => {
|
|
9
|
+
expect(parseAmount(number, 'gbp', locale)).toBe(1234.56);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('parses numbers with invalid locale', () => {
|
|
14
|
+
expect(parseAmount('123.45', 'gbp', '12345de_DE')).toBe(123.45);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('parses negative numbers into positive ones', () => {
|
|
18
|
+
expect(parseAmount('-123.45', 'gbp', 'en-GB')).toBe(123.45);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it.each([
|
|
22
|
+
['0---9(s.t.r!@#$%^&*()_+^[]{};’,<>?', 9],
|
|
23
|
+
['$12.341', 12.34],
|
|
24
|
+
['$12.347', 12.35],
|
|
25
|
+
['.asd121', 0.12],
|
|
26
|
+
['.asd129', 0.13],
|
|
27
|
+
[',asd129', 129],
|
|
28
|
+
['123.123.123', 123.12],
|
|
29
|
+
['asda', NaN],
|
|
30
|
+
])(
|
|
31
|
+
"parses strings by removing the non-numerical characters; case: '%s', expected: '%s'",
|
|
32
|
+
(testValue, expectedValue) => {
|
|
33
|
+
expect(parseAmount(testValue, 'gbp', 'en-GB')).toBe(expectedValue);
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// TODO: This is a dup of https://github.com/transferwise/neptune-web/blob/main/packages/components/src/moneyInput/currencyFormatting.js
|
|
2
|
+
// It's not exported out of neptune-web correctly and cannot get it working with Jest.
|
|
3
|
+
|
|
4
|
+
const currencyDecimals: Record<string, number> = {
|
|
5
|
+
BIF: 0,
|
|
6
|
+
BYR: 0,
|
|
7
|
+
CLP: 0,
|
|
8
|
+
DJF: 0,
|
|
9
|
+
GNF: 0,
|
|
10
|
+
JPY: 0,
|
|
11
|
+
KMF: 0,
|
|
12
|
+
KRW: 0,
|
|
13
|
+
MGA: 0,
|
|
14
|
+
PYG: 0,
|
|
15
|
+
RWF: 0,
|
|
16
|
+
VND: 0,
|
|
17
|
+
VUV: 0,
|
|
18
|
+
XAF: 0,
|
|
19
|
+
XOF: 0,
|
|
20
|
+
XPF: 0,
|
|
21
|
+
// technically HUF does have decimals, but due to the exchange rate banks
|
|
22
|
+
// do not accept decimal amounts
|
|
23
|
+
HUF: 0,
|
|
24
|
+
|
|
25
|
+
BHD: 3,
|
|
26
|
+
JOD: 3,
|
|
27
|
+
KWD: 3,
|
|
28
|
+
OMR: 3,
|
|
29
|
+
TND: 3,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const DEFAULT_LOCALE = 'en-GB';
|
|
33
|
+
const DEFAULT_CURRENCY_DECIMALS = 2;
|
|
34
|
+
|
|
35
|
+
function isNumberLocaleSupported() {
|
|
36
|
+
const number = 1234;
|
|
37
|
+
const numberString = number.toLocaleString && number.toLocaleString(DEFAULT_LOCALE);
|
|
38
|
+
return numberString === '1,234';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getValidLocale(locale: string) {
|
|
42
|
+
if (!locale) {
|
|
43
|
+
return DEFAULT_LOCALE;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const noUnderscoreLocale = locale.replace(/_/, '-');
|
|
47
|
+
|
|
48
|
+
Intl.NumberFormat(noUnderscoreLocale);
|
|
49
|
+
return noUnderscoreLocale;
|
|
50
|
+
} catch {
|
|
51
|
+
return DEFAULT_LOCALE;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const getCurrencyDecimals = (currency = ''): number => {
|
|
56
|
+
const upperCaseCurrency = currency.toUpperCase();
|
|
57
|
+
if (Object.prototype.hasOwnProperty.call(currencyDecimals, upperCaseCurrency)) {
|
|
58
|
+
return currencyDecimals[upperCaseCurrency];
|
|
59
|
+
}
|
|
60
|
+
return DEFAULT_CURRENCY_DECIMALS;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getDecimalSeparator = (locale: string) => {
|
|
64
|
+
return isNumberLocaleSupported() ? (1.1).toLocaleString(locale)[1] : '.';
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export function parseAmount(number: string, currency: string, locale: string): number {
|
|
68
|
+
const validLocale = getValidLocale(locale);
|
|
69
|
+
|
|
70
|
+
const precision = getCurrencyDecimals(currency);
|
|
71
|
+
const groupSeparator = isNumberLocaleSupported() ? (10000).toLocaleString(validLocale)[2] : ',';
|
|
72
|
+
const decimalSeparator = getDecimalSeparator(validLocale);
|
|
73
|
+
const numberWithStandardDecimalSeparator = (number ? `${number}` : '')
|
|
74
|
+
.replace(new RegExp(`\\${groupSeparator}`, 'g'), '')
|
|
75
|
+
.replace(new RegExp(`\\${decimalSeparator}`, 'g'), '.')
|
|
76
|
+
.replace(/[^0-9.]/g, '');
|
|
77
|
+
const parsedAmount = parseFloat(
|
|
78
|
+
parseFloat(numberWithStandardDecimalSeparator).toFixed(precision),
|
|
79
|
+
);
|
|
80
|
+
return Math.abs(parsedAmount);
|
|
81
|
+
}
|
|
@@ -4,15 +4,14 @@ import { mount } from 'enzyme';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { IntlProvider } from 'react-intl';
|
|
6
6
|
|
|
7
|
+
import * as parseAmount from '../../common/parseAmount';
|
|
7
8
|
import translations from '../assets/translations/translations.json';
|
|
8
9
|
import AmountInput from '../components/AmountInput';
|
|
9
10
|
|
|
10
11
|
jest.mock('@transferwise/formatting', () => ({
|
|
11
12
|
formatAmount: jest.fn(),
|
|
12
13
|
}));
|
|
13
|
-
|
|
14
|
-
parseAmount: jest.fn(),
|
|
15
|
-
}));
|
|
14
|
+
|
|
16
15
|
const mountRenderComponent = (renderProps) =>
|
|
17
16
|
mount(
|
|
18
17
|
<IntlProvider locale="en" messages={translations.en}>
|
|
@@ -24,7 +23,7 @@ const mountRenderComponent = (renderProps) =>
|
|
|
24
23
|
},
|
|
25
24
|
);
|
|
26
25
|
|
|
27
|
-
const
|
|
26
|
+
const parseAmountSpy = jest.spyOn(parseAmount, 'default');
|
|
28
27
|
const currencyFormatting = require('@transferwise/formatting');
|
|
29
28
|
|
|
30
29
|
describe('AmountInput', () => {
|
|
@@ -75,7 +74,7 @@ describe('AmountInput', () => {
|
|
|
75
74
|
children: <AmountInput {...{ ...props, locale: 'en-US' }} />,
|
|
76
75
|
});
|
|
77
76
|
component.update();
|
|
78
|
-
|
|
77
|
+
parseAmountSpy.mockImplementation(parseFloat);
|
|
79
78
|
enterAmount('123.45');
|
|
80
79
|
component.update();
|
|
81
80
|
expect(amountInput().prop('value')).toBe('123.45');
|
|
@@ -94,7 +93,7 @@ describe('AmountInput', () => {
|
|
|
94
93
|
});
|
|
95
94
|
|
|
96
95
|
component.update();
|
|
97
|
-
|
|
96
|
+
parseAmountSpy.mockImplementation((amount, currency, locale) => {
|
|
98
97
|
expect(amount).toBe('500.1234');
|
|
99
98
|
expect(locale).toBe('es-ES');
|
|
100
99
|
expect(currency).toBe('eur');
|
|
@@ -117,7 +116,7 @@ describe('AmountInput', () => {
|
|
|
117
116
|
children: <AmountInput {...{ ...props, onAmountChange }} />,
|
|
118
117
|
});
|
|
119
118
|
component.update();
|
|
120
|
-
|
|
119
|
+
parseAmountSpy.mockImplementation(() => NaN);
|
|
121
120
|
enterAmount('cannot parse this yo');
|
|
122
121
|
expect(onAmountChange).not.toHaveBeenCalled();
|
|
123
122
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { parseAmount } from '@transferwise/components';
|
|
2
1
|
import { formatAmount } from '@transferwise/formatting';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import React, { useState, useEffect } from 'react';
|
|
5
4
|
import { FormattedMessage } from 'react-intl';
|
|
6
5
|
|
|
6
|
+
import parseAmount from '../../common/parseAmount';
|
|
7
7
|
import createClassNamesFromStyles from '../../resources/createClassNamesFromStyles';
|
|
8
8
|
import style from '../ProviderComparisonWidget.module.less';
|
|
9
9
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { parseAmount } from '@transferwise/components';
|
|
2
1
|
import { formatAmount } from '@transferwise/formatting';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import React, { useState, useEffect } from 'react';
|
|
5
4
|
import { FormattedMessage } from 'react-intl';
|
|
6
5
|
|
|
6
|
+
import parseAmount from '../../common/parseAmount';
|
|
7
7
|
import createClassNamesFromStyles from '../../resources/createClassNamesFromStyles';
|
|
8
8
|
import style from '../TravelMoney.module.less';
|
|
9
9
|
|