83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
/* eslint-disable @next/next/no-img-element */
|
|
import countries from "countries-phone-masks";
|
|
import {
|
|
CountryCode,
|
|
getCountries,
|
|
getCountryCallingCode,
|
|
} from "libphonenumber-js";
|
|
import { SyntheticEvent, useRef, useState } from "react";
|
|
import { useOnClickOutside } from "usehooks-ts";
|
|
import ChevronDownIcon from "@/components/icons/ChevronDownIcon";
|
|
import ChevronUpIcon from "@/components/icons/ChevronUpIcon";
|
|
|
|
export function SelectPhoneCode({
|
|
currentPhoneCodeAndCountry: [currentPhoneCode, currentCountry],
|
|
onClick,
|
|
}: {
|
|
currentPhoneCodeAndCountry: [string, CountryCode];
|
|
onClick: ([phoneCode, country]: [string, CountryCode]) => void;
|
|
}) {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
useOnClickOutside(ref, () => setOpen(false));
|
|
|
|
function handleExpand(e: SyntheticEvent) {
|
|
e.preventDefault();
|
|
setOpen((prev) => !prev);
|
|
}
|
|
|
|
function pickPhoneCode(phoneCode: string, country: CountryCode) {
|
|
onClick([phoneCode, country as CountryCode]);
|
|
setOpen(false);
|
|
}
|
|
|
|
return (
|
|
<div ref={ref} className="relative flex flex-col w-[10%] max-w-[350px]">
|
|
<button
|
|
className="gap-x-1 relative flex items-center justify-between"
|
|
onClick={handleExpand}
|
|
>
|
|
<img
|
|
width={16}
|
|
height={8}
|
|
src={countries.find((c) => c.iso === currentCountry)?.flag || ""}
|
|
className="!relative w-4 sm:w-6"
|
|
alt={currentCountry}
|
|
/>
|
|
<p className="btnl font-medium">{currentPhoneCode}</p>
|
|
<div className="text-white lg:size-[1.111vw] size-4">
|
|
{open ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
</div>
|
|
</button>
|
|
{open && (
|
|
<div className="space-y-1 absolute z-10 bg-[#14161F] top-[100%] -left-1 border border-t-0 rounded-b-lg border-[#37393B] max-h-[300px] overflow-y-auto overflow-x-hidden">
|
|
{getCountries()
|
|
.map((country) => [`+${getCountryCallingCode(country)}`, country])
|
|
.filter(
|
|
([phonecode, country]) =>
|
|
phonecode !== currentPhoneCode || country !== currentCountry
|
|
)
|
|
.map(([phoneCode, country]) => (
|
|
<div
|
|
key={country}
|
|
className="flex items-center gap-x-1 hover:bg-[#3D425C] px-1"
|
|
onClick={() => pickPhoneCode(phoneCode, country as CountryCode)}
|
|
>
|
|
<img
|
|
src={countries.find((c) => c.iso === country)?.flag || ""}
|
|
alt={country}
|
|
className="!relative w-4 sm:w-6"
|
|
width={16}
|
|
height={8}
|
|
/>
|
|
<p className="m-text flex-1 py-1 cursor-pointer">{phoneCode}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|