feat(WEB-170): edit profile view
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"use client"
|
||||
import "react-international-phone/style.css"
|
||||
import { useController, useFormContext, useWatch } from "react-hook-form"
|
||||
import { useCallback, useEffect, useRef } from "react"
|
||||
import { defaultCountries, getCountry } from "react-international-phone"
|
||||
|
||||
import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage"
|
||||
import { PhoneInput, type PhoneInputRefType } from "react-international-phone"
|
||||
|
||||
import styles from "./phone.module.css"
|
||||
|
||||
import type { PhoneProps } from "./phone"
|
||||
|
||||
export default function Phone({
|
||||
name = "phone",
|
||||
placeholder = "",
|
||||
registerOptions = {
|
||||
required: true,
|
||||
},
|
||||
}: PhoneProps) {
|
||||
const phoneRef = useRef<PhoneInputRefType>(null)
|
||||
const { control, formState } = useFormContext()
|
||||
const countryValue = useWatch({ name: "country" })
|
||||
const defaultCountry = getCountry({
|
||||
countries: defaultCountries,
|
||||
field: "name",
|
||||
value: countryValue,
|
||||
})
|
||||
/**
|
||||
* 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: "name",
|
||||
value: country,
|
||||
})
|
||||
|
||||
if (selectedCountry) {
|
||||
phoneRef.current?.setCountry(selectedCountry.iso2)
|
||||
prevSelectedCountry.current = country
|
||||
}
|
||||
},
|
||||
[phoneRef.current, prevSelectedCountry.current]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (countryValue) {
|
||||
if (field.value) {
|
||||
if (prevSelectedCountry.current) {
|
||||
if (prevSelectedCountry.current !== countryValue) {
|
||||
const selectedCountryPrev = getCountry({
|
||||
countries: defaultCountries,
|
||||
field: "name",
|
||||
value: prevSelectedCountry.current,
|
||||
})
|
||||
if (
|
||||
field.value.replace("+", "") === selectedCountryPrev?.dialCode
|
||||
) {
|
||||
handleCountrySelectForPhone(countryValue)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleCountrySelectForPhone(countryValue)
|
||||
}
|
||||
} else {
|
||||
handleCountrySelectForPhone(countryValue)
|
||||
}
|
||||
}
|
||||
}, [countryValue, prevSelectedCountry.current])
|
||||
|
||||
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>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
.phone {
|
||||
--react-international-phone-border-color: var(--some-black-color, #757575);
|
||||
--react-international-phone-border-radius: 0.4rem;
|
||||
--react-international-phone-font-size: 1.6rem;
|
||||
--react-international-phone-height: 4rem;
|
||||
--react-international-phone-text-color: color:
|
||||
var(--some-black-color, #757575);
|
||||
}
|
||||
|
||||
.phone :global(.react-international-phone-input-container) {
|
||||
display: grid;
|
||||
/* r-i-p sets their width dynamically and doesn't respect the width property of its parent */
|
||||
grid-template-columns: 4.7rem minmax(20.3rem, 1fr);
|
||||
width: min(28rem, 100%);
|
||||
}
|
||||
|
||||
/* react-international-phone only exposes variables to change border-color */
|
||||
.phone :global(.react-international-phone-country-selector-button),
|
||||
.phone :global(.react-international-phone-input) {
|
||||
border-width: 0.2rem;
|
||||
}
|
||||
|
||||
.phone :global(.react-international-phone-input) {
|
||||
padding: 0.8rem 1.6rem;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export type PhoneProps = {
|
||||
name?: string
|
||||
placeholder?: string
|
||||
registerOptions?: RegisterOptions
|
||||
}
|
||||
Reference in New Issue
Block a user