@adyen/kyc-components
Version:
This guide assumes that you have already an account with Adyen. A legalEntity needs to be created, and you need to have a `legalEntityId` to instatiate a Component.
514 lines (513 loc) • 14.8 kB
JavaScript
try {
let e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "e924e430-0918-42e1-9700-d1d5ea1da76c", e._sentryDebugIdIdentifier = "sentry-dbid-e924e430-0918-42e1-9700-d1d5ea1da76c");
} catch (e) {}
import { r as useTranslation } from "./translation-BYvhW5zA.js";
import { C as useDataset, k as Header, nt as isEmpty, w as datasetIdentifier } from "./resolveEnvironment-DNmu53Rr.js";
import { r as httpPost, s as useApiContext } from "./http-8qgzqVqk.js";
import { c as entriesOf } from "./AnalyticsContext-BFrJmsp0.js";
import { t as CountryCodes } from "./country-code-CJk2hdPu.js";
import { n as mergeFieldMetadataIntoProps, t as createFormUtils } from "./formUtils-DVc3a6gf.js";
import { c as nonInputs, l as numericInputs, n as InputEmail, s as makeMask, t as MaskedInput, u as spacer } from "./MaskedInput-_dYxgb7_.js";
import { n as emailPattern } from "./basePatterns-plHFNzgJ.js";
import { t as resolveFieldMetadata } from "./fieldConfigurations-CZCFghnK.js";
import { t as Field } from "./Field-DoXLi6EY.js";
import { t as Select } from "./Select-DUo2rOfa.js";
import { t as InputGroup } from "./InputGroup-B4U3QVEp.js";
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
import { jsx, jsxs } from "preact/jsx-runtime";
import "@tanstack/preact-query";
//#region src/api/validation/useValidatePhoneNumber.ts
var validatePhoneNumber = (baseUrl, data) => {
return httpPost({
baseUrl,
path: `validations/phonenumber`
}, data);
};
var useValidatePhoneNumberImperatively = () => {
const { baseUrl } = useApiContext();
return useCallback((data) => validatePhoneNumber(baseUrl.value, data), [baseUrl.value]);
};
//#endregion
//#region src/components/Shared/fields/PhoneField/fieldConfig.ts
var validatePhoneCountryCodeNotEmptyOnBlur = {
modes: ["blur"],
validate: (phone) => !isEmpty(phone?.phoneCountryCode),
errorMessage: "missingPhoneCountryCode"
};
var validatePhoneNumberNotEmpty = {
modes: ["blur"],
validate: (phone) => !isEmpty(phone?.number),
errorMessage: "invalidPhoneNumber"
};
var getAsyncPhoneValidationRules = (validatePhoneNumber) => ({ phoneNumber: {
asyncValidate: async (phone) => {
if (!phone?.number) return false;
return (await validatePhoneNumber({ number: phone.number })).valid;
},
errorMessage: "invalidPhoneNumber",
modes: ["blur"]
} });
var defaultValidators = [validatePhoneCountryCodeNotEmptyOnBlur, validatePhoneNumberNotEmpty];
var defaultFieldMetadata = { validators: defaultValidators };
var fieldConfig = {
[CountryCodes.Albania]: {
validators: defaultValidators,
mask: { mask: makeMask(...numericInputs(2), spacer, ...numericInputs(3), spacer, ...numericInputs(4)) }
},
[CountryCodes.AmericanSamoa]: {
validators: defaultValidators,
mask: { mask: makeMask(...numericInputs(3), ...nonInputs("-"), ...numericInputs(4)) }
},
[CountryCodes.Netherlands]: {
validators: defaultValidators,
mask: { mask: makeMask(...numericInputs(1), spacer, ...numericInputs(8)) }
},
[CountryCodes.Singapore]: {
validators: defaultValidators,
mask: { mask: makeMask(...numericInputs(4), spacer, ...numericInputs(4)) }
},
[CountryCodes.Japan]: {
validators: defaultValidators,
mask: { mask: makeMask(...numericInputs(2), ...nonInputs("-"), ...numericInputs(4), ...nonInputs("-"), ...numericInputs(4)) }
},
[CountryCodes.UnitedStates]: {
validators: defaultValidators,
mask: { mask: makeMask(...nonInputs("(", { displayEagerly: false }), ...numericInputs(3), ...nonInputs(")"), spacer, ...numericInputs(3), ...nonInputs("-"), ...numericInputs(4)) }
}
};
/**
* Returns the placeholder text for the phone field based on country.
*/
var getPhonePlaceholder = (country) => {
switch (country) {
case CountryCodes.Albania: return "00 000 0000";
case CountryCodes.AmericanSamoa: return "000-0000";
case CountryCodes.Netherlands: return "0 00000000";
case CountryCodes.Singapore: return "0000 0000";
case CountryCodes.Japan: return "00-0000-0000";
case CountryCodes.UnitedStates: return "(000) 000-0000";
default: return;
}
};
//#endregion
//#region src/components/Shared/forms/ContactDetails/validate.ts
var contactDetailsValidationRules = { email: [{
modes: ["blur"],
validate: (email) => email ? emailPattern.test(email) : false,
errorMessage: "invalidEmail"
}] };
//#endregion
//#region src/datasets/phonePrefixes.json
var phonePrefixes_default = {
"AD": "+376",
"AE": "+971",
"AF": "+93",
"AG": "+1268",
"AI": "+1264",
"AL": "+355",
"AM": "+374",
"AN": "+599",
"AO": "+244",
"AQ": "+672",
"AR": "+54",
"AS": "+1684",
"AT": "+43",
"AU": "+61",
"AW": "+297",
"AX": "+358",
"AZ": "+994",
"BA": "+387",
"BB": "+1246",
"BD": "+880",
"BE": "+32",
"BF": "+226",
"BG": "+359",
"BH": "+973",
"BI": "+257",
"BJ": "+229",
"BL": "+590",
"BM": "+1441",
"BN": "+673",
"BO": "+591",
"BR": "+55",
"BS": "+1242",
"BT": "+975",
"BW": "+267",
"BY": "+375",
"BZ": "+501",
"CA": "+1",
"CC": "+61",
"CD": "+243",
"CF": "+236",
"CG": "+242",
"CH": "+41",
"CI": "+225",
"CK": "+682",
"CL": "+56",
"CM": "+237",
"CN": "+86",
"CO": "+57",
"CR": "+506",
"CU": "+53",
"CV": "+238",
"CX": "+61",
"CY": "+357",
"CZ": "+420",
"DE": "+49",
"DJ": "+253",
"DK": "+45",
"DM": "+1767",
"DO": "+1849",
"DZ": "+213",
"EC": "+593",
"EE": "+372",
"EG": "+20",
"ER": "+291",
"ES": "+34",
"ET": "+251",
"FI": "+358",
"FJ": "+679",
"FK": "+500",
"FM": "+691",
"FO": "+298",
"FR": "+33",
"GA": "+241",
"GB": "+44",
"GD": "+1473",
"GE": "+995",
"GF": "+594",
"GG": "+44",
"GH": "+233",
"GI": "+350",
"GL": "+299",
"GM": "+220",
"GN": "+224",
"GP": "+590",
"GQ": "+240",
"GR": "+30",
"GS": "+500",
"GT": "+502",
"GU": "+1671",
"GW": "+245",
"GY": "+595",
"HK": "+852",
"HN": "+504",
"HR": "+385",
"HT": "+509",
"HU": "+36",
"ID": "+62",
"IE": "+353",
"IL": "+972",
"IM": "+44",
"IN": "+91",
"IO": "+246",
"IQ": "+964",
"IR": "+98",
"IS": "+354",
"IT": "+39",
"JE": "+44",
"JM": "+1876",
"JO": "+962",
"JP": "+81",
"KE": "+254",
"KG": "+996",
"KH": "+855",
"KI": "+686",
"KM": "+269",
"KN": "+1869",
"KP": "+850",
"KR": "+82",
"KW": "+965",
"KY": "+ 345",
"KZ": "+77",
"LA": "+856",
"LB": "+961",
"LC": "+1758",
"LI": "+423",
"LK": "+94",
"LR": "+231",
"LS": "+266",
"LT": "+370",
"LU": "+352",
"LV": "+371",
"LY": "+218",
"MA": "+212",
"MC": "+377",
"MD": "+373",
"ME": "+382",
"MF": "+590",
"MG": "+261",
"MH": "+692",
"MK": "+389",
"ML": "+223",
"MM": "+95",
"MN": "+976",
"MO": "+853",
"MP": "+1670",
"MQ": "+596",
"MR": "+222",
"MS": "+1664",
"MT": "+356",
"MU": "+230",
"MV": "+960",
"MW": "+265",
"MX": "+52",
"MY": "+60",
"MZ": "+258",
"NA": "+264",
"NC": "+687",
"NE": "+227",
"NF": "+672",
"NG": "+234",
"NI": "+505",
"NL": "+31",
"NO": "+47",
"NP": "+977",
"NR": "+674",
"NU": "+683",
"NZ": "+64",
"OM": "+968",
"PA": "+507",
"PE": "+51",
"PF": "+689",
"PG": "+675",
"PH": "+63",
"PK": "+92",
"PL": "+48",
"PM": "+508",
"PN": "+872",
"PR": "+1939",
"PS": "+970",
"PT": "+351",
"PW": "+680",
"PY": "+595",
"QA": "+974",
"RE": "+262",
"RO": "+40",
"RS": "+381",
"RU": "+7",
"RW": "+250",
"SA": "+966",
"SB": "+677",
"SC": "+248",
"SD": "+249",
"SE": "+46",
"SG": "+65",
"SH": "+290",
"SI": "+386",
"SJ": "+47",
"SK": "+421",
"SL": "+232",
"SM": "+378",
"SN": "+221",
"SO": "+252",
"SR": "+597",
"ST": "+239",
"SV": "+503",
"SY": "+963",
"SZ": "+268",
"TC": "+1649",
"TD": "+235",
"TG": "+228",
"TH": "+66",
"TJ": "+992",
"TK": "+690",
"TL": "+670",
"TM": "+993",
"TN": "+216",
"TO": "+676",
"TR": "+90",
"TT": "+1868",
"TV": "+688",
"TW": "+886",
"TZ": "+255",
"UA": "+380",
"UG": "+256",
"US": "+1",
"UY": "+598",
"UZ": "+998",
"VA": "+379",
"VC": "+1784",
"VE": "+58",
"VG": "+1284",
"VI": "+1340",
"VN": "+84",
"VU": "+678",
"WF": "+681",
"WS": "+685",
"YE": "+967",
"YT": "+262",
"ZA": "+27",
"ZM": "+260",
"ZW": "+263"
};
//#endregion
//#region src/components/Shared/fields/PhoneField/PhoneField.tsx
var PHONE_FIELD = ["phoneNumber"];
var phonePrefixes = phonePrefixes_default;
function PhoneField({ country, name = "phoneNumber", data, valid, errors, label, mask, readonly, optional, placeholder, helper, helperPosition, handleChangeFor }) {
const { t } = useTranslation("common");
const { dataset: countries } = useDataset(datasetIdentifier.country);
const [isFocused, setIsFocused] = useState(false);
const currentPrefix = phonePrefixes?.[data.phoneNumber?.phoneCountryCode ?? country];
const numberStrippedOfCountryCode = useMemo(() => {
if (!phonePrefixes || !data.phoneNumber?.number) return "";
return currentPrefix && data.phoneNumber?.number.startsWith(currentPrefix) ? data.phoneNumber.number.slice(currentPrefix.length) : data.phoneNumber.number;
}, [data.phoneNumber?.number, currentPrefix]);
const selectItems = useMemo(() => {
const countryMap = new Map(countries.map((entry) => [entry.id, entry.name]));
return entriesOf(phonePrefixes ?? {}).map(([countryCode, prefix]) => {
return {
id: countryCode,
name: `${countryMap.get(countryCode) ?? countryCode} (${prefix})`,
selectedOptionName: `${countryCode} (${prefix})`
};
}).sort((a, b) => a.name.localeCompare(b.name));
}, [countries]);
const handleSelectChange = useCallback((event) => {
const newCC = phonePrefixes?.[event.target.value];
const withoutCC = currentPrefix && data.phoneNumber?.number?.startsWith(currentPrefix) ? data.phoneNumber?.number?.slice(currentPrefix.length) : data.phoneNumber?.number?.replace(/\D+/g, "");
handleChangeFor("phoneNumber", "input")({
phoneCountryCode: event.target.value,
number: withoutCC ? newCC + withoutCC : newCC,
type: "mobile"
});
}, [
currentPrefix,
data.phoneNumber?.number,
handleChangeFor
]);
const handleOnInput = useCallback((event) => {
const onlyDigits = (currentPrefix ? event.replace(currentPrefix, "") : event).replace(/\D+/g, "");
const number = currentPrefix ? `${currentPrefix}${onlyDigits}` : onlyDigits;
handleChangeFor("phoneNumber", "input")({
...data.phoneNumber,
number,
type: "mobile"
});
}, [
currentPrefix,
data.phoneNumber,
handleChangeFor
]);
const handleOnBlur = useCallback((event) => {
const onlyDigits = event.currentTarget.value.replace(/\D+/g, "");
const number = currentPrefix ? `${currentPrefix}${onlyDigits}` : onlyDigits;
setIsFocused(false);
handleChangeFor("phoneNumber", "blur")({
...data.phoneNumber,
number,
type: "mobile"
});
}, [
currentPrefix,
data.phoneNumber,
handleChangeFor
]);
const transformOnType = useCallback((value) => currentPrefix ? value.startsWith(currentPrefix) ? value.slice(currentPrefix.length) : value : value, [currentPrefix]);
useEffect(() => {
if (!data.phoneNumber?.phoneCountryCode && country) handleChangeFor("phoneNumber", "input")({
...data.phoneNumber,
phoneCountryCode: country,
type: "mobile"
});
}, [
country,
data.phoneNumber?.phoneCountryCode,
data?.phoneNumber,
handleChangeFor
]);
return /* @__PURE__ */ jsx(Field, {
el: "fieldset",
name,
label: label ?? t(($) => $["phoneNumber"]),
errorMessage: errors.phoneNumber,
isValid: Boolean(valid.phoneNumber),
optional: Boolean(optional),
disabled: Boolean(readonly),
helper,
helperPosition,
children: (childProps) => /* @__PURE__ */ jsxs(InputGroup, {
...childProps,
id: "phoneInputGroup",
isFocused,
isInvalid: Boolean(!valid.phoneNumber && errors.phoneNumber),
children: [/* @__PURE__ */ jsx(Select, {
name: "phoneCountryCode",
"aria-label": t(($) => $["phoneNumberPrefix"]),
isMulti: false,
items: selectItems,
selected: data.phoneNumber?.phoneCountryCode,
placeholder: t(($) => $["select"]),
onChange: handleSelectChange,
minimal: true
}), /* @__PURE__ */ jsx(MaskedInput, {
useFieldComponent: false,
name: "phoneNumber",
type: "tel",
label: label ?? t(($) => $["phoneNumber"]),
value: numberStrippedOfCountryCode,
"aria-invalid": Boolean(!valid.phoneNumber),
isValid: Boolean(valid.phoneNumber),
placeholder,
shouldValidate: true,
errorMessage: errors.phoneNumber,
readonly,
disabled: readonly,
transformOnType,
...mask,
stripNonAllowedInputs: true,
onInput: handleOnInput,
onBlur: handleOnBlur,
onFocus: () => setIsFocused(true)
})]
})
});
}
//#endregion
//#region src/components/Shared/forms/ContactDetails/ContactDetails.tsx
var contactDetailFields = [...PHONE_FIELD, "email"];
function ContactDetails(props) {
const { t } = useTranslation("common");
const { country, data, errors = {}, handleFieldChange, fieldValidationErrors, valid = {}, ...newProps } = props;
let mergedProps = newProps;
if (!handleFieldChange) return;
mergedProps = mergeFieldMetadataIntoProps("phoneNumber", resolveFieldMetadata(fieldConfig[data?.phoneNumber?.phoneCountryCode ?? country], {}, defaultFieldMetadata), mergedProps);
const formUtils = createFormUtils(mergedProps, t);
return /* @__PURE__ */ jsxs("div", {
role: "form",
children: [
mergedProps.heading && /* @__PURE__ */ jsx(Header, { title: mergedProps.heading }),
formUtils.isRequiredField("email") && /* @__PURE__ */ jsx(Field, {
name: "email",
label: formUtils.getLabel("email"),
errorMessage: formUtils.getErrorMessage("email", errors, fieldValidationErrors),
isValid: valid.email,
children: (childProps) => /* @__PURE__ */ jsx(InputEmail, {
...childProps,
name: "email",
value: data?.email,
readonly: formUtils.isReadOnly("email"),
onInput: handleFieldChange("email", "input"),
onBlur: handleFieldChange("email", "blur"),
"aria-required": true,
"aria-invalid": !valid?.email
})
}),
formUtils.isRequiredField("phoneNumber") && /* @__PURE__ */ jsx(PhoneField, {
country,
data: formUtils.getFieldData(data ?? {}, PHONE_FIELD),
valid: formUtils.getFieldValid(valid, PHONE_FIELD),
errors: formUtils.getFieldErrors(errors, {}, PHONE_FIELD),
placeholder: getPhonePlaceholder(country),
optional: formUtils.isOptionalField("phoneNumber"),
readonly: formUtils.isReadOnly("phoneNumber"),
mask: formUtils.getMask("phoneNumber"),
handleChangeFor: handleFieldChange
})
]
});
}
//#endregion
export { contactDetailsValidationRules as a, getAsyncPhoneValidationRules as c, phonePrefixes_default as i, getPhonePlaceholder as l, contactDetailFields as n, defaultFieldMetadata as o, PhoneField as r, fieldConfig as s, ContactDetails as t, useValidatePhoneNumberImperatively as u };