UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

93 lines (92 loc) 3.02 kB
import { jsx } from "react/jsx-runtime"; import { InputAdornment } from "@mui/material"; import omit from "lodash/omit"; import { useEffect, useRef, useCallback } from "react"; import { useFormContext, useWatch } from "react-hook-form"; import { defaultCountries, usePhoneInput } from "react-international-phone"; import { useMount } from "ahooks"; import FormInput from "../../components/input.js"; import { isValidCountry } from "../../libs/util.js"; import CountrySelect from "../../components/country-select.js"; import { getPhoneUtil } from "../../libs/phone-validator.js"; export default function PhoneInput({ ...props }) { const countryFieldName = props.countryFieldName || "billing_address.country"; const { control, getValues, setValue, trigger } = useFormContext(); const values = getValues(); const isUpdatingRef = useRef(false); const safeUpdate = useCallback((callback) => { if (isUpdatingRef.current) return; try { isUpdatingRef.current = true; callback(); } finally { requestAnimationFrame(() => { isUpdatingRef.current = false; }); } }, []); const { phone, handlePhoneValueChange, inputRef, country, setCountry } = usePhoneInput({ defaultCountry: isValidCountry(values[countryFieldName]) ? values[countryFieldName] : "us", value: values[props.name] || "", countries: defaultCountries, onChange: (data) => { safeUpdate(() => { setValue(props.name, data.phone); setValue(countryFieldName, data.country); }); } }); const userCountry = useWatch({ control, name: countryFieldName }); useEffect(() => { if (!userCountry || userCountry === country) return; safeUpdate(() => { setCountry(userCountry); }); }, [userCountry, country, setCountry, safeUpdate]); useMount(() => { getPhoneUtil().catch((err) => { console.error("Failed to preload phone validator:", err); }); }); const onCountryChange = useCallback( (v) => { safeUpdate(() => { setCountry(v); }); }, [setCountry, safeUpdate] ); const handleBlur = useCallback(() => { trigger(props.name); }, [props.name]); return ( // @ts-ignore /* @__PURE__ */ jsx( FormInput, { value: phone, onChange: handlePhoneValueChange, type: "tel", inputRef, onBlur: handleBlur, InputProps: { startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", style: { marginRight: "2px", marginLeft: "-8px" }, children: /* @__PURE__ */ jsx( CountrySelect, { value: country, onChange: onCountryChange, name: countryFieldName, sx: { "&.MuiOutlinedInput-notchedOutline": { borderColor: "transparent !important" } }, showDialCode: true } ) }) }, ...omit(props, ["countryFieldName"]) } ) ); }