105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef, useState } from "react";
|
|
import { IMaskInput } from "react-imask";
|
|
import {
|
|
InputBase,
|
|
type InputBaseProps,
|
|
type PolymorphicComponentProps,
|
|
} from "@mantine/core";
|
|
import { Country } from "@/components/ui/PhoneInput/types";
|
|
import getInitialDataFromValue from "@/components/ui/PhoneInput/utils/getInitialDataFromValue";
|
|
|
|
type AdditionalProps = {
|
|
onChange: (value: string | null) => void;
|
|
setPhoneMask: (mask: string) => void;
|
|
initialCountryCode?: string;
|
|
};
|
|
|
|
type InputProps = Omit<
|
|
PolymorphicComponentProps<typeof IMaskInput, InputBaseProps>,
|
|
"onChange" | "defaultValue" | "value"
|
|
>;
|
|
|
|
export type Props = AdditionalProps & InputProps;
|
|
|
|
const PhoneInput = ({
|
|
initialCountryCode = "RU",
|
|
onChange: _onChange,
|
|
setPhoneMask: _setPhoneMask,
|
|
...props
|
|
}: Props) => {
|
|
const [mask, setMask] = useState<string>("");
|
|
const initialData = useRef(getInitialDataFromValue(initialCountryCode));
|
|
const [country, setCountry] = useState<Country>(
|
|
initialData.current.country
|
|
);
|
|
const [value, setValue] = useState<string>("");
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const [dropdownWidth, setDropdownWidth] = useState<number>(300);
|
|
|
|
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]);
|
|
|
|
const { readOnly, disabled } = props;
|
|
const leftSectionWidth = 90;
|
|
|
|
useEffect(() => {
|
|
if (!inputRef.current?.offsetWidth) return;
|
|
setDropdownWidth(inputRef.current?.offsetWidth);
|
|
}, [inputRef.current?.offsetWidth]);
|
|
|
|
return (
|
|
<InputBase
|
|
{...props}
|
|
component={IMaskInput}
|
|
inputRef={inputRef}
|
|
leftSection={
|
|
<></>
|
|
// <CountrySelect
|
|
// disabled={disabled || readOnly}
|
|
// country={country}
|
|
// setCountry={country => {
|
|
// 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={onChange}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default PhoneInput;
|