"use client"; import { useEffect, useRef, useState } from "react"; import { IMaskInput } from "react-imask"; import { InputBase, type InputBaseProps, type PolymorphicComponentProps, } from "@mantine/core"; import CountrySelect from "@/components/PhoneInput/components/CountrySelect"; import { Country } from "@/components/PhoneInput/types"; import getInitialDataFromValue from "@/components/PhoneInput/utils/getInitialDataFromValue"; import getPhoneMask from "@/components/PhoneInput/utils/getPhoneMask"; type AdditionalProps = { onChange: (value: string | null) => void; setPhoneMask: (mask: string) => void; initialCountryCode?: string; }; type InputProps = Omit< PolymorphicComponentProps, "onChange" | "defaultValue" >; export type Props = AdditionalProps & InputProps; const PhoneInput = ({ initialCountryCode = "RU", value: _value, onChange: _onChange, setPhoneMask: _setPhoneMask, ...props }: Props) => { const [mask, setMask] = useState(""); const initialData = useRef(getInitialDataFromValue(initialCountryCode)); const [country, setCountry] = useState( initialData.current.country ); const [value, setValue] = useState(""); const inputRef = useRef(null); const [dropdownWidth, setDropdownWidth] = useState(300); const lastNotifiedValue = useRef(value ?? ""); const onChange = (numberWithoutCode: string) => { setValue(numberWithoutCode); _onChange(`+${country.callingCode} ${numberWithoutCode}`); }; const setPhoneMask = (phoneMask: string, country: Country) => { setMask(phoneMask); _setPhoneMask(`+${country.callingCode} ${phoneMask}`); }; useEffect(() => { setPhoneMask(initialData.current.format, country); }, [initialData.current.format]); useEffect(() => { const localValue = value.trim(); if (localValue !== lastNotifiedValue.current) { lastNotifiedValue.current = localValue; onChange(localValue); } }, [country.code, value]); const { readOnly, disabled } = props; const leftSectionWidth = 90; useEffect(() => { if (!inputRef.current?.offsetWidth) return; setDropdownWidth(inputRef.current?.offsetWidth); }, [inputRef.current?.offsetWidth]); return ( { setCountry(country); setPhoneMask(getPhoneMask(country.code), country); setValue(""); if (inputRef.current) { inputRef.current.focus(); } }} leftSectionWidth={leftSectionWidth} inputWidth={dropdownWidth} /> } leftSectionWidth={leftSectionWidth} styles={{ input: { fontSize: 17, paddingLeft: `calc(${leftSectionWidth}px + var(--mantine-spacing-sm))`, }, section: { borderRight: "1px solid var(--mantine-color-default-border)", }, }} inputMode={"numeric"} mask={mask} value={value} onAccept={value => setValue(value)} /> ); }; export default PhoneInput;