@rh-support/components 2.0.12 → 2.0.13
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/lib/cjs/DropDownList/SearchableList.d.ts +1 -0
- package/lib/cjs/DropDownList/SearchableList.d.ts.map +1 -1
- package/lib/cjs/DropDownList/SearchableList.js +4 -2
- package/lib/cjs/DropDownList/dropdownList.css +1 -1
- package/lib/cjs/DropDownList/types.d.ts +1 -0
- package/lib/cjs/DropDownList/types.d.ts.map +1 -1
- package/lib/cjs/InlineEdit/InlineEdit.d.ts +1 -0
- package/lib/cjs/InlineEdit/InlineEdit.d.ts.map +1 -1
- package/lib/cjs/InlineEdit/InlineEdit.js +2 -2
- package/lib/cjs/InlineEdit/NewInlineEdit.d.ts +1 -0
- package/lib/cjs/InlineEdit/NewInlineEdit.d.ts.map +1 -1
- package/lib/cjs/InlineEdit/NewInlineEdit.js +2 -2
- package/lib/cjs/InlineEdit/inlineEdit.css +4 -0
- package/lib/cjs/InlineEdit/newInlineEdit.css +4 -0
- package/lib/cjs/PhoneInput/CountryData.d.ts +3 -0
- package/lib/cjs/PhoneInput/CountryData.d.ts.map +1 -0
- package/lib/cjs/PhoneInput/CountryData.js +590 -0
- package/lib/cjs/PhoneInput/PhoneInput.d.ts +16 -0
- package/lib/cjs/PhoneInput/PhoneInput.d.ts.map +1 -0
- package/lib/cjs/PhoneInput/PhoneInput.js +204 -0
- package/lib/cjs/PhoneInput/PhoneInput.scss +757 -0
- package/lib/cjs/PhoneInput/flags.png +0 -0
- package/lib/cjs/PhoneInput/index.d.ts +2 -0
- package/lib/cjs/PhoneInput/index.d.ts.map +1 -0
- package/lib/cjs/PhoneInput/index.js +13 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +1 -0
- package/lib/esm/DropDownList/SearchableList.d.ts +1 -0
- package/lib/esm/DropDownList/SearchableList.d.ts.map +1 -1
- package/lib/esm/DropDownList/SearchableList.js +4 -2
- package/lib/esm/DropDownList/dropdownList.css +1 -1
- package/lib/esm/DropDownList/types.d.ts +1 -0
- package/lib/esm/DropDownList/types.d.ts.map +1 -1
- package/lib/esm/InlineEdit/InlineEdit.d.ts +1 -0
- package/lib/esm/InlineEdit/InlineEdit.d.ts.map +1 -1
- package/lib/esm/InlineEdit/InlineEdit.js +2 -2
- package/lib/esm/InlineEdit/NewInlineEdit.d.ts +1 -0
- package/lib/esm/InlineEdit/NewInlineEdit.d.ts.map +1 -1
- package/lib/esm/InlineEdit/NewInlineEdit.js +2 -2
- package/lib/esm/InlineEdit/inlineEdit.css +4 -0
- package/lib/esm/InlineEdit/newInlineEdit.css +4 -0
- package/lib/esm/PhoneInput/CountryData.d.ts +3 -0
- package/lib/esm/PhoneInput/CountryData.d.ts.map +1 -0
- package/lib/esm/PhoneInput/CountryData.js +588 -0
- package/lib/esm/PhoneInput/PhoneInput.d.ts +16 -0
- package/lib/esm/PhoneInput/PhoneInput.d.ts.map +1 -0
- package/lib/esm/PhoneInput/PhoneInput.js +178 -0
- package/lib/esm/PhoneInput/PhoneInput.scss +757 -0
- package/lib/esm/PhoneInput/flags.png +0 -0
- package/lib/esm/PhoneInput/index.d.ts +2 -0
- package/lib/esm/PhoneInput/index.d.ts.map +1 -0
- package/lib/esm/PhoneInput/index.js +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +1 -0
- package/package.json +8 -5
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import './PhoneInput.scss';
|
|
2
|
+
import { InputGroup, Select, SelectOption, SelectVariant, Spinner, TextInput } from '@patternfly/react-core';
|
|
3
|
+
import { isEmpty, isEqual } from 'lodash';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
// import { usePrevious } from '../hooks/usePrevious';
|
|
7
|
+
import CountryData from './CountryData';
|
|
8
|
+
export function PhoneInput(props) {
|
|
9
|
+
const { phoneValue, countryCode, onCountryCodeChange, onPhoneValueChange, validations, setInvalid } = props;
|
|
10
|
+
const { t } = useTranslation();
|
|
11
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
12
|
+
const [iso2, setIso2] = useState('');
|
|
13
|
+
const [formattedNumber, setFormattedNumber] = useState('');
|
|
14
|
+
const [format, setFormat] = useState('');
|
|
15
|
+
const prefix = '+';
|
|
16
|
+
const defaultMask = '... ... ... ... ..';
|
|
17
|
+
const alwaysDefaultMask = false;
|
|
18
|
+
const [countryObj, setCountryObj] = useState({
|
|
19
|
+
name: '',
|
|
20
|
+
regions: [''],
|
|
21
|
+
iso2: '',
|
|
22
|
+
countryCode: '',
|
|
23
|
+
dialCode: '',
|
|
24
|
+
format: '', // Number Format (For US, '(...) ...-....' )
|
|
25
|
+
});
|
|
26
|
+
// Getting Country phone format
|
|
27
|
+
function getMask(prefix, dialCode, predefinedMask, defaultMask, alwaysDefaultMask) {
|
|
28
|
+
if (!predefinedMask || alwaysDefaultMask) {
|
|
29
|
+
return prefix + ''.padEnd(dialCode.length, '.') + ' ' + defaultMask;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return prefix + ''.padEnd(dialCode.length, '.') + ' ' + predefinedMask;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const initializedCountries = CountryData.map((country) => {
|
|
36
|
+
const countryItem = {
|
|
37
|
+
name: country[0],
|
|
38
|
+
regions: country[1],
|
|
39
|
+
iso2: country[2],
|
|
40
|
+
countryCode: country[3],
|
|
41
|
+
dialCode: country[3],
|
|
42
|
+
format: getMask(prefix, country[3], country[4], defaultMask, alwaysDefaultMask),
|
|
43
|
+
priority: country[5] || 0,
|
|
44
|
+
};
|
|
45
|
+
return countryItem;
|
|
46
|
+
});
|
|
47
|
+
const setLocalFormat = (phoneNumber) => {
|
|
48
|
+
let localPhone = phoneNumber.replace(prefix, '');
|
|
49
|
+
// Guessing countries according to user input
|
|
50
|
+
const possibleCountries = initializedCountries.filter((country) => localPhone === null || localPhone === void 0 ? void 0 : localPhone.startsWith(country.dialCode.toString()));
|
|
51
|
+
const exactCountry = initializedCountries.filter((country) => country.dialCode.toString() === localPhone);
|
|
52
|
+
let localFormat;
|
|
53
|
+
if (!isEmpty(exactCountry)) {
|
|
54
|
+
setIso2(exactCountry[0].iso2.toString());
|
|
55
|
+
localFormat = exactCountry[0].format.toString();
|
|
56
|
+
onCountryCodeChange && onCountryCodeChange(prefix + exactCountry[0].dialCode.toString());
|
|
57
|
+
setFormat(localFormat);
|
|
58
|
+
}
|
|
59
|
+
else if (!isEmpty(possibleCountries)) {
|
|
60
|
+
setIso2(possibleCountries[0].iso2.toString());
|
|
61
|
+
localFormat = possibleCountries[0].format.toString();
|
|
62
|
+
onCountryCodeChange && onCountryCodeChange(prefix + possibleCountries[0].dialCode.toString());
|
|
63
|
+
setFormat(localFormat);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// if the exact and possible are not the
|
|
67
|
+
setIso2('');
|
|
68
|
+
localFormat = format;
|
|
69
|
+
onCountryCodeChange && onCountryCodeChange('');
|
|
70
|
+
}
|
|
71
|
+
return localFormat;
|
|
72
|
+
};
|
|
73
|
+
const onPhoneChange = (phone) => {
|
|
74
|
+
if (isEmpty(phone.replace(prefix, ''))) {
|
|
75
|
+
setFormattedNumber('');
|
|
76
|
+
onPhoneValueChange('');
|
|
77
|
+
}
|
|
78
|
+
const regex = /^[\d ()+-]+$/;
|
|
79
|
+
if (setInvalid)
|
|
80
|
+
regex.test(phone) ? setInvalid(false) : setInvalid(true);
|
|
81
|
+
const localFormat = setLocalFormat(phone);
|
|
82
|
+
const _formattedNumber = formatNumber(phone, localFormat);
|
|
83
|
+
setFormattedNumber(_formattedNumber);
|
|
84
|
+
if (!phoneValue.startsWith(prefix) && regex.test(phone) && !isEqual(phone, '-')) {
|
|
85
|
+
onPhoneValueChange(prefix + phone);
|
|
86
|
+
}
|
|
87
|
+
else if (phone.length <= _formattedNumber.length) {
|
|
88
|
+
onPhoneValueChange(phone);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const onToggle = (isOpen) => {
|
|
92
|
+
setIsOpen(isOpen);
|
|
93
|
+
};
|
|
94
|
+
const onCountrySelect = (event, selection) => {
|
|
95
|
+
setCountryObj(selection);
|
|
96
|
+
setIsOpen(!isOpen);
|
|
97
|
+
};
|
|
98
|
+
const getOptions = (options) => {
|
|
99
|
+
return options.map((country) => (React.createElement(SelectOption, { key: country.iso2, value: country },
|
|
100
|
+
React.createElement("div", { className: "pf-u-display-inline-flex" },
|
|
101
|
+
React.createElement("div", { className: `flag ${country.iso2}`, style: { marginRight: '8px' } }),
|
|
102
|
+
country.name,
|
|
103
|
+
" (+",
|
|
104
|
+
country.dialCode,
|
|
105
|
+
")"))));
|
|
106
|
+
};
|
|
107
|
+
const onFilter = (_, value) => {
|
|
108
|
+
if (!value)
|
|
109
|
+
return getOptions(initializedCountries);
|
|
110
|
+
const input = new RegExp(value, 'i');
|
|
111
|
+
const newOptions = initializedCountries.filter((country) => input.test(country.name.toString()));
|
|
112
|
+
return getOptions(newOptions);
|
|
113
|
+
};
|
|
114
|
+
// Formatting phone numbers according to country
|
|
115
|
+
const formatNumber = (fullPhoneNumber, localFormat) => {
|
|
116
|
+
if (isEmpty(fullPhoneNumber)) {
|
|
117
|
+
return '';
|
|
118
|
+
}
|
|
119
|
+
let localPhone = fullPhoneNumber.replace(prefix, '');
|
|
120
|
+
if (isEmpty(localPhone))
|
|
121
|
+
return '';
|
|
122
|
+
// Formatting inputted number
|
|
123
|
+
let phone = '';
|
|
124
|
+
[...fullPhoneNumber].forEach((ele) => {
|
|
125
|
+
if (ele >= '0' && ele <= '9') {
|
|
126
|
+
phone = phone.concat(ele);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
let pattern = '';
|
|
130
|
+
let i = 0;
|
|
131
|
+
for (let j = 0; j < localFormat.length && i < phone.length; j++) {
|
|
132
|
+
if (localFormat[j] === '.') {
|
|
133
|
+
pattern += phone[i];
|
|
134
|
+
i++;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
pattern += localFormat[j];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return pattern;
|
|
141
|
+
};
|
|
142
|
+
const placeholder = (React.createElement("div", { className: "phone-number-select-placeholder" },
|
|
143
|
+
React.createElement("div", { className: "pf-u-display-inline-flex" },
|
|
144
|
+
React.createElement("div", { className: `flag ${iso2}`, style: { marginRight: '5px' } }),
|
|
145
|
+
iso2.toUpperCase())));
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (isEmpty(phoneValue))
|
|
148
|
+
return;
|
|
149
|
+
if (isEmpty(iso2)) {
|
|
150
|
+
const localFormat = setLocalFormat(phoneValue);
|
|
151
|
+
const _formattedNumber = formatNumber(phoneValue, localFormat);
|
|
152
|
+
setFormattedNumber(_formattedNumber);
|
|
153
|
+
}
|
|
154
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
155
|
+
}, []);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (!isEmpty(countryObj.iso2) && `${prefix}${countryObj.dialCode}` !== countryCode) {
|
|
158
|
+
setIso2(countryObj.iso2);
|
|
159
|
+
setFormat(countryObj.format);
|
|
160
|
+
onPhoneValueChange(`${prefix}${countryObj.dialCode}`);
|
|
161
|
+
setFormattedNumber(`${prefix}${countryObj.dialCode}`);
|
|
162
|
+
}
|
|
163
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
164
|
+
}, [countryObj]);
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (isEmpty(phoneValue)) {
|
|
167
|
+
setIso2('');
|
|
168
|
+
setInvalid && setInvalid(false);
|
|
169
|
+
setFormattedNumber('');
|
|
170
|
+
}
|
|
171
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
172
|
+
}, [phoneValue]);
|
|
173
|
+
return (React.createElement(InputGroup, { className: "phone-number-input" },
|
|
174
|
+
React.createElement("div", null,
|
|
175
|
+
React.createElement(Select, { variant: SelectVariant.single, "data-tracking-id": "case-phone-number-country-code", className: "phone-number-select", onToggle: onToggle, onSelect: onCountrySelect, isOpen: isOpen, placeholderText: iso2 && phoneValue !== '' ? placeholder : 'Country Code', onFilter: onFilter, hasInlineFilter: true, inlineFilterPlaceholderText: t('Search'), isDisabled: props.isDisabled }, getOptions(initializedCountries))),
|
|
176
|
+
React.createElement(TextInput, { id: "case-phone-number", "data-tracking-id": "case-phone-number", placeholder: "55-555-5555", value: formattedNumber ? formattedNumber : phoneValue, onChange: onPhoneChange, validated: validations, isDisabled: props.isDisabled }),
|
|
177
|
+
props.isLoading && React.createElement(Spinner, { isSVG: true, size: "lg", className: "pf-u-ml-2xl pf-u-mr-xl phone-spinner" })));
|
|
178
|
+
}
|