fix(BOOK-562): update disable color * fix(BOOK-562): update disable color Approved-by: Matilda Landström
158 lines
4.5 KiB
TypeScript
158 lines
4.5 KiB
TypeScript
'use client'
|
|
import 'react-international-phone/style.css'
|
|
|
|
import { useEffect, useMemo } from 'react'
|
|
import { TextField } from 'react-aria-components'
|
|
import { useFormContext, useWatch } from 'react-hook-form'
|
|
import {
|
|
buildCountryData,
|
|
CountrySelector,
|
|
defaultCountries,
|
|
DialCodePreview,
|
|
parseCountry,
|
|
type ParsedCountry,
|
|
usePhoneInput,
|
|
} from 'react-international-phone'
|
|
|
|
import { ErrorMessage } from '../ErrorMessage'
|
|
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
|
import { Input } from '../../Input'
|
|
import { Label } from '../../Label'
|
|
|
|
import styles from './phone.module.css'
|
|
|
|
import type { PhoneProps } from './phone'
|
|
import { Typography } from '../../Typography'
|
|
|
|
export default function Phone({
|
|
ariaLabel = 'Phone number input',
|
|
className = '',
|
|
countryLabel = 'Country code',
|
|
countrySelectorName = 'phoneNumberCC',
|
|
countriesWithTranslatedName,
|
|
defaultCountryCode,
|
|
disabled = false,
|
|
errorMessage,
|
|
label,
|
|
name = 'phoneNumber',
|
|
placeholder,
|
|
registerOptions = {
|
|
required: true,
|
|
},
|
|
}: PhoneProps) {
|
|
const countries = useMemo(() => {
|
|
return defaultCountries.map((dc) => {
|
|
const parsedCountry = parseCountry(dc)
|
|
const country = countriesWithTranslatedName?.find(
|
|
(country) => country.code === parsedCountry.iso2.toUpperCase()
|
|
)
|
|
const translatedCountryName = country?.displayName ?? country?.name
|
|
if (translatedCountryName) {
|
|
parsedCountry.name = translatedCountryName
|
|
}
|
|
return buildCountryData(parsedCountry)
|
|
})
|
|
}, [countriesWithTranslatedName])
|
|
|
|
const { formState, getFieldState, register, setValue } = useFormContext()
|
|
const fieldState = getFieldState(name)
|
|
const ccFieldState = getFieldState(countrySelectorName)
|
|
const [phoneNumber, phoneNumberCC]: [string, string] = useWatch({
|
|
name: [name, countrySelectorName],
|
|
})
|
|
|
|
const { country, setCountry } = usePhoneInput({
|
|
countries,
|
|
defaultCountry: phoneNumberCC ? phoneNumberCC : defaultCountryCode,
|
|
})
|
|
|
|
function handleSelectCountry(value: ParsedCountry) {
|
|
setCountry(value.iso2)
|
|
setValue(countrySelectorName, value.iso2, {
|
|
shouldDirty: true,
|
|
shouldTouch: true,
|
|
shouldValidate: true,
|
|
})
|
|
if (registerOptions.onBlur) {
|
|
registerOptions.onBlur(value)
|
|
}
|
|
}
|
|
useEffect(() => {
|
|
if (!ccFieldState.isTouched) {
|
|
setCountry(phoneNumberCC)
|
|
}
|
|
}, [phoneNumberCC, setCountry, ccFieldState])
|
|
return (
|
|
<div className={`${styles.phone} ${className}`}>
|
|
<CountrySelector
|
|
countries={countries}
|
|
disabled={disabled}
|
|
dropdownArrowClassName={styles.arrow}
|
|
flagClassName={styles.flag}
|
|
onSelect={handleSelectCountry}
|
|
preferredCountries={['de', 'dk', 'fi', 'no', 'se', 'gb']}
|
|
selectedCountry={country.iso2}
|
|
renderButtonWrapper={(props) => (
|
|
<button
|
|
{...props.rootProps}
|
|
className={styles.select}
|
|
tabIndex={0}
|
|
type="button"
|
|
data-testid="country-selector"
|
|
>
|
|
<Label
|
|
required={!!registerOptions.required}
|
|
size="small"
|
|
disabled={disabled}
|
|
>
|
|
{countryLabel}
|
|
</Label>
|
|
<span className={styles.selectContainer}>
|
|
{props.children}
|
|
<Typography variant="Body/Paragraph/mdRegular">
|
|
<p>
|
|
<DialCodePreview
|
|
className={styles.dialCode}
|
|
dialCode={country.dialCode}
|
|
prefix="+"
|
|
disabled={disabled}
|
|
/>
|
|
</p>
|
|
</Typography>
|
|
<MaterialIcon
|
|
icon="keyboard_arrow_down"
|
|
className={styles.chevron}
|
|
color="Icon/Default"
|
|
size={18}
|
|
/>
|
|
</span>
|
|
</button>
|
|
)}
|
|
/>
|
|
<TextField
|
|
aria-label={ariaLabel}
|
|
isDisabled={disabled || registerOptions.disabled}
|
|
isInvalid={fieldState.invalid}
|
|
isRequired={!!registerOptions?.required}
|
|
name={name}
|
|
type="tel"
|
|
value={phoneNumber}
|
|
>
|
|
<Input
|
|
{...register(name, registerOptions)}
|
|
autoComplete="tel-national"
|
|
label={label}
|
|
placeholder={placeholder}
|
|
disabled={disabled}
|
|
type="tel"
|
|
/>
|
|
<ErrorMessage
|
|
errors={formState.errors}
|
|
name={name}
|
|
messageLabel={errorMessage}
|
|
/>
|
|
</TextField>
|
|
</div>
|
|
)
|
|
}
|