@transferwise/components 0.0.0-experimental-85b9dd1 → 0.0.0-experimental-0db2ae7

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.
Files changed (151) hide show
  1. package/build/index.esm.js +335 -234
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +336 -235
  4. package/build/index.js.map +1 -1
  5. package/build/types/common/locale/index.d.ts +43 -26
  6. package/build/types/common/locale/index.d.ts.map +1 -1
  7. package/build/types/common/textFormat/formatWithPattern/formatWithPattern.d.ts +1 -1
  8. package/build/types/common/textFormat/formatWithPattern/formatWithPattern.d.ts.map +1 -1
  9. package/build/types/common/textFormat/getCursorPositionAfterKeystroke/getCursorPositionAfterKeystroke.d.ts +2 -2
  10. package/build/types/common/textFormat/getCursorPositionAfterKeystroke/getCursorPositionAfterKeystroke.d.ts.map +1 -1
  11. package/build/types/common/textFormat/getSymbolsInPatternWithPosition/getSymbolsInPatternWithPosition.d.ts +5 -1
  12. package/build/types/common/textFormat/getSymbolsInPatternWithPosition/getSymbolsInPatternWithPosition.d.ts.map +1 -1
  13. package/build/types/common/textFormat/unformatWithPattern/unformatWithPattern.d.ts +1 -1
  14. package/build/types/common/textFormat/unformatWithPattern/unformatWithPattern.d.ts.map +1 -1
  15. package/build/types/index.d.ts +2 -0
  16. package/build/types/index.d.ts.map +1 -1
  17. package/build/types/inputWithDisplayFormat/InputWithDisplayFormat.d.ts +7 -11
  18. package/build/types/inputWithDisplayFormat/InputWithDisplayFormat.d.ts.map +1 -1
  19. package/build/types/inputWithDisplayFormat/index.d.ts +2 -1
  20. package/build/types/inputWithDisplayFormat/index.d.ts.map +1 -1
  21. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +27 -22
  22. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  23. package/build/types/phoneNumberInput/data/countries.d.ts +10 -5
  24. package/build/types/phoneNumberInput/data/countries.d.ts.map +1 -1
  25. package/build/types/phoneNumberInput/index.d.ts +1 -1
  26. package/build/types/phoneNumberInput/index.d.ts.map +1 -1
  27. package/build/types/phoneNumberInput/utils/cleanNumber/cleanNumber.d.ts +1 -1
  28. package/build/types/phoneNumberInput/utils/cleanNumber/cleanNumber.d.ts.map +1 -1
  29. package/build/types/phoneNumberInput/utils/cleanNumber/index.d.ts +1 -1
  30. package/build/types/phoneNumberInput/utils/cleanNumber/index.d.ts.map +1 -1
  31. package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts +1 -8
  32. package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts.map +1 -1
  33. package/build/types/phoneNumberInput/utils/excludeCountries/index.d.ts +1 -1
  34. package/build/types/phoneNumberInput/utils/excludeCountries/index.d.ts.map +1 -1
  35. package/build/types/phoneNumberInput/utils/explodeNumberModel/index.d.ts +4 -8
  36. package/build/types/phoneNumberInput/utils/explodeNumberModel/index.d.ts.map +1 -1
  37. package/build/types/phoneNumberInput/utils/filterOptionsForQuery/index.d.ts +2 -0
  38. package/build/types/phoneNumberInput/utils/filterOptionsForQuery/index.d.ts.map +1 -0
  39. package/build/types/phoneNumberInput/utils/findCountryByCode/index.d.ts +1 -1
  40. package/build/types/phoneNumberInput/utils/findCountryByCode/index.d.ts.map +1 -1
  41. package/build/types/phoneNumberInput/utils/findCountryByPrefix/index.d.ts +1 -1
  42. package/build/types/phoneNumberInput/utils/findCountryByPrefix/index.d.ts.map +1 -1
  43. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts +1 -2
  44. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts.map +1 -1
  45. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/index.d.ts +1 -1
  46. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/index.d.ts.map +1 -1
  47. package/build/types/phoneNumberInput/utils/index.d.ts +13 -11
  48. package/build/types/phoneNumberInput/utils/index.d.ts.map +1 -1
  49. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/index.d.ts +2 -0
  50. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/index.d.ts.map +1 -0
  51. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.d.ts +3 -0
  52. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.d.ts.map +1 -0
  53. package/build/types/phoneNumberInput/utils/isStringNumeric/index.d.ts +1 -1
  54. package/build/types/phoneNumberInput/utils/isStringNumeric/index.d.ts.map +1 -1
  55. package/build/types/phoneNumberInput/utils/isStringNumeric/isStringNumeric.d.ts +1 -1
  56. package/build/types/phoneNumberInput/utils/isStringNumeric/isStringNumeric.d.ts.map +1 -1
  57. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/index.d.ts +1 -1
  58. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/index.d.ts.map +1 -1
  59. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.d.ts +1 -6
  60. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.d.ts.map +1 -1
  61. package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts +1 -2
  62. package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts.map +1 -1
  63. package/build/types/phoneNumberInput/utils/setDefaultPrefix/index.d.ts +1 -7
  64. package/build/types/phoneNumberInput/utils/setDefaultPrefix/index.d.ts.map +1 -1
  65. package/build/types/phoneNumberInput/utils/sortArrayByProperty/index.d.ts +1 -1
  66. package/build/types/phoneNumberInput/utils/sortArrayByProperty/index.d.ts.map +1 -1
  67. package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts +1 -1
  68. package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts.map +1 -1
  69. package/build/types/textareaWithDisplayFormat/TextareaWithDisplayFormat.d.ts +7 -11
  70. package/build/types/textareaWithDisplayFormat/TextareaWithDisplayFormat.d.ts.map +1 -1
  71. package/build/types/textareaWithDisplayFormat/index.d.ts +2 -1
  72. package/build/types/textareaWithDisplayFormat/index.d.ts.map +1 -1
  73. package/build/types/withDisplayFormat/WithDisplayFormat.d.ts +54 -82
  74. package/build/types/withDisplayFormat/WithDisplayFormat.d.ts.map +1 -1
  75. package/build/types/withDisplayFormat/index.d.ts +2 -1
  76. package/build/types/withDisplayFormat/index.d.ts.map +1 -1
  77. package/package.json +1 -1
  78. package/src/common/locale/index.js +139 -0
  79. package/src/common/locale/{index.spec.ts → index.spec.js} +4 -4
  80. package/src/common/textFormat/formatWithPattern/{formatWithPattern.js → formatWithPattern.ts} +8 -4
  81. package/src/common/textFormat/getCursorPositionAfterKeystroke/{getCursorPositionAfterKeystroke.js → getCursorPositionAfterKeystroke.ts} +8 -8
  82. package/src/common/textFormat/getSymbolsInPatternWithPosition/{getSymbolsInPatternWithPosition.js → getSymbolsInPatternWithPosition.ts} +7 -2
  83. package/src/common/textFormat/unformatWithPattern/{unformatWithPattern.js → unformatWithPattern.ts} +3 -2
  84. package/src/index.ts +2 -0
  85. package/src/inputWithDisplayFormat/InputWithDisplayFormat.tsx +10 -0
  86. package/src/inputWithDisplayFormat/index.ts +2 -0
  87. package/src/phoneNumberInput/PhoneNumberInput.js +210 -0
  88. package/src/phoneNumberInput/PhoneNumberInput.spec.js +22 -18
  89. package/src/phoneNumberInput/data/{countries.ts → countries.js} +1 -9
  90. package/src/phoneNumberInput/data/countries.spec.js +12 -0
  91. package/src/phoneNumberInput/utils/cleanNumber/cleanNumber.js +4 -0
  92. package/src/phoneNumberInput/utils/excludeCountries/{excludeCountries.ts → excludeCountries.js} +5 -6
  93. package/src/phoneNumberInput/utils/excludeCountries/{excludeCountries.spec.ts → excludeCountries.spec.js} +1 -1
  94. package/src/phoneNumberInput/utils/explodeNumberModel/{explodeNumberModel.spec.ts → explodeNumberModel.spec.js} +1 -1
  95. package/src/phoneNumberInput/utils/explodeNumberModel/index.js +27 -0
  96. package/src/phoneNumberInput/utils/filterOptionsForQuery/filterOptionsForQuery.spec.js +36 -0
  97. package/src/phoneNumberInput/utils/filterOptionsForQuery/index.js +11 -0
  98. package/src/phoneNumberInput/utils/findCountryByCode/{findCountryByCode.spec.ts → findCountryByCode.spec.js} +1 -0
  99. package/src/phoneNumberInput/utils/findCountryByCode/index.js +10 -0
  100. package/src/phoneNumberInput/utils/findCountryByPrefix/index.js +11 -0
  101. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.js +26 -0
  102. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.spec.js +67 -0
  103. package/src/phoneNumberInput/utils/{index.ts → index.js} +2 -0
  104. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/index.js +1 -0
  105. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.js +25 -0
  106. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.spec.js +66 -0
  107. package/src/phoneNumberInput/utils/isStringNumeric/isStringNumeric.js +1 -0
  108. package/src/phoneNumberInput/utils/isStringNumeric/{isStringNumeric.spec.ts → isStringNumeric.spec.js} +1 -0
  109. package/src/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.js +10 -0
  110. package/src/phoneNumberInput/utils/isValidPhoneNumber/{isValidPhoneNumber.spec.ts → isValidPhoneNumber.spec.js} +1 -1
  111. package/src/phoneNumberInput/utils/longestMatchingPrefix/index.js +2 -0
  112. package/src/phoneNumberInput/utils/setDefaultPrefix/index.js +25 -0
  113. package/src/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.js +3 -0
  114. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.spec.js +3 -1
  115. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +32 -0
  116. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.tsx +13 -0
  117. package/src/textareaWithDisplayFormat/index.ts +2 -0
  118. package/src/withDisplayFormat/WithDisplayFormat.spec.js +1 -1
  119. package/src/withDisplayFormat/{WithDisplayFormat.js → WithDisplayFormat.tsx} +127 -107
  120. package/src/withDisplayFormat/index.ts +2 -0
  121. package/src/common/locale/index.ts +0 -96
  122. package/src/inputWithDisplayFormat/InputWithDisplayFormat.js +0 -14
  123. package/src/inputWithDisplayFormat/index.js +0 -1
  124. package/src/phoneNumberInput/PhoneNumberInput.tsx +0 -193
  125. package/src/phoneNumberInput/utils/cleanNumber/cleanNumber.ts +0 -3
  126. package/src/phoneNumberInput/utils/explodeNumberModel/index.ts +0 -24
  127. package/src/phoneNumberInput/utils/findCountryByCode/index.ts +0 -12
  128. package/src/phoneNumberInput/utils/findCountryByPrefix/index.ts +0 -12
  129. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.spec.ts +0 -102
  130. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.ts +0 -12
  131. package/src/phoneNumberInput/utils/isStringNumeric/isStringNumeric.ts +0 -1
  132. package/src/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.ts +0 -7
  133. package/src/phoneNumberInput/utils/longestMatchingPrefix/index.ts +0 -4
  134. package/src/phoneNumberInput/utils/setDefaultPrefix/index.ts +0 -20
  135. package/src/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.ts +0 -6
  136. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.js +0 -14
  137. package/src/textareaWithDisplayFormat/index.js +0 -1
  138. package/src/withDisplayFormat/index.js +0 -1
  139. /package/src/phoneNumberInput/{PhoneNumberInput.story.tsx → PhoneNumberInput.story.js} +0 -0
  140. /package/src/phoneNumberInput/{index.ts → index.js} +0 -0
  141. /package/src/phoneNumberInput/utils/cleanNumber/{cleanNumber.spec.ts → cleanNumber.spec.js} +0 -0
  142. /package/src/phoneNumberInput/utils/cleanNumber/{index.ts → index.js} +0 -0
  143. /package/src/phoneNumberInput/utils/excludeCountries/{index.ts → index.js} +0 -0
  144. /package/src/phoneNumberInput/utils/findCountryByPrefix/{findCountryByPrefix.spec.ts → findCountryByPrefix.spec.js} +0 -0
  145. /package/src/phoneNumberInput/utils/groupCountriesByPrefix/{index.ts → index.js} +0 -0
  146. /package/src/phoneNumberInput/utils/isStringNumeric/{index.ts → index.js} +0 -0
  147. /package/src/phoneNumberInput/utils/isValidPhoneNumber/{index.ts → index.js} +0 -0
  148. /package/src/phoneNumberInput/utils/longestMatchingPrefix/{longestMatchingPrefix.spec.ts → longestMatchingPrefix.spec.js} +0 -0
  149. /package/src/phoneNumberInput/utils/setDefaultPrefix/{setDefaultPrefix.spec.ts → setDefaultPrefix.spec.js} +0 -0
  150. /package/src/phoneNumberInput/utils/sortArrayByProperty/{index.ts → index.js} +0 -0
  151. /package/src/phoneNumberInput/utils/sortArrayByProperty/{sortArrayByProperty.spec.ts → sortArrayByProperty.spec.js} +0 -0
