UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

97 lines (96 loc) 3.12 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useCallback } from "react"; import { Box, InputBase, InputAdornment, Typography } from "@mui/material"; import { defaultCountries, usePhoneInput } from "react-international-phone"; import { useMount } from "ahooks"; import CountrySelect from "./country-select.js"; import { isValidCountry } from "../libs/util.js"; import { getPhoneUtil } from "../libs/phone-validator.js"; export default function PhoneField({ value, country: externalCountry, onChange, onCountryChange, label, error = void 0, onBlur = void 0 }) { 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(externalCountry) ? externalCountry : "us", value: value || "", countries: defaultCountries, onChange: (data) => { safeUpdate(() => { onChange(data.phone); onCountryChange(data.country); }); } }); useMount(() => { getPhoneUtil().catch((err) => { console.error("Failed to preload phone validator:", err); }); }); useEffect(() => { if (!externalCountry || externalCountry === country) return; safeUpdate(() => { setCountry(externalCountry); }); }, [externalCountry, country, setCountry, safeUpdate]); const handleCountryChange = useCallback( (v) => { safeUpdate(() => { setCountry(v); onCountryChange(v); }); }, [setCountry, safeUpdate, onCountryChange] ); return /* @__PURE__ */ jsxs(Box, { sx: { mb: 1.5 }, children: [ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 13, fontWeight: 600, color: "text.primary", mb: 0.5 }, children: label }), /* @__PURE__ */ jsx( InputBase, { fullWidth: true, value: phone, onChange: handlePhoneValueChange, onBlur, type: "tel", inputRef, startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", sx: { mr: 0.25, ml: -0.5 }, children: /* @__PURE__ */ jsx( CountrySelect, { value: country, onChange: handleCountryChange, sx: { ".MuiOutlinedInput-notchedOutline": { borderColor: "transparent !important" }, "& .MuiSelect-select": { py: 0, pr: "20px !important" } }, showDialCode: true } ) }), sx: { bgcolor: (theme) => theme.palette.mode === "dark" ? "rgba(255,255,255,0.06)" : "grey.50", borderRadius: "8px", px: 1.5, py: 0.75, fontSize: 14, "& .MuiInputBase-input": { p: 0 } } } ), error && /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, color: "error.main", mt: 0.25 }, children: error }) ] }); }