@transferwise/components 0.0.0-experimental-89ae24f → 0.0.0-experimental-c42d7d6
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/build/i18n/en.json +2 -0
- package/build/i18n/en.json.js +2 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +2 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -0
- package/build/index.mjs.map +1 -1
- package/build/main.css +58 -0
- package/build/moneyInputField/AmountInput.js +281 -0
- package/build/moneyInputField/AmountInput.js.map +1 -0
- package/build/moneyInputField/AmountInput.mjs +279 -0
- package/build/moneyInputField/AmountInput.mjs.map +1 -0
- package/build/moneyInputField/AnimatedNumber.js +50 -0
- package/build/moneyInputField/AnimatedNumber.js.map +1 -0
- package/build/moneyInputField/AnimatedNumber.mjs +48 -0
- package/build/moneyInputField/AnimatedNumber.mjs.map +1 -0
- package/build/moneyInputField/Chevron.js +33 -0
- package/build/moneyInputField/Chevron.js.map +1 -0
- package/build/moneyInputField/Chevron.mjs +31 -0
- package/build/moneyInputField/Chevron.mjs.map +1 -0
- package/build/moneyInputField/CurrencySelector.js +160 -0
- package/build/moneyInputField/CurrencySelector.js.map +1 -0
- package/build/moneyInputField/CurrencySelector.mjs +157 -0
- package/build/moneyInputField/CurrencySelector.mjs.map +1 -0
- package/build/moneyInputField/MoneyInputField.js +113 -0
- package/build/moneyInputField/MoneyInputField.js.map +1 -0
- package/build/moneyInputField/MoneyInputField.messages.js +17 -0
- package/build/moneyInputField/MoneyInputField.messages.js.map +1 -0
- package/build/moneyInputField/MoneyInputField.messages.mjs +13 -0
- package/build/moneyInputField/MoneyInputField.messages.mjs.map +1 -0
- package/build/moneyInputField/MoneyInputField.mjs +109 -0
- package/build/moneyInputField/MoneyInputField.mjs.map +1 -0
- package/build/moneyInputField/useFocus.js +37 -0
- package/build/moneyInputField/useFocus.js.map +1 -0
- package/build/moneyInputField/useFocus.mjs +35 -0
- package/build/moneyInputField/useFocus.mjs.map +1 -0
- package/build/moneyInputField/useInputStyle.js +71 -0
- package/build/moneyInputField/useInputStyle.js.map +1 -0
- package/build/moneyInputField/useInputStyle.mjs +69 -0
- package/build/moneyInputField/useInputStyle.mjs.map +1 -0
- package/build/moneyInputField/utils.js +87 -0
- package/build/moneyInputField/utils.js.map +1 -0
- package/build/moneyInputField/utils.mjs +78 -0
- package/build/moneyInputField/utils.mjs.map +1 -0
- package/build/styles/main.css +58 -0
- package/build/styles/moneyInputField/AmountInput.css +32 -0
- package/build/styles/moneyInputField/Chevron.css +12 -0
- package/build/styles/moneyInputField/CurrencySelector.css +6 -0
- package/build/styles/moneyInputField/MoneyInputField.css +58 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/moneyInputField/AmountInput.d.ts +13 -0
- package/build/types/moneyInputField/AmountInput.d.ts.map +1 -0
- package/build/types/moneyInputField/AnimatedNumber.d.ts +9 -0
- package/build/types/moneyInputField/AnimatedNumber.d.ts.map +1 -0
- package/build/types/moneyInputField/Chevron.d.ts +6 -0
- package/build/types/moneyInputField/Chevron.d.ts.map +1 -0
- package/build/types/moneyInputField/CurrencySelector.d.ts +30 -0
- package/build/types/moneyInputField/CurrencySelector.d.ts.map +1 -0
- package/build/types/moneyInputField/MoneyInputField.d.ts +30 -0
- package/build/types/moneyInputField/MoneyInputField.d.ts.map +1 -0
- package/build/types/moneyInputField/MoneyInputField.messages.d.ts +12 -0
- package/build/types/moneyInputField/MoneyInputField.messages.d.ts.map +1 -0
- package/build/types/moneyInputField/index.d.ts +3 -0
- package/build/types/moneyInputField/index.d.ts.map +1 -0
- package/build/types/moneyInputField/useFocus.d.ts +7 -0
- package/build/types/moneyInputField/useFocus.d.ts.map +1 -0
- package/build/types/moneyInputField/useInputStyle.d.ts +10 -0
- package/build/types/moneyInputField/useInputStyle.d.ts.map +1 -0
- package/build/types/moneyInputField/useSelectionRange.d.ts +10 -0
- package/build/types/moneyInputField/useSelectionRange.d.ts.map +1 -0
- package/build/types/moneyInputField/utils.d.ts +22 -0
- package/build/types/moneyInputField/utils.d.ts.map +1 -0
- package/build/types/test-utils/index.d.ts +4 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +9 -2
- package/src/i18n/en.json +2 -0
- package/src/index.ts +2 -0
- package/src/main.css +58 -0
- package/src/main.less +1 -0
- package/src/moneyInputField/AmountInput.css +32 -0
- package/src/moneyInputField/AmountInput.less +43 -0
- package/src/moneyInputField/AmountInput.tsx +353 -0
- package/src/moneyInputField/AnimatedNumber.tsx +40 -0
- package/src/moneyInputField/Chevron.css +12 -0
- package/src/moneyInputField/Chevron.less +13 -0
- package/src/moneyInputField/Chevron.tsx +35 -0
- package/src/moneyInputField/CurrencySelector.css +6 -0
- package/src/moneyInputField/CurrencySelector.less +7 -0
- package/src/moneyInputField/CurrencySelector.tsx +218 -0
- package/src/moneyInputField/MoneyInputField.css +58 -0
- package/src/moneyInputField/MoneyInputField.less +13 -0
- package/src/moneyInputField/MoneyInputField.messages.ts +13 -0
- package/src/moneyInputField/MoneyInputField.story.tsx +188 -0
- package/src/moneyInputField/MoneyInputField.tsx +124 -0
- package/src/moneyInputField/index.ts +2 -0
- package/src/moneyInputField/useFocus.ts +35 -0
- package/src/moneyInputField/useInputStyle.ts +85 -0
- package/src/moneyInputField/useSelectionRange.ts +23 -0
- package/src/moneyInputField/utils.spec.ts +114 -0
- package/src/moneyInputField/utils.ts +116 -0
- package/src/ssr.spec.tsx +1 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { formatAmount } from '@transferwise/formatting';
|
|
2
|
+
import type { KeyboardEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
export const getDecimalSeparator = (currency: string, locale: string): string | null => {
|
|
5
|
+
return formatAmount(1.1, currency, locale).replace(/\p{Number}/gu, '');
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getGroupSeparator = (currency: string, locale: string): string | null => {
|
|
9
|
+
return formatAmount(10000000, currency, locale).replace(/\p{Number}/gu, '')[0];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const getDecimalCount = (currency: string, locale: string): number => {
|
|
13
|
+
const decimalSeparator = getDecimalSeparator(currency, locale);
|
|
14
|
+
if (!decimalSeparator) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const parts = formatAmount(1.1, currency, locale).split(decimalSeparator);
|
|
18
|
+
return parts.length === 2 ? parts[1].length : 0;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getEnteredDecimalsCount = (value: string, decimalSeparator: string) => {
|
|
22
|
+
return value.split(decimalSeparator)[1]?.length ?? 0;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const getUnformattedNumber = ({
|
|
26
|
+
value: formattedValue,
|
|
27
|
+
currency,
|
|
28
|
+
locale,
|
|
29
|
+
}: {
|
|
30
|
+
value: string;
|
|
31
|
+
currency: string;
|
|
32
|
+
locale: string;
|
|
33
|
+
}): number | null => {
|
|
34
|
+
const groupSeparator = getGroupSeparator(currency, locale);
|
|
35
|
+
const decimalSeparator = getDecimalSeparator(currency, locale);
|
|
36
|
+
if (!formattedValue) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// parseFloat can't handle thousands separators
|
|
41
|
+
const withoutGroupSeparator = groupSeparator
|
|
42
|
+
? formattedValue.replace(/ /gu, '').replace(new RegExp(`\\${groupSeparator}`, 'g'), '')
|
|
43
|
+
: formattedValue;
|
|
44
|
+
|
|
45
|
+
// parseFloat can only handle . as decimal separator
|
|
46
|
+
const withNormalisedDecimalSeparator = decimalSeparator
|
|
47
|
+
? withoutGroupSeparator.replace(decimalSeparator, '.')
|
|
48
|
+
: withoutGroupSeparator;
|
|
49
|
+
|
|
50
|
+
const parsedValue = Number.parseFloat(withNormalisedDecimalSeparator);
|
|
51
|
+
return parsedValue;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const getFormattedString = ({
|
|
55
|
+
value: unformattedValue,
|
|
56
|
+
currency,
|
|
57
|
+
locale,
|
|
58
|
+
alwaysShowDecimals = false,
|
|
59
|
+
}: {
|
|
60
|
+
value: number;
|
|
61
|
+
currency: string;
|
|
62
|
+
locale: string;
|
|
63
|
+
alwaysShowDecimals?: boolean;
|
|
64
|
+
}): string => {
|
|
65
|
+
const decimalSeparator = getDecimalSeparator(currency, locale);
|
|
66
|
+
// formatAmount rounds extra decimals, so 1.999 will become 2. Instead we will manually strip extra decimals so that it becomes 1.99 after formatting
|
|
67
|
+
const decimalCount = getDecimalCount(currency, locale);
|
|
68
|
+
const unformattedString = unformattedValue.toString();
|
|
69
|
+
|
|
70
|
+
const [integerPart, decimalPart] = decimalSeparator
|
|
71
|
+
? unformattedString.split(decimalSeparator)
|
|
72
|
+
: [unformattedString, undefined];
|
|
73
|
+
|
|
74
|
+
const formattedDecimalPart = decimalPart ? decimalPart.slice(0, decimalCount) : '';
|
|
75
|
+
|
|
76
|
+
const sanitisedUnformattedValue = Number.parseFloat(`${integerPart}.${formattedDecimalPart}`);
|
|
77
|
+
|
|
78
|
+
return formatAmount(sanitisedUnformattedValue, currency, locale, {
|
|
79
|
+
alwaysShowDecimals,
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const isInputPossiblyOverflowing = ({
|
|
84
|
+
ref,
|
|
85
|
+
value,
|
|
86
|
+
}: {
|
|
87
|
+
ref: React.RefObject<HTMLInputElement>;
|
|
88
|
+
value: string;
|
|
89
|
+
}) => {
|
|
90
|
+
const textLength = value.length;
|
|
91
|
+
const inputWidth = ref.current?.clientWidth;
|
|
92
|
+
if (!inputWidth || !textLength) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const maxCharactersWithoutOverflow = Math.floor(inputWidth / 19);
|
|
97
|
+
return textLength > maxCharactersWithoutOverflow;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const allowedInputKeys = new Set([
|
|
101
|
+
'Backspace',
|
|
102
|
+
'Delete',
|
|
103
|
+
',',
|
|
104
|
+
'.',
|
|
105
|
+
'ArrowLeft',
|
|
106
|
+
'ArrowRight',
|
|
107
|
+
'Enter',
|
|
108
|
+
'Tab',
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
export const isAllowedInputKey = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
112
|
+
const { metaKey, key, ctrlKey } = e;
|
|
113
|
+
const isNumberKey = !Number.isNaN(Number.parseInt(key, 10));
|
|
114
|
+
|
|
115
|
+
return isNumberKey || metaKey || ctrlKey || allowedInputKeys.has(key);
|
|
116
|
+
};
|
package/src/ssr.spec.tsx
CHANGED
|
@@ -92,6 +92,7 @@ describe('Server side rendering', () => {
|
|
|
92
92
|
// stick all possible properties we might need to render all components in here
|
|
93
93
|
const allProps: Record<string, unknown> = {
|
|
94
94
|
currencies: [],
|
|
95
|
+
currencySelector: { options: [] },
|
|
95
96
|
steps: [],
|
|
96
97
|
stepper: {
|
|
97
98
|
steps: [],
|