101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
"use client"
|
|
import "react-international-phone/style.css"
|
|
|
|
import { useCallback, useEffect, useRef } from "react"
|
|
import { useController, useFormContext, useWatch } from "react-hook-form"
|
|
import {
|
|
defaultCountries,
|
|
getCountry,
|
|
PhoneInput,
|
|
type PhoneInputRefType,
|
|
} from "react-international-phone"
|
|
|
|
import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage"
|
|
|
|
import styles from "./phone.module.css"
|
|
|
|
import type { PhoneProps } from "./phone"
|
|
|
|
export default function Phone({
|
|
countrySelectName = "country",
|
|
name = "phoneNumber",
|
|
placeholder = "",
|
|
registerOptions = {
|
|
required: true,
|
|
},
|
|
}: PhoneProps) {
|
|
const phoneRef = useRef<PhoneInputRefType>(null)
|
|
const { control, formState } = useFormContext()
|
|
const countryValue = useWatch({ name: countrySelectName })
|
|
const defaultCountry = getCountry({
|
|
countries: defaultCountries,
|
|
field: "iso2",
|
|
value: String(countryValue).toLowerCase(),
|
|
})
|
|
/**
|
|
* Holds the previous selected country to be able to update
|
|
* countrycode based on country select field.
|
|
* Since PhoneInput inputs the countrys dialcode (country code) upon
|
|
* selection, we need to check if the current value is just
|
|
* the previously selected countrys dialcode number.
|
|
*/
|
|
const prevSelectedCountry = useRef<string | undefined>(countryValue)
|
|
const { field } = useController({
|
|
control,
|
|
name,
|
|
rules: registerOptions,
|
|
})
|
|
|
|
const handleCountrySelectForPhone = useCallback((country: string) => {
|
|
const selectedCountry = getCountry({
|
|
countries: defaultCountries,
|
|
field: "iso2",
|
|
value: country.toLowerCase(),
|
|
})
|
|
|
|
if (selectedCountry) {
|
|
phoneRef.current?.setCountry(selectedCountry.iso2)
|
|
prevSelectedCountry.current = country.toLowerCase()
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (countryValue) {
|
|
if (field.value) {
|
|
if (prevSelectedCountry.current) {
|
|
if (prevSelectedCountry.current !== countryValue) {
|
|
const selectedCountryPrev = getCountry({
|
|
countries: defaultCountries,
|
|
field: "iso2",
|
|
value: prevSelectedCountry.current.toLowerCase(),
|
|
})
|
|
if (
|
|
field.value.replace("+", "") === selectedCountryPrev?.dialCode
|
|
) {
|
|
handleCountrySelectForPhone(countryValue)
|
|
}
|
|
}
|
|
} else {
|
|
handleCountrySelectForPhone(countryValue)
|
|
}
|
|
} else {
|
|
handleCountrySelectForPhone(countryValue)
|
|
}
|
|
}
|
|
}, [countryValue, field.value, handleCountrySelectForPhone])
|
|
|
|
return (
|
|
<div className={styles.phone}>
|
|
<PhoneInput
|
|
{...field}
|
|
className={styles.input}
|
|
defaultCountry={defaultCountry?.iso2 ?? "se"}
|
|
placeholder={placeholder}
|
|
preferredCountries={["de", "dk", "fi", "no", "se", "gb"]}
|
|
ref={phoneRef}
|
|
/>
|
|
<ErrorMessage errors={formState.errors} name={name} />
|
|
</div>
|
|
)
|
|
}
|