@@ -1,96 +0,0 @@
1
- import { Direction } from '..';
2
-
3
- export const DEFAULT_LANG = 'en';
4
- export const DEFAULT_LOCALE = 'en-GB';
5
-
6
- /**
7
- * Languages written right-to-left.
8
- */
9
- export const RTL_LANGUAGES = ['ar', 'he'];
10
-
11
- /**
12
- * @deprecated The source of truth for supported languages lives in Crab.
13
- */
14
- export const SUPPORTED_LANGUAGES = [
15
- DEFAULT_LANG,
16
- 'de',
17
- 'es',
18
- 'fr',
19
- 'hu',
20
- 'id',
21
- 'it',
22
- 'ja',
23
- 'pl',
24
- 'pt',
25
- 'ro',
26
- 'ru',
27
- 'th',
28
- 'tr',
29
- 'uk',
30
- 'zh',
31
- ];
32
-
33
- /**
34
- * Verifies and adjusts locale, replacing `_` with `-`.
35
- *
36
- * @param locale `es`, `es_ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
37
- * @returns `null` if locale is unrecognized by `Intl.Locale`.
38
- */
39
- export function adjustLocale(locale: string) {
40
- const localeTrimmed = locale?.trim();
41
- if (localeTrimmed) {
42
- try {
43
- return new Intl.Locale(localeTrimmed.replace('_', '-')).baseName;
44
- } catch (error) {
45
- // eslint-disable-next-line no-console
46
- console.error(error);
47
- }
48
- }
49
- return null;
50
- }
51
-
52
- /**
53
- * Provides corresponding lang (iso2) for provided locale.
54
- *
55
- * @deprecated The use of this function almost always breaks language variants
56
- * e.g. Simplified and Traditional Chinese.
57
- * There should be no use case for this function.
58
- * To select the correct translations from a translations object, pass the
59
- * locale directly into Crab's getLocalisedMessages.
60
- * @param locale `es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
61
- * @returns Two-letter ISO 639-1 language code, falling back to `null` if locale is invalid or language is unsupported.
62
- */
63
- export function getLangFromLocale(locale: string) {
64
- const adjustedLocale = adjustLocale(locale);
65
- if (adjustedLocale != null) {
66
- const { language } = new Intl.Locale(adjustedLocale);
67
- if (SUPPORTED_LANGUAGES.includes(language)) {
68
- return language;
69
- }
70
- }
71
- return null;
72
- }
73
-
74
- /**
75
- * Provides corresponding country code (iso2) for locales code with explicit region value.
76
- *
77
- * @param locale `es-ES`, `en-GB`, `ja-JP`, etc.
78
- * @returns `null` if the locale is invalid or the region can‘t be identified.
79
- */
80
- export function getCountryFromLocale(locale: string) {
81
- const adjustedLocale = adjustLocale(locale);
82
- return adjustedLocale != null ? new Intl.Locale(adjustedLocale).region ?? null : null;
83
- }
84
-
85
- /**
86
- * Provides the layout direction for a given locale.
87
- *
88
- * @param locale `es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
89
- * @returns The layout direction based on the locale, falling back to `Direction.LTR` if the locale is invalid or unsupported.
90
- */
91
- export function getDirectionFromLocale(locale: string) {
92
- const adjustedLocale = adjustLocale(locale);
93
- return adjustedLocale != null && RTL_LANGUAGES.includes(new Intl.Locale(adjustedLocale).language)
94
- ? Direction.RTL
95
- : Direction.LTR;
96
- }
@@ -1,14 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- import WithDisplayFormat from '../withDisplayFormat';
4
-
5
- const InputWithDisplayFormat = (props) => (
6
- <WithDisplayFormat {...props} render={(renderProps) => <input {...renderProps} />} />
7
- );
8
-
9
- InputWithDisplayFormat.propTypes = {
10
- displayPattern: PropTypes.string.isRequired,
11
- onChange: PropTypes.func.isRequired,
12
- };
13
-
14
- export default InputWithDisplayFormat;
@@ -1 +0,0 @@
1
- export { default } from './InputWithDisplayFormat';
@@ -1,193 +0,0 @@
1
- import { useState, useEffect, useMemo } from 'react';
2
- import { useIntl } from 'react-intl';
3
-
4
- import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
5
- import { SelectInput, SelectInputOptionContent, SelectInputProps } from '../inputs/SelectInput';
6
-
7
- import countries from './data/countries';
8
- import {
9
- explodeNumberModel,
10
- isValidPhoneNumber,
11
- cleanNumber,
12
- setDefaultPrefix,
13
- sortArrayByProperty,
14
- groupCountriesByPrefix,
15
- excludeCountries,
16
- findCountryByPrefix,
17
- } from './utils';
18
- import { PhoneNumber } from './utils/explodeNumberModel';
19
-
20
- const ALLOWED_PHONE_CHARS = /^$|^[\d-\s]+$/;
21
-
22
- export interface PhoneNumberInputProps {
23
- id?: string;
24
- required?: boolean;
25
- disabled?: boolean;
26
- initialValue?: string;
27
- onChange: (value: string | null, prefix: string) => void;
28
- onFocus?: React.FocusEventHandler<HTMLInputElement>;
29
- onBlur?: React.FocusEventHandler<HTMLInputElement>;
30
- countryCode?: string;
31
- searchPlaceholder?: string;
32
- size?: SizeSmall | SizeMedium | SizeLarge;
33
- placeholder?: string;
34
- selectProps?: Partial<SelectInputProps<string | null>>;
35
- /** List of iso3 codes of countries to remove from the list */
36
- disabledCountries?: string[];
37
- }
38
-
39
- const defaultSelectProps = {} satisfies PhoneNumberInputProps['selectProps'];
40
- const defaultDisabledCountries = [] satisfies PhoneNumberInputProps['disabledCountries'];
41
-
42
- const PhoneNumberInput = ({
43
- id,
44
- required,
45
- disabled,
46
- initialValue,
47
- onChange,
48
- onFocus,
49
- onBlur,
50
- countryCode,
51
- searchPlaceholder = 'Prefix',
52
- size = Size.MEDIUM,
53
- placeholder,
54
- selectProps = defaultSelectProps,
55
- disabledCountries = defaultDisabledCountries,
56
- }: PhoneNumberInputProps) => {
57
- const { locale } = useIntl();
58
-
59
- const [internalValue, setInternalValue] = useState<PhoneNumber>(() => {
60
- const cleanValue = initialValue ? cleanNumber(initialValue) : null;
61
-
62
- if (!cleanValue || !isValidPhoneNumber(cleanValue)) {
63
- return {
64
- prefix: setDefaultPrefix(locale, countryCode),
65
- suffix: '',
66
- };
67
- }
68
-
69
- return explodeNumberModel(cleanValue);
70
- });
71
- const [broadcastedValue, setBroadcastedValue] = useState<PhoneNumber | null>(null);
72
-
73
- const countriesByPrefix = useMemo(
74
- () =>
75
- groupCountriesByPrefix(
76
- sortArrayByProperty(excludeCountries(countries, disabledCountries), 'iso3'),
77
- ),
78
- [disabledCountries],
79
- );
80
-
81
- const onSuffixChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
82
- const suffix = event.target.value;
83
- if (ALLOWED_PHONE_CHARS.test(suffix)) {
84
- setInternalValue((prev) => ({ ...prev, suffix }));
85
- }
86
- };
87
-
88
- const onPaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {
89
- if (!event.nativeEvent.clipboardData) {
90
- return;
91
- }
92
-
93
- const pastedValue = (event.nativeEvent.clipboardData.getData('text/plain') || '').replace(
94
- /(\s|-)+/g,
95
- '',
96
- );
97
- const pastedNumber = explodeNumberModel(pastedValue);
98
-
99
- if (
100
- pastedNumber.prefix != null &&
101
- countriesByPrefix.has(pastedNumber.prefix) &&
102
- ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)
103
- ) {
104
- setInternalValue(pastedNumber);
105
- }
106
- };
107
-
108
- useEffect(() => {
109
- if (broadcastedValue === null) {
110
- return setBroadcastedValue(internalValue);
111
- }
112
-
113
- const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;
114
- const broadcastedPhoneNumber = `${broadcastedValue.prefix ?? ''}${broadcastedValue.suffix}`;
115
-
116
- if (internalPhoneNumber === broadcastedPhoneNumber) {
117
- return;
118
- }
119
-
120
- const newValue = isValidPhoneNumber(internalPhoneNumber)
121
- ? cleanNumber(internalPhoneNumber)
122
- : null;
123
-
124
- onChange(
125
- newValue,
126
- internalValue.prefix ?? '', // TODO: Allow `null` in public API
127
- );
128
- setBroadcastedValue(internalValue);
129
- }, [onChange, broadcastedValue, internalValue]);
130
-
131
- return (
132
- <div className="tw-telephone">
133
- <div className="tw-telephone__country-select">
134
- <SelectInput
135
- placeholder="Select an option…"
136
- items={[...countriesByPrefix].map(([prefix, countries]) => ({
137
- type: 'option',
138
- value: prefix,
139
- filterMatchers: [
140
- prefix,
141
- ...countries.map((country) => country.name),
142
- ...countries.map((country) => country.iso3),
143
- ],
144
- }))}
145
- value={internalValue.prefix}
146
- renderValue={(prefix, withinTrigger) => (
147
- <SelectInputOptionContent
148
- title={prefix}
149
- note={
150
- withinTrigger
151
- ? undefined
152
- : countriesByPrefix
153
- .get(prefix)
154
- ?.map((country) => country.iso3)
155
- .join(', ')
156
- }
157
- />
158
- )}
159
- filterable
160
- filterPlaceholder={searchPlaceholder}
161
- disabled={disabled}
162
- size={size}
163
- onChange={(prefix) => {
164
- const country = prefix != null ? findCountryByPrefix(prefix) : null;
165
- setInternalValue((prev) => ({ ...prev, prefix, format: country?.phoneFormat }));
166
- }}
167
- {...selectProps}
168
- />
169
- </div>
170
- <div className="tw-telephone__number-input">
171
- <div className={`input-group input-group-${size}`}>
172
- <input
173
- id={id}
174
- autoComplete="tel-national"
175
- name="phoneNumber"
176
- inputMode="numeric"
177
- value={internalValue.suffix}
178
- className="form-control"
179
- disabled={disabled}
180
- required={required}
181
- placeholder={placeholder}
182
- onChange={onSuffixChange}
183
- onPaste={onPaste}
184
- onFocus={onFocus}
185
- onBlur={onBlur}
186
- />
187
- </div>
188
- </div>
189
- </div>
190
- );
191
- };
192
-
193
- export default PhoneNumberInput;
@@ -1,3 +0,0 @@
1
- const DIGITS_MATCH = /^$|^(\+)|([\d]+)/g;
2
-
3
- export const cleanNumber = (number: string) => number.match(DIGITS_MATCH)?.join('') ?? '';
@@ -1,24 +0,0 @@
1
- import { findCountryByPrefix } from '../findCountryByPrefix';
2
-
3
- export interface PhoneNumber {
4
- prefix: string | null;
5
- suffix: string;
6
- format?: string;
7
- }
8
-
9
- /**
10
- * @param number Phone number in a format like "+447573135343"
11
- */
12
- export const explodeNumberModel = (number: string): PhoneNumber => {
13
- const country = findCountryByPrefix(number);
14
- return country
15
- ? {
16
- prefix: country.phone,
17
- suffix: number.slice(country.phone.length),
18
- format: country.phoneFormat,
19
- }
20
- : {
21
- prefix: null,
22
- suffix: number.slice(1),
23
- };
24
- };
@@ -1,12 +0,0 @@
1
- import countries from '../../data/countries';
2
- import { longestMatchingPrefix } from '../longestMatchingPrefix';
3
-
4
- export const findCountryByCode = (code: string) => {
5
- if (code.length === 2) {
6
- const matchingCodes = countries.filter((country) => code.toUpperCase() === country.iso2);
7
- if (matchingCodes.length > 0) {
8
- return longestMatchingPrefix(matchingCodes);
9
- }
10
- }
11
- return null;
12
- };
@@ -1,12 +0,0 @@
1
- import countries from '../../data/countries';
2
- import { longestMatchingPrefix } from '../longestMatchingPrefix';
3
-
4
- export const findCountryByPrefix = (number: string) => {
5
- if (number.length > 1) {
6
- const matchingCodes = countries.filter((country) => number.startsWith(country.phone));
7
- if (matchingCodes.length > 0) {
8
- return longestMatchingPrefix(matchingCodes);
9
- }
10
- }
11
- return null;
12
- };
@@ -1,102 +0,0 @@
1
- import { Country } from '../../data/countries';
2
-
3
- import { groupCountriesByPrefix } from '.';
4
-
5
- const countries = [
6
- {
7
- name: 'Canada',
8
- iso2: 'CA',
9
- iso3: 'CAN',
10
- phone: '+1',
11
- },
12
- {
13
- name: 'United States of America',
14
- iso2: 'US',
15
- iso3: 'USA',
16
- phone: '+1',
17
- },
18
- {
19
- name: 'United States Minor Outlying Islands',
20
- iso2: 'UM',
21
- iso3: 'UMI',
22
- phone: '+1',
23
- },
24
- {
25
- name: 'United Kingdom',
26
- iso2: 'GB',
27
- iso3: 'GBR',
28
- phone: '+44',
29
- },
30
- {
31
- name: 'Guernsey',
32
- iso2: 'GG',
33
- iso3: 'GGY',
34
- phone: '+44',
35
- },
36
- {
37
- name: 'Guinea',
38
- iso2: 'GN',
39
- iso3: 'GIN',
40
- phone: '+224',
41
- },
42
- ];
43
-
44
- const groupedCountries = new Map<string, Country[]>([
45
- [
46
- '+1',
47
- [
48
- {
49
- name: 'Canada',
50
- iso2: 'CA',
51
- iso3: 'CAN',
52
- phone: '+1',
53
- },
54
- {
55
- name: 'United States of America',
56
- iso2: 'US',
57
- iso3: 'USA',
58
- phone: '+1',
59
- },
60
- {
61
- name: 'United States Minor Outlying Islands',
62
- iso2: 'UM',
63
- iso3: 'UMI',
64
- phone: '+1',
65
- },
66
- ],
67
- ],
68
- [
69
- '+44',
70
- [
71
- {
72
- name: 'United Kingdom',
73
- iso2: 'GB',
74
- iso3: 'GBR',
75
- phone: '+44',
76
- },
77
- {
78
- name: 'Guernsey',
79
- iso2: 'GG',
80
- iso3: 'GGY',
81
- phone: '+44',
82
- },
83
- ],
84
- ],
85
- [
86
- '+224',
87
- [
88
- {
89
- name: 'Guinea',
90
- iso2: 'GN',
91
- iso3: 'GIN',
92
- phone: '+224',
93
- },
94
- ],
95
- ],
96
- ]);
97
-
98
- describe('groupCountriesByPrefix', () => {
99
- it('groups countries by prefix', () => {
100
- expect(groupCountriesByPrefix(countries)).toStrictEqual(groupedCountries);
101
- });
102
- });
@@ -1,12 +0,0 @@
1
- import { Country } from '../../data/countries';
2
-
3
- export const groupCountriesByPrefix = (countries: Country[]) => {
4
- const countriesByPrefix = new Map<string, Country[]>();
5
- countries.forEach((country) => {
6
- countriesByPrefix.set(country.phone, [
7
- ...(countriesByPrefix.get(country.phone) ?? []),
8
- country,
9
- ]);
10
- });
11
- return countriesByPrefix;
12
- };
@@ -1 +0,0 @@
1
- export const isStringNumeric = (value: string) => /^\+?[\d-\s]+$/.test(value);
@@ -1,7 +0,0 @@
1
- /**
2
- *
3
- * @param phoneNumber
4
- * @returns True if number that starts with "+" and contains a mix of digits and spaces with at least 4 digits.
5
- */
6
- export const isValidPhoneNumber = (phoneNumber: string) =>
7
- /^\+[\d-\s]+$/.test(phoneNumber) && (phoneNumber.match(/\d+/g)?.join('').length ?? 0) >= 4;
@@ -1,4 +0,0 @@
1
- import { Country } from '../../data/countries';
2
-
3
- export const longestMatchingPrefix = (matchingCodes: Country[]) =>
4
- matchingCodes.reduce((a, b) => (a.phone.length > b.phone.length ? a : b));
@@ -1,20 +0,0 @@
1
- import { getCountryFromLocale } from '../../../common/locale';
2
- import { findCountryByCode } from '../findCountryByCode';
3
-
4
- /**
5
- * Default phone code, the UK one `+44`
6
- */
7
- const DEFAULT_PHONE_CODE = '+44';
8
-
9
- /**
10
- * Given a valid locale it returns the correspondent prefix if found or +44 otherwise.
11
- *
12
- * @param locale BCP 47 language tag of locale, e.g. `"es-ES"`.
13
- * @param countryCode Two-letter country code (ISO 3166-1 alpha-2).
14
- */
15
- export const setDefaultPrefix = (locale: string, countryCode?: string) => {
16
- const country =
17
- (countryCode != null ? findCountryByCode(countryCode) : null) ??
18
- findCountryByCode(getCountryFromLocale(locale) ?? locale);
19
- return country?.phone ?? DEFAULT_PHONE_CODE;
20
- };
@@ -1,6 +0,0 @@
1
- export function sortArrayByProperty<T extends Record<PropertyKey, string>>(
2
- arrayToSort: T[],
3
- property: keyof T,
4
- ) {
5
- return [...arrayToSort].sort((a, b) => a[property].localeCompare(b[property]));
6
- }
@@ -1,14 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- import WithDisplayFormat from '../withDisplayFormat';
4
-
5
- const TextareaWithDisplayFormat = (props) => (
6
- <WithDisplayFormat {...props} render={(renderProps) => <textarea {...renderProps} />} />
7
- );
8
-
9
- TextareaWithDisplayFormat.propTypes = {
10
- displayPattern: PropTypes.string.isRequired,
11
- onChange: PropTypes.func.isRequired,
12
- };
13
-
14
- export default TextareaWithDisplayFormat;
@@ -1 +0,0 @@
1
- export { default } from './TextareaWithDisplayFormat';
@@ -1 +0,0 @@
1
- export { default } from './WithDisplayFormat';
File without changes