UNPKG

@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
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 };