@trackunit/react-form-components 0.0.225 → 0.0.228
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/index.cjs.js
CHANGED
|
@@ -44,7 +44,7 @@ var ReactCreatableSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactCrea
|
|
|
44
44
|
var ReactAsyncSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactAsyncSelect);
|
|
45
45
|
|
|
46
46
|
var defaultTranslations = {
|
|
47
|
-
|
|
47
|
+
"phoneField.error": "Invalid phone number"
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
/** The translation namespace for this library */
|
|
@@ -78,6 +78,10 @@ const translations = {
|
|
|
78
78
|
th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
|
|
79
79
|
},
|
|
80
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Local useTranslation for this specific library
|
|
83
|
+
*/
|
|
84
|
+
const useTranslation = () => i18nLibraryTranslation.useNamespaceTranslation(namespace);
|
|
81
85
|
/**
|
|
82
86
|
* Registers the translations for this library
|
|
83
87
|
*/
|
|
@@ -779,6 +783,38 @@ const getPhoneNumberWithPlus = (phoneNumber) => {
|
|
|
779
783
|
const stringPhoneNumber = phoneNumber.toString();
|
|
780
784
|
return checkIfPhoneNumberHasPlus(stringPhoneNumber) ? stringPhoneNumber : `+${stringPhoneNumber}`;
|
|
781
785
|
};
|
|
786
|
+
/**
|
|
787
|
+
* Generates a flag emoji based on the given country code.
|
|
788
|
+
*
|
|
789
|
+
* @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
|
|
790
|
+
* @returns {string} - The corresponding flag emoji for the given country code.
|
|
791
|
+
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
792
|
+
*/
|
|
793
|
+
const countryCodeToFlagEmoji = (countryCode) => {
|
|
794
|
+
let code = countryCode;
|
|
795
|
+
if (countryCode.startsWith("+")) {
|
|
796
|
+
code = getCountryAbbreviation(countryCode.substring(1));
|
|
797
|
+
}
|
|
798
|
+
else if (!isNaN(Number(countryCode))) {
|
|
799
|
+
code = getCountryAbbreviation(countryCode);
|
|
800
|
+
}
|
|
801
|
+
return code.toUpperCase().replace(/./g, char => String.fromCodePoint(127397 + char.charCodeAt(0)));
|
|
802
|
+
};
|
|
803
|
+
/**
|
|
804
|
+
* Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
|
|
805
|
+
*
|
|
806
|
+
* @param {string} callCode - The international calling code for a country.
|
|
807
|
+
* @returns {string} The abbreviation for a country or an empty string if no matching country is found.
|
|
808
|
+
* @example getCountryAbbreviation("45") // "DK"
|
|
809
|
+
* @example getCountryAbbreviation("+45") // "DK"
|
|
810
|
+
*/
|
|
811
|
+
const getCountryAbbreviation = (callCode) => {
|
|
812
|
+
let code = callCode;
|
|
813
|
+
if (callCode.startsWith("+")) {
|
|
814
|
+
code = callCode.substring(1);
|
|
815
|
+
}
|
|
816
|
+
return parsePhoneNumberFromString.getCountries().find(c => parsePhoneNumberFromString.getCountryCallingCode(c) === code) || "";
|
|
817
|
+
};
|
|
782
818
|
|
|
783
819
|
/**
|
|
784
820
|
* A custom hook for managing phone number input state and validation.
|
|
@@ -1268,7 +1304,7 @@ const Select = (props) => {
|
|
|
1268
1304
|
};
|
|
1269
1305
|
Select.displayName = "Select";
|
|
1270
1306
|
|
|
1271
|
-
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["53", "98", "211", "247", "249", "383", "850", "963"];
|
|
1307
|
+
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["+53", "+98", "+211", "+247", "+249", "+383", "+850", "+963"];
|
|
1272
1308
|
const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
1273
1309
|
"1242",
|
|
1274
1310
|
"1246",
|
|
@@ -1298,13 +1334,73 @@ const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
|
1298
1334
|
"882",
|
|
1299
1335
|
"883",
|
|
1300
1336
|
];
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1337
|
+
const DUPLICATE_COUNTRY_CODES = [
|
|
1338
|
+
// +1
|
|
1339
|
+
"AG",
|
|
1340
|
+
"AI",
|
|
1341
|
+
"AS",
|
|
1342
|
+
"BB",
|
|
1343
|
+
"BM",
|
|
1344
|
+
"BS",
|
|
1345
|
+
"CA",
|
|
1346
|
+
"DM",
|
|
1347
|
+
"DO",
|
|
1348
|
+
"GD",
|
|
1349
|
+
"GU",
|
|
1350
|
+
"JM",
|
|
1351
|
+
"KN",
|
|
1352
|
+
"KY",
|
|
1353
|
+
"LC",
|
|
1354
|
+
"MP",
|
|
1355
|
+
"MS",
|
|
1356
|
+
"PR",
|
|
1357
|
+
"SX",
|
|
1358
|
+
"TC",
|
|
1359
|
+
"TT",
|
|
1360
|
+
"VC",
|
|
1361
|
+
"VG",
|
|
1362
|
+
"VI",
|
|
1363
|
+
// +7
|
|
1364
|
+
"KZ",
|
|
1365
|
+
// +39
|
|
1366
|
+
"VA",
|
|
1367
|
+
// +44
|
|
1368
|
+
"GG",
|
|
1369
|
+
"IM",
|
|
1370
|
+
"JE",
|
|
1371
|
+
// +47
|
|
1372
|
+
"SJ",
|
|
1373
|
+
// +61
|
|
1374
|
+
"CC",
|
|
1375
|
+
"CX",
|
|
1376
|
+
// 212
|
|
1377
|
+
"EH",
|
|
1378
|
+
// 262
|
|
1379
|
+
"RE",
|
|
1380
|
+
// 290
|
|
1381
|
+
"SH",
|
|
1382
|
+
// 590
|
|
1383
|
+
"BL",
|
|
1384
|
+
"MF",
|
|
1385
|
+
// 599
|
|
1386
|
+
"CW",
|
|
1387
|
+
];
|
|
1388
|
+
const countries = parsePhoneNumberFromString.getCountries()
|
|
1389
|
+
.filter(code => !DUPLICATE_COUNTRY_CODES.includes(code))
|
|
1390
|
+
.map(code => {
|
|
1391
|
+
const c = parsePhoneNumberFromString.getCountryCallingCode(code);
|
|
1392
|
+
return {
|
|
1393
|
+
label: `+${c} ${countryCodeToFlagEmoji(code)}`,
|
|
1394
|
+
value: `+${c}`,
|
|
1395
|
+
};
|
|
1396
|
+
});
|
|
1397
|
+
const additionalCountries = ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND.map(code => ({
|
|
1398
|
+
label: `+${code}`,
|
|
1399
|
+
value: `+${code}`,
|
|
1400
|
+
}));
|
|
1401
|
+
const countryCodes = [...countries, ...additionalCountries]
|
|
1402
|
+
.filter(code => !COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND.includes(code.value))
|
|
1403
|
+
.sort((a, b) => Number(a.value) - Number(b.value));
|
|
1308
1404
|
|
|
1309
1405
|
/**
|
|
1310
1406
|
* The CountryCodeSelect component is used to select a country code for a phone number.
|
|
@@ -1320,7 +1416,7 @@ const CountryCodeSelect = ({ excludedCountries, countryCode, isInvalid, onChange
|
|
|
1320
1416
|
const filteredCodes = countryCodes.filter(code => {
|
|
1321
1417
|
return !(excludedCountries === null || excludedCountries === void 0 ? void 0 : excludedCountries.some(excludedCode => excludedCode.value === code.value));
|
|
1322
1418
|
});
|
|
1323
|
-
return (jsxRuntime.jsx(Select, { dataTestId: dataTestId, className: "w-
|
|
1419
|
+
return (jsxRuntime.jsx(Select, { dataTestId: dataTestId, className: "w-36", "aria-invalid": isCountryCodeMissing, options: filteredCodes.map(code => code), value: filteredCodes.find(({ value }) => value === `+${countryCode}`), placeholder: placeholder, hasError: isCountryCodeMissing || isInvalid, maxMenuHeight: 200, onChange: onChange, disabled: disabled, readOnly: readOnly, onBlur: onBlur, closeMenuOnSelect: true, menuIsOpen: readOnly ? false : undefined, isClearable: isClearable }));
|
|
1324
1420
|
};
|
|
1325
1421
|
|
|
1326
1422
|
/**
|
|
@@ -1338,7 +1434,16 @@ const PhoneInput = React.forwardRef((_a, ref) => {
|
|
|
1338
1434
|
var { dataTestId, isInvalid, disabled = false, value, defaultValue, fieldSize = "medium", disableAction = false, onChange, onBlurCountryCode, readOnly, countryCodePlaceholder, onChangeCountryCode, onBlur, onFieldsBlur, onChangeValue, isCountryCodeClearable } = _a, rest = __rest(_a, ["dataTestId", "isInvalid", "disabled", "value", "defaultValue", "fieldSize", "disableAction", "onChange", "onBlurCountryCode", "readOnly", "countryCodePlaceholder", "onChangeCountryCode", "onBlur", "onFieldsBlur", "onChangeValue", "isCountryCodeClearable"]);
|
|
1339
1435
|
const DEFAULT_COUNTRY_CODE = "+45";
|
|
1340
1436
|
const { getPhoneNumber } = usePhoneInput();
|
|
1341
|
-
const
|
|
1437
|
+
const [placeholder, setPlaceholder] = React.useState();
|
|
1438
|
+
React.useEffect(() => {
|
|
1439
|
+
if (readOnly) {
|
|
1440
|
+
setPlaceholder("");
|
|
1441
|
+
}
|
|
1442
|
+
else {
|
|
1443
|
+
const countryCode = countryCodePlaceholder || DEFAULT_COUNTRY_CODE;
|
|
1444
|
+
setPlaceholder(`${countryCode} ${countryCodeToFlagEmoji(countryCode)}`);
|
|
1445
|
+
}
|
|
1446
|
+
}, [countryCodePlaceholder, readOnly]);
|
|
1342
1447
|
const safePhoneNumber = getPhoneNumberWithPlus(value || "");
|
|
1343
1448
|
const number = parsePhoneNumberFromString__default["default"](safePhoneNumber, { defaultCountry: "DK" });
|
|
1344
1449
|
const valueHasOnlyCountryCode = (number === null || number === void 0 ? void 0 : number.isPossible) === undefined && typeof value === "string" && value[0] === "+" && value.length < 5;
|
|
@@ -1387,7 +1492,7 @@ const PhoneInput = React.forwardRef((_a, ref) => {
|
|
|
1387
1492
|
}, onChange: e => {
|
|
1388
1493
|
var _a;
|
|
1389
1494
|
onCodeChangeHandler((_a = e === null || e === void 0 ? void 0 : e.value) !== null && _a !== void 0 ? _a : "");
|
|
1390
|
-
}, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, placeholder:
|
|
1495
|
+
}, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, placeholder: placeholder, isClearable: isCountryCodeClearable }), jsxRuntime.jsx(BaseInput, Object.assign({ id: "phoneInput-number", dataTestId: dataTestId && `${dataTestId}-phoneNumberInput`, fieldSize: fieldSize, type: "tel", value: phone, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, onChange: e => {
|
|
1391
1496
|
onPhoneChangeHandler(e.target.value);
|
|
1392
1497
|
}, onBlur: () => {
|
|
1393
1498
|
onBlurHandler();
|
|
@@ -1413,8 +1518,24 @@ const PhoneInput = React.forwardRef((_a, ref) => {
|
|
|
1413
1518
|
const PhoneField = React.forwardRef((_a, ref) => {
|
|
1414
1519
|
var { label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, onChangeValue, onFieldsBlur } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "isInvalid", "errorMessage", "value", "helpAddon", "className", "defaultValue", "dataTestId", "onChangeValue", "onFieldsBlur"]);
|
|
1415
1520
|
const htmlForId = id ? id : "phoneField-" + uuid.v4();
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1521
|
+
const [t] = useTranslation();
|
|
1522
|
+
const [isValid, setIsValid] = React.useState(true);
|
|
1523
|
+
const renderAsInvalid = !isValid || isInvalid || Boolean(errorMessage);
|
|
1524
|
+
const onChangeValueHandler = ({ phone, national, countryCode }) => {
|
|
1525
|
+
if (!isValid && countryCode) {
|
|
1526
|
+
const countryAbbreviation = getCountryAbbreviation(countryCode);
|
|
1527
|
+
setIsValid(phone && national && countryAbbreviation ? parsePhoneNumberFromString.isValidPhoneNumber(phone, countryAbbreviation) : true);
|
|
1528
|
+
}
|
|
1529
|
+
onChangeValue && onChangeValue({ phone, national, countryCode, isValid });
|
|
1530
|
+
};
|
|
1531
|
+
const handleOnFieldBlur = ({ phone, national, countryCode }) => {
|
|
1532
|
+
if (countryCode) {
|
|
1533
|
+
const countryAbbreviation = getCountryAbbreviation(countryCode);
|
|
1534
|
+
setIsValid(phone && national && countryAbbreviation ? parsePhoneNumberFromString.isValidPhoneNumber(phone, countryAbbreviation) : true);
|
|
1535
|
+
}
|
|
1536
|
+
onFieldsBlur && onFieldsBlur({ phone, national, countryCode, isValid });
|
|
1537
|
+
};
|
|
1538
|
+
return (jsxRuntime.jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && (errorMessage || t("phoneField.error"))) || helpText, helpAddon: helpAddon, disabled: rest.disabled, className: className, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsxRuntime.jsx(PhoneInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", value: value, defaultValue: defaultValue, ref: ref, isInvalid: renderAsInvalid, dataTestId: dataTestId, onChangeValue: onChangeValueHandler, onFieldsBlur: handleOnFieldBlur }, rest)) }));
|
|
1418
1539
|
});
|
|
1419
1540
|
|
|
1420
1541
|
/**
|
|
@@ -2069,6 +2190,7 @@ exports.Toggle = Toggle;
|
|
|
2069
2190
|
exports.UploadField = UploadField;
|
|
2070
2191
|
exports.UploadInput = UploadInput;
|
|
2071
2192
|
exports.checkIfPhoneNumberHasPlus = checkIfPhoneNumberHasPlus;
|
|
2193
|
+
exports.countryCodeToFlagEmoji = countryCodeToFlagEmoji;
|
|
2072
2194
|
exports.cvaInput = cvaInput;
|
|
2073
2195
|
exports.cvaInputAddon = cvaInputAddon;
|
|
2074
2196
|
exports.cvaInputAddonAfter = cvaInputAddonAfter;
|
|
@@ -2087,6 +2209,7 @@ exports.cvaSelectMenu = cvaSelectMenu;
|
|
|
2087
2209
|
exports.cvaSelectMenuList = cvaSelectMenuList;
|
|
2088
2210
|
exports.cvaSelectPrefix = cvaSelectPrefix;
|
|
2089
2211
|
exports.cvaSelectXIcon = cvaSelectXIcon;
|
|
2212
|
+
exports.getCountryAbbreviation = getCountryAbbreviation;
|
|
2090
2213
|
exports.getOrderedOptions = getOrderedOptions;
|
|
2091
2214
|
exports.getPhoneNumberWithPlus = getPhoneNumberWithPlus;
|
|
2092
2215
|
exports.isInvalidCountryCode = isInvalidCountryCode;
|
package/index.esm.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { registerTranslations } from '@trackunit/i18n-library-translation';
|
|
2
|
+
import { useNamespaceTranslation, registerTranslations } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { IconButton, Icon, Tip, Heading, Text, MenuItem, Tag, Spinner } from '@trackunit/react-components';
|
|
4
4
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import React__default, { useMemo, forwardRef, useState, cloneElement, useEffect, useRef } from 'react';
|
|
7
7
|
import { v4 } from 'uuid';
|
|
8
8
|
import { format } from 'date-fns';
|
|
9
|
-
import parsePhoneNumberFromString, { getCountries, getCountryCallingCode, parsePhoneNumberFromString as parsePhoneNumberFromString$1,
|
|
9
|
+
import parsePhoneNumberFromString, { getCountries, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString as parsePhoneNumberFromString$1, validatePhoneNumberLength } from 'libphonenumber-js';
|
|
10
10
|
import ReactSelect, { components } from 'react-select';
|
|
11
11
|
export { default as ValueType } from 'react-select';
|
|
12
12
|
import ReactAsyncCreatableSelect from 'react-select/async-creatable';
|
|
@@ -14,7 +14,7 @@ import ReactCreatableSelect from 'react-select/creatable';
|
|
|
14
14
|
import ReactAsyncSelect from 'react-select/async';
|
|
15
15
|
|
|
16
16
|
var defaultTranslations = {
|
|
17
|
-
|
|
17
|
+
"phoneField.error": "Invalid phone number"
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/** The translation namespace for this library */
|
|
@@ -48,6 +48,10 @@ const translations = {
|
|
|
48
48
|
th: () => import('./translation.esm17.js'),
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Local useTranslation for this specific library
|
|
53
|
+
*/
|
|
54
|
+
const useTranslation = () => useNamespaceTranslation(namespace);
|
|
51
55
|
/**
|
|
52
56
|
* Registers the translations for this library
|
|
53
57
|
*/
|
|
@@ -749,6 +753,38 @@ const getPhoneNumberWithPlus = (phoneNumber) => {
|
|
|
749
753
|
const stringPhoneNumber = phoneNumber.toString();
|
|
750
754
|
return checkIfPhoneNumberHasPlus(stringPhoneNumber) ? stringPhoneNumber : `+${stringPhoneNumber}`;
|
|
751
755
|
};
|
|
756
|
+
/**
|
|
757
|
+
* Generates a flag emoji based on the given country code.
|
|
758
|
+
*
|
|
759
|
+
* @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
|
|
760
|
+
* @returns {string} - The corresponding flag emoji for the given country code.
|
|
761
|
+
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
762
|
+
*/
|
|
763
|
+
const countryCodeToFlagEmoji = (countryCode) => {
|
|
764
|
+
let code = countryCode;
|
|
765
|
+
if (countryCode.startsWith("+")) {
|
|
766
|
+
code = getCountryAbbreviation(countryCode.substring(1));
|
|
767
|
+
}
|
|
768
|
+
else if (!isNaN(Number(countryCode))) {
|
|
769
|
+
code = getCountryAbbreviation(countryCode);
|
|
770
|
+
}
|
|
771
|
+
return code.toUpperCase().replace(/./g, char => String.fromCodePoint(127397 + char.charCodeAt(0)));
|
|
772
|
+
};
|
|
773
|
+
/**
|
|
774
|
+
* Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
|
|
775
|
+
*
|
|
776
|
+
* @param {string} callCode - The international calling code for a country.
|
|
777
|
+
* @returns {string} The abbreviation for a country or an empty string if no matching country is found.
|
|
778
|
+
* @example getCountryAbbreviation("45") // "DK"
|
|
779
|
+
* @example getCountryAbbreviation("+45") // "DK"
|
|
780
|
+
*/
|
|
781
|
+
const getCountryAbbreviation = (callCode) => {
|
|
782
|
+
let code = callCode;
|
|
783
|
+
if (callCode.startsWith("+")) {
|
|
784
|
+
code = callCode.substring(1);
|
|
785
|
+
}
|
|
786
|
+
return getCountries().find(c => getCountryCallingCode(c) === code) || "";
|
|
787
|
+
};
|
|
752
788
|
|
|
753
789
|
/**
|
|
754
790
|
* A custom hook for managing phone number input state and validation.
|
|
@@ -1238,7 +1274,7 @@ const Select = (props) => {
|
|
|
1238
1274
|
};
|
|
1239
1275
|
Select.displayName = "Select";
|
|
1240
1276
|
|
|
1241
|
-
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["53", "98", "211", "247", "249", "383", "850", "963"];
|
|
1277
|
+
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["+53", "+98", "+211", "+247", "+249", "+383", "+850", "+963"];
|
|
1242
1278
|
const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
1243
1279
|
"1242",
|
|
1244
1280
|
"1246",
|
|
@@ -1268,13 +1304,73 @@ const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
|
1268
1304
|
"882",
|
|
1269
1305
|
"883",
|
|
1270
1306
|
];
|
|
1271
|
-
const
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1307
|
+
const DUPLICATE_COUNTRY_CODES = [
|
|
1308
|
+
// +1
|
|
1309
|
+
"AG",
|
|
1310
|
+
"AI",
|
|
1311
|
+
"AS",
|
|
1312
|
+
"BB",
|
|
1313
|
+
"BM",
|
|
1314
|
+
"BS",
|
|
1315
|
+
"CA",
|
|
1316
|
+
"DM",
|
|
1317
|
+
"DO",
|
|
1318
|
+
"GD",
|
|
1319
|
+
"GU",
|
|
1320
|
+
"JM",
|
|
1321
|
+
"KN",
|
|
1322
|
+
"KY",
|
|
1323
|
+
"LC",
|
|
1324
|
+
"MP",
|
|
1325
|
+
"MS",
|
|
1326
|
+
"PR",
|
|
1327
|
+
"SX",
|
|
1328
|
+
"TC",
|
|
1329
|
+
"TT",
|
|
1330
|
+
"VC",
|
|
1331
|
+
"VG",
|
|
1332
|
+
"VI",
|
|
1333
|
+
// +7
|
|
1334
|
+
"KZ",
|
|
1335
|
+
// +39
|
|
1336
|
+
"VA",
|
|
1337
|
+
// +44
|
|
1338
|
+
"GG",
|
|
1339
|
+
"IM",
|
|
1340
|
+
"JE",
|
|
1341
|
+
// +47
|
|
1342
|
+
"SJ",
|
|
1343
|
+
// +61
|
|
1344
|
+
"CC",
|
|
1345
|
+
"CX",
|
|
1346
|
+
// 212
|
|
1347
|
+
"EH",
|
|
1348
|
+
// 262
|
|
1349
|
+
"RE",
|
|
1350
|
+
// 290
|
|
1351
|
+
"SH",
|
|
1352
|
+
// 590
|
|
1353
|
+
"BL",
|
|
1354
|
+
"MF",
|
|
1355
|
+
// 599
|
|
1356
|
+
"CW",
|
|
1357
|
+
];
|
|
1358
|
+
const countries = getCountries()
|
|
1359
|
+
.filter(code => !DUPLICATE_COUNTRY_CODES.includes(code))
|
|
1360
|
+
.map(code => {
|
|
1361
|
+
const c = getCountryCallingCode(code);
|
|
1362
|
+
return {
|
|
1363
|
+
label: `+${c} ${countryCodeToFlagEmoji(code)}`,
|
|
1364
|
+
value: `+${c}`,
|
|
1365
|
+
};
|
|
1366
|
+
});
|
|
1367
|
+
const additionalCountries = ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND.map(code => ({
|
|
1368
|
+
label: `+${code}`,
|
|
1369
|
+
value: `+${code}`,
|
|
1370
|
+
}));
|
|
1371
|
+
const countryCodes = [...countries, ...additionalCountries]
|
|
1372
|
+
.filter(code => !COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND.includes(code.value))
|
|
1373
|
+
.sort((a, b) => Number(a.value) - Number(b.value));
|
|
1278
1374
|
|
|
1279
1375
|
/**
|
|
1280
1376
|
* The CountryCodeSelect component is used to select a country code for a phone number.
|
|
@@ -1290,7 +1386,7 @@ const CountryCodeSelect = ({ excludedCountries, countryCode, isInvalid, onChange
|
|
|
1290
1386
|
const filteredCodes = countryCodes.filter(code => {
|
|
1291
1387
|
return !(excludedCountries === null || excludedCountries === void 0 ? void 0 : excludedCountries.some(excludedCode => excludedCode.value === code.value));
|
|
1292
1388
|
});
|
|
1293
|
-
return (jsx(Select, { dataTestId: dataTestId, className: "w-
|
|
1389
|
+
return (jsx(Select, { dataTestId: dataTestId, className: "w-36", "aria-invalid": isCountryCodeMissing, options: filteredCodes.map(code => code), value: filteredCodes.find(({ value }) => value === `+${countryCode}`), placeholder: placeholder, hasError: isCountryCodeMissing || isInvalid, maxMenuHeight: 200, onChange: onChange, disabled: disabled, readOnly: readOnly, onBlur: onBlur, closeMenuOnSelect: true, menuIsOpen: readOnly ? false : undefined, isClearable: isClearable }));
|
|
1294
1390
|
};
|
|
1295
1391
|
|
|
1296
1392
|
/**
|
|
@@ -1308,7 +1404,16 @@ const PhoneInput = forwardRef((_a, ref) => {
|
|
|
1308
1404
|
var { dataTestId, isInvalid, disabled = false, value, defaultValue, fieldSize = "medium", disableAction = false, onChange, onBlurCountryCode, readOnly, countryCodePlaceholder, onChangeCountryCode, onBlur, onFieldsBlur, onChangeValue, isCountryCodeClearable } = _a, rest = __rest(_a, ["dataTestId", "isInvalid", "disabled", "value", "defaultValue", "fieldSize", "disableAction", "onChange", "onBlurCountryCode", "readOnly", "countryCodePlaceholder", "onChangeCountryCode", "onBlur", "onFieldsBlur", "onChangeValue", "isCountryCodeClearable"]);
|
|
1309
1405
|
const DEFAULT_COUNTRY_CODE = "+45";
|
|
1310
1406
|
const { getPhoneNumber } = usePhoneInput();
|
|
1311
|
-
const
|
|
1407
|
+
const [placeholder, setPlaceholder] = useState();
|
|
1408
|
+
useEffect(() => {
|
|
1409
|
+
if (readOnly) {
|
|
1410
|
+
setPlaceholder("");
|
|
1411
|
+
}
|
|
1412
|
+
else {
|
|
1413
|
+
const countryCode = countryCodePlaceholder || DEFAULT_COUNTRY_CODE;
|
|
1414
|
+
setPlaceholder(`${countryCode} ${countryCodeToFlagEmoji(countryCode)}`);
|
|
1415
|
+
}
|
|
1416
|
+
}, [countryCodePlaceholder, readOnly]);
|
|
1312
1417
|
const safePhoneNumber = getPhoneNumberWithPlus(value || "");
|
|
1313
1418
|
const number = parsePhoneNumberFromString(safePhoneNumber, { defaultCountry: "DK" });
|
|
1314
1419
|
const valueHasOnlyCountryCode = (number === null || number === void 0 ? void 0 : number.isPossible) === undefined && typeof value === "string" && value[0] === "+" && value.length < 5;
|
|
@@ -1357,7 +1462,7 @@ const PhoneInput = forwardRef((_a, ref) => {
|
|
|
1357
1462
|
}, onChange: e => {
|
|
1358
1463
|
var _a;
|
|
1359
1464
|
onCodeChangeHandler((_a = e === null || e === void 0 ? void 0 : e.value) !== null && _a !== void 0 ? _a : "");
|
|
1360
|
-
}, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, placeholder:
|
|
1465
|
+
}, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, placeholder: placeholder, isClearable: isCountryCodeClearable }), jsx(BaseInput, Object.assign({ id: "phoneInput-number", dataTestId: dataTestId && `${dataTestId}-phoneNumberInput`, fieldSize: fieldSize, type: "tel", value: phone, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, onChange: e => {
|
|
1361
1466
|
onPhoneChangeHandler(e.target.value);
|
|
1362
1467
|
}, onBlur: () => {
|
|
1363
1468
|
onBlurHandler();
|
|
@@ -1383,8 +1488,24 @@ const PhoneInput = forwardRef((_a, ref) => {
|
|
|
1383
1488
|
const PhoneField = forwardRef((_a, ref) => {
|
|
1384
1489
|
var { label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, onChangeValue, onFieldsBlur } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "isInvalid", "errorMessage", "value", "helpAddon", "className", "defaultValue", "dataTestId", "onChangeValue", "onFieldsBlur"]);
|
|
1385
1490
|
const htmlForId = id ? id : "phoneField-" + v4();
|
|
1386
|
-
const
|
|
1387
|
-
|
|
1491
|
+
const [t] = useTranslation();
|
|
1492
|
+
const [isValid, setIsValid] = useState(true);
|
|
1493
|
+
const renderAsInvalid = !isValid || isInvalid || Boolean(errorMessage);
|
|
1494
|
+
const onChangeValueHandler = ({ phone, national, countryCode }) => {
|
|
1495
|
+
if (!isValid && countryCode) {
|
|
1496
|
+
const countryAbbreviation = getCountryAbbreviation(countryCode);
|
|
1497
|
+
setIsValid(phone && national && countryAbbreviation ? isValidPhoneNumber(phone, countryAbbreviation) : true);
|
|
1498
|
+
}
|
|
1499
|
+
onChangeValue && onChangeValue({ phone, national, countryCode, isValid });
|
|
1500
|
+
};
|
|
1501
|
+
const handleOnFieldBlur = ({ phone, national, countryCode }) => {
|
|
1502
|
+
if (countryCode) {
|
|
1503
|
+
const countryAbbreviation = getCountryAbbreviation(countryCode);
|
|
1504
|
+
setIsValid(phone && national && countryAbbreviation ? isValidPhoneNumber(phone, countryAbbreviation) : true);
|
|
1505
|
+
}
|
|
1506
|
+
onFieldsBlur && onFieldsBlur({ phone, national, countryCode, isValid });
|
|
1507
|
+
};
|
|
1508
|
+
return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && (errorMessage || t("phoneField.error"))) || helpText, helpAddon: helpAddon, disabled: rest.disabled, className: className, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(PhoneInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", value: value, defaultValue: defaultValue, ref: ref, isInvalid: renderAsInvalid, dataTestId: dataTestId, onChangeValue: onChangeValueHandler, onFieldsBlur: handleOnFieldBlur }, rest)) }));
|
|
1388
1509
|
});
|
|
1389
1510
|
|
|
1390
1511
|
/**
|
|
@@ -2002,4 +2123,4 @@ const UploadField = forwardRef((_a, ref) => {
|
|
|
2002
2123
|
*/
|
|
2003
2124
|
setupLibraryTranslations();
|
|
2004
2125
|
|
|
2005
|
-
export { ActionButton, BaseInput, Checkbox, CreatableSelect, DateField, DateInput, DropZone, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, checkIfPhoneNumberHasPlus, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };
|
|
2126
|
+
export { ActionButton, BaseInput, Checkbox, CreatableSelect, DateField, DateInput, DropZone, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CountryCode } from "libphonenumber-js";
|
|
1
2
|
/**
|
|
2
3
|
* @param phoneNumber - a phone number as a string
|
|
3
4
|
* @returns {boolean} true if the phone number starts with a plus sign
|
|
@@ -11,3 +12,20 @@ export declare const checkIfPhoneNumberHasPlus: (phoneNumber: string) => boolean
|
|
|
11
12
|
* @example getPhoneNumberWithPlus("123456789") // "+123456789"
|
|
12
13
|
*/
|
|
13
14
|
export declare const getPhoneNumberWithPlus: (phoneNumber: string | number | readonly string[]) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Generates a flag emoji based on the given country code.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
|
|
19
|
+
* @returns {string} - The corresponding flag emoji for the given country code.
|
|
20
|
+
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
21
|
+
*/
|
|
22
|
+
export declare const countryCodeToFlagEmoji: (countryCode: string) => string;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} callCode - The international calling code for a country.
|
|
27
|
+
* @returns {string} The abbreviation for a country or an empty string if no matching country is found.
|
|
28
|
+
* @example getCountryAbbreviation("45") // "DK"
|
|
29
|
+
* @example getCountryAbbreviation("+45") // "DK"
|
|
30
|
+
*/
|
|
31
|
+
export declare const getCountryAbbreviation: (callCode: string) => CountryCode | "";
|
package/src/translation.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export declare const translations: TranslationResource<TranslationKeys>;
|
|
|
15
15
|
/**
|
|
16
16
|
* Local useTranslation for this specific library
|
|
17
17
|
*/
|
|
18
|
-
export declare const useTranslation: () => [TransForLibs<
|
|
19
|
-
t: TransForLibs<
|
|
18
|
+
export declare const useTranslation: () => [TransForLibs<"phoneField.error">, import("i18next").i18n, boolean] & {
|
|
19
|
+
t: TransForLibs<"phoneField.error">;
|
|
20
20
|
i18n: import("i18next").i18n;
|
|
21
21
|
ready: boolean;
|
|
22
22
|
};
|