Merged in chore/SW-3145-move-phone (pull request #2549)

chore/SW-3145 Moved Phone to design system

* chore/SW-3145 Moved Phone to design system

* chore: SW-3145 Moved phone and removed intl direct dependency


Approved-by: Anton Gunnarsson
This commit is contained in:
Hrishikesh Vaipurkar
2025-07-28 08:28:07 +00:00
parent 58af469e22
commit 42ab6e58b3
12 changed files with 130 additions and 81 deletions

View File

@@ -4,24 +4,27 @@ import { useIntl } from "react-intl"
import { Divider } from "@scandic-hotels/design-system/Divider" import { Divider } from "@scandic-hotels/design-system/Divider"
import CountrySelect from "@scandic-hotels/design-system/Form/Country" import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import { Select } from "@scandic-hotels/design-system/Select" import { Select } from "@scandic-hotels/design-system/Select"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { getLocalizedLanguageOptions } from "@/constants/languages" import {
getDefaultCountryFromLang,
getLocalizedLanguageOptions,
} from "@/constants/languages"
import DateSelect from "@/components/TempDesignSystem/Form/Date" import DateSelect from "@/components/TempDesignSystem/Form/Date"
import Input from "@/components/TempDesignSystem/Form/Input" import Input from "@/components/TempDesignSystem/Form/Input"
import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput" import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput"
import Phone from "@/components/TempDesignSystem/Form/Phone"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { getFormattedCountryList } from "@/utils/countries" import { getFormattedCountryList } from "@/utils/countries"
import { getErrorMessage } from "@/utils/getErrorMessage" import { getErrorMessage } from "@/utils/getErrorMessage"
import { editProfileErrors } from "../schema"
import styles from "./formContent.module.css" import styles from "./formContent.module.css"
export default function FormContent() { import type { FieldErrors } from "react-hook-form"
export default function FormContent({ errors }: { errors: FieldErrors }) {
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const languageOptions = getLocalizedLanguageOptions(lang) const languageOptions = getLocalizedLanguageOptions(lang)
@@ -66,7 +69,8 @@ export default function FormContent() {
countries={getFormattedCountryList(intl)} countries={getFormattedCountryList(intl)}
errorMessage={getErrorMessage( errorMessage={getErrorMessage(
intl, intl,
editProfileErrors.COUNTRY_REQUIRED // @ts-expect-error countryCode doesn't exist schema not available
errors?.address?.countryCode?.message?.toString()
)} )}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country", defaultMessage: "Country",
@@ -86,6 +90,15 @@ export default function FormContent() {
data-hj-suppress data-hj-suppress
/> />
<Phone <Phone
countryLabel={intl.formatMessage({
defaultMessage: "Country code",
})}
countriesWithTranslatedName={getFormattedCountryList(intl)}
defaultCountryCode={getDefaultCountryFromLang(lang)}
errorMessage={getErrorMessage(
intl,
errors?.phoneNumber?.message?.toString()
)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone number", defaultMessage: "Phone number",
})} })}

View File

@@ -185,7 +185,7 @@ export default function Form({ user }: EditFormProps) {
onSubmit={methods.handleSubmit(handleSubmit)} onSubmit={methods.handleSubmit(handleSubmit)}
> >
<FormProvider {...methods}> <FormProvider {...methods}>
<FormContent /> <FormContent errors={methods.formState.errors} />
</FormProvider> </FormProvider>
</form> </form>
</section> </section>

View File

@@ -10,6 +10,7 @@ import { logger } from "@scandic-hotels/common/logger"
import { Button } from "@scandic-hotels/design-system/Button" import { Button } from "@scandic-hotels/design-system/Button"
import Checkbox from "@scandic-hotels/design-system/Form/Checkbox" import Checkbox from "@scandic-hotels/design-system/Form/Checkbox"
import CountrySelect from "@scandic-hotels/design-system/Form/Country" import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trpc } from "@scandic-hotels/trpc/client" import { trpc } from "@scandic-hotels/trpc/client"
import { import {
@@ -27,7 +28,6 @@ import {
import DateSelect from "@/components/TempDesignSystem/Form/Date" import DateSelect from "@/components/TempDesignSystem/Form/Date"
import Input from "@/components/TempDesignSystem/Form/Input" import Input from "@/components/TempDesignSystem/Form/Input"
import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput" import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput"
import Phone from "@/components/TempDesignSystem/Form/Phone"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import { toast } from "@/components/TempDesignSystem/Toasts" import { toast } from "@/components/TempDesignSystem/Toasts"
import { useFormTracking } from "@/components/TrackingSDK/hooks" import { useFormTracking } from "@/components/TrackingSDK/hooks"
@@ -98,7 +98,11 @@ export default function SignupForm({ title }: SignUpFormProps) {
shouldFocusError: true, shouldFocusError: true,
}) })
const { control, subscribe } = methods const {
control,
subscribe,
formState: { errors },
} = methods
const { trackFormSubmit } = useFormTracking("signup", subscribe, control) const { trackFormSubmit } = useFormTracking("signup", subscribe, control)
@@ -174,7 +178,7 @@ export default function SignupForm({ title }: SignUpFormProps) {
countries={getFormattedCountryList(intl)} countries={getFormattedCountryList(intl)}
errorMessage={getErrorMessage( errorMessage={getErrorMessage(
intl, intl,
signupErrors.COUNTRY_REQUIRED errors.address?.countryCode?.message
)} )}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country", defaultMessage: "Country",
@@ -192,6 +196,15 @@ export default function SignupForm({ title }: SignUpFormProps) {
type="email" type="email"
/> />
<Phone <Phone
countryLabel={intl.formatMessage({
defaultMessage: "Country code",
})}
countriesWithTranslatedName={getFormattedCountryList(intl)}
defaultCountryCode={getDefaultCountryFromLang(lang)}
errorMessage={getErrorMessage(
intl,
errors.phoneNumber?.message
)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone number", defaultMessage: "Phone number",
})} })}

View File

@@ -6,12 +6,13 @@ import { useIntl } from "react-intl"
import Footnote from "@scandic-hotels/design-system/Footnote" import Footnote from "@scandic-hotels/design-system/Footnote"
import CountrySelect from "@scandic-hotels/design-system/Form/Country" import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import { getDefaultCountryFromLang } from "@/constants/languages"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import SpecialRequests from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests" import SpecialRequests from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests"
import Input from "@/components/TempDesignSystem/Form/Input" import Input from "@/components/TempDesignSystem/Form/Input"
import Phone from "@/components/TempDesignSystem/Form/Phone"
import { useFormTracking } from "@/components/TrackingSDK/hooks" import { useFormTracking } from "@/components/TrackingSDK/hooks"
import { useRoomContext } from "@/contexts/Details/Room" import { useRoomContext } from "@/contexts/Details/Room"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
@@ -21,7 +22,7 @@ import { getErrorMessage } from "@/utils/getErrorMessage"
import MemberPriceModal from "../MemberPriceModal" import MemberPriceModal from "../MemberPriceModal"
import JoinScandicFriendsCard from "./JoinScandicFriendsCard" import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
import { getMultiroomDetailsSchema, multiroomErrors } from "./schema" import { getMultiroomDetailsSchema } from "./schema"
import styles from "./details.module.css" import styles from "./details.module.css"
@@ -89,7 +90,7 @@ export default function Details() {
trigger, trigger,
control, control,
subscribe, subscribe,
formState: { isValid }, formState: { isValid, errors },
setValue, setValue,
watch, watch,
} = methods } = methods
@@ -192,10 +193,7 @@ export default function Details() {
<CountrySelect <CountrySelect
className={styles.fullWidth} className={styles.fullWidth}
countries={getFormattedCountryList(intl)} countries={getFormattedCountryList(intl)}
errorMessage={getErrorMessage( errorMessage={getErrorMessage(intl, errors.countryCode?.message)}
intl,
multiroomErrors.COUNTRY_REQUIRED
)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country", defaultMessage: "Country",
})} })}
@@ -212,6 +210,12 @@ export default function Details() {
registerOptions={{ required: true, onBlur: updateDetailsStore }} registerOptions={{ required: true, onBlur: updateDetailsStore }}
/> />
<Phone <Phone
countryLabel={intl.formatMessage({
defaultMessage: "Country code",
})}
countriesWithTranslatedName={getFormattedCountryList(intl)}
defaultCountryCode={getDefaultCountryFromLang(lang)}
errorMessage={getErrorMessage(intl, errors.phoneNumber?.message)}
className={styles.fullWidth} className={styles.fullWidth}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone number", defaultMessage: "Phone number",

View File

@@ -6,12 +6,13 @@ import { useIntl } from "react-intl"
import Footnote from "@scandic-hotels/design-system/Footnote" import Footnote from "@scandic-hotels/design-system/Footnote"
import CountrySelect from "@scandic-hotels/design-system/Form/Country" import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import { getDefaultCountryFromLang } from "@/constants/languages"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import SpecialRequests from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests" import SpecialRequests from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests"
import Input from "@/components/TempDesignSystem/Form/Input" import Input from "@/components/TempDesignSystem/Form/Input"
import Phone from "@/components/TempDesignSystem/Form/Phone"
import { useFormTracking } from "@/components/TrackingSDK/hooks" import { useFormTracking } from "@/components/TrackingSDK/hooks"
import { useRoomContext } from "@/contexts/Details/Room" import { useRoomContext } from "@/contexts/Details/Room"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
@@ -21,11 +22,7 @@ import { getErrorMessage } from "@/utils/getErrorMessage"
import MemberPriceModal from "../MemberPriceModal" import MemberPriceModal from "../MemberPriceModal"
import JoinScandicFriendsCard from "./JoinScandicFriendsCard" import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
import { import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
guestDetailsSchema,
roomOneErrors,
signedInDetailsSchema,
} from "./schema"
import Signup from "./Signup" import Signup from "./Signup"
import styles from "./details.module.css" import styles from "./details.module.css"
@@ -178,7 +175,10 @@ export default function Details({ user }: DetailsProps) {
})} })}
lang={lang} lang={lang}
countries={getFormattedCountryList(intl)} countries={getFormattedCountryList(intl)}
errorMessage={getErrorMessage(intl, roomOneErrors.COUNTRY_REQUIRED)} errorMessage={getErrorMessage(
intl,
formState.errors.countryCode?.message
)}
name="countryCode" name="countryCode"
readOnly={!!user} readOnly={!!user}
registerOptions={{ required: true, onBlur: updateDetailsStore }} registerOptions={{ required: true, onBlur: updateDetailsStore }}
@@ -195,6 +195,15 @@ export default function Details({ user }: DetailsProps) {
/> />
<Phone <Phone
className={styles.fullWidth} className={styles.fullWidth}
countryLabel={intl.formatMessage({
defaultMessage: "Country code",
})}
countriesWithTranslatedName={getFormattedCountryList(intl)}
defaultCountryCode={getDefaultCountryFromLang(lang)}
errorMessage={getErrorMessage(
intl,
formState.errors.phoneNumber?.message
)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone number", defaultMessage: "Phone number",
})} })}

View File

@@ -5,10 +5,11 @@ import { useIntl } from "react-intl"
import Body from "@scandic-hotels/design-system/Body" import Body from "@scandic-hotels/design-system/Body"
import CountrySelect from "@scandic-hotels/design-system/Form/Country" import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import { signupErrors } from "@scandic-hotels/trpc/routers/user/schemas" import Phone from "@scandic-hotels/design-system/Form/Phone"
import { getDefaultCountryFromLang } from "@/constants/languages"
import Input from "@/components/TempDesignSystem/Form/Input" import Input from "@/components/TempDesignSystem/Form/Input"
import Phone from "@/components/TempDesignSystem/Form/Phone"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { getFormattedCountryList } from "@/utils/countries" import { getFormattedCountryList } from "@/utils/countries"
import { getErrorMessage } from "@/utils/getErrorMessage" import { getErrorMessage } from "@/utils/getErrorMessage"
@@ -28,7 +29,11 @@ export default function ModifyContact({
}: ModifyContactProps) { }: ModifyContactProps) {
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const { getValues, setValue } = useFormContext() const {
getValues,
setValue,
formState: { errors },
} = useFormContext()
useEffect(() => { useEffect(() => {
setValue("firstName", guest.firstName ?? "") setValue("firstName", guest.firstName ?? "")
@@ -65,7 +70,7 @@ export default function ModifyContact({
countries={getFormattedCountryList(intl)} countries={getFormattedCountryList(intl)}
errorMessage={getErrorMessage( errorMessage={getErrorMessage(
intl, intl,
signupErrors.COUNTRY_REQUIRED errors.countryCode?.message?.toString()
)} )}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Country", defaultMessage: "Country",
@@ -86,6 +91,15 @@ export default function ModifyContact({
</div> </div>
<div className={styles.row}> <div className={styles.row}>
<Phone <Phone
countryLabel={intl.formatMessage({
defaultMessage: "Country code",
})}
countriesWithTranslatedName={getFormattedCountryList(intl)}
defaultCountryCode={getDefaultCountryFromLang(lang)}
errorMessage={getErrorMessage(
intl,
errors.phoneNumber?.message?.toString()
)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Phone number", defaultMessage: "Phone number",
})} })}

View File

@@ -1,7 +1,7 @@
import { Lang } from "@scandic-hotels/common/constants/language" import { Lang } from "@scandic-hotels/common/constants/language"
import { ApiLang } from "@scandic-hotels/trpc/constants/apiLang" import { ApiLang } from "@scandic-hotels/trpc/constants/apiLang"
import type { LowerCaseCountryCode } from "@/types/components/form/phone" import type { CountryCode } from "libphonenumber-js"
export const languages: Record<Lang, string> = { export const languages: Record<Lang, string> = {
[Lang.da]: "Dansk", [Lang.da]: "Dansk",
@@ -82,8 +82,8 @@ export function getLocalizedLanguageOptions(currentLang: Lang) {
}) })
} }
export function getDefaultCountryFromLang(lang: Lang): LowerCaseCountryCode { export function getDefaultCountryFromLang(lang: Lang): Lowercase<CountryCode> {
const countryMap: Record<Lang, LowerCaseCountryCode> = { const countryMap: Record<Lang, Lowercase<CountryCode>> = {
sv: "se", sv: "se",
da: "dk", da: "dk",
fi: "fi", fi: "fi",

View File

@@ -1,9 +1,9 @@
"use client" 'use client'
import "react-international-phone/style.css" import 'react-international-phone/style.css'
import { useEffect, useMemo } from "react" import { useEffect, useMemo } from 'react'
import { TextField } from "react-aria-components" import { TextField } from 'react-aria-components'
import { useFormContext, useWatch } from "react-hook-form" import { useFormContext, useWatch } from 'react-hook-form'
import { import {
buildCountryData, buildCountryData,
CountrySelector, CountrySelector,
@@ -12,53 +12,48 @@ import {
parseCountry, parseCountry,
type ParsedCountry, type ParsedCountry,
usePhoneInput, usePhoneInput,
} from "react-international-phone" } from 'react-international-phone'
import { useIntl } from "react-intl"
import Body from "@scandic-hotels/design-system/Body" import Body from '../../Body'
import { ErrorMessage } from "@scandic-hotels/design-system/Form/ErrorMessage" import { ErrorMessage } from '../ErrorMessage'
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from '../../Icons/MaterialIcon'
import { Input } from "@scandic-hotels/design-system/Input" import { Input } from '../../Input'
import { Label } from "@scandic-hotels/design-system/Label" import { Label } from '../../Label'
import { getDefaultCountryFromLang } from "@/constants/languages" import styles from './phone.module.css'
import useLang from "@/hooks/useLang" import type { PhoneProps } from './phone'
import { getErrorMessage } from "@/utils/getErrorMessage"
import styles from "./phone.module.css"
import type { PhoneProps } from "@/types/components/form/phone"
export default function Phone({ export default function Phone({
ariaLabel = "Phone number input", ariaLabel = 'Phone number input',
className = "", className = '',
countrySelectorName = "phoneNumberCC", countryLabel = 'Country code',
countrySelectorName = 'phoneNumberCC',
countriesWithTranslatedName,
defaultCountryCode,
disabled = false, disabled = false,
errorMessage,
label, label,
name = "phoneNumber", name = 'phoneNumber',
placeholder, placeholder,
readOnly = false, readOnly = false,
registerOptions = { registerOptions = {
required: true, required: true,
}, },
}: PhoneProps) { }: PhoneProps) {
const intl = useIntl()
const lang = useLang()
const countries = useMemo(() => { const countries = useMemo(() => {
return defaultCountries.map((dc) => { return defaultCountries.map((dc) => {
const country = parseCountry(dc) const parsedCountry = parseCountry(dc)
const translatedCountryName = intl.formatDisplayName( const country = countriesWithTranslatedName?.find(
country.iso2.toUpperCase(), (country) => country.code === parsedCountry.iso2.toUpperCase()
{ type: "region" }
) )
const translatedCountryName = country?.displayName ?? country?.name
if (translatedCountryName) { if (translatedCountryName) {
country.name = translatedCountryName parsedCountry.name = translatedCountryName
} }
return buildCountryData(country) return buildCountryData(parsedCountry)
}) })
}, [intl]) }, [countriesWithTranslatedName])
const { formState, getFieldState, register, setValue } = useFormContext() const { formState, getFieldState, register, setValue } = useFormContext()
const fieldState = getFieldState(name) const fieldState = getFieldState(name)
@@ -69,9 +64,7 @@ export default function Phone({
const { country, setCountry } = usePhoneInput({ const { country, setCountry } = usePhoneInput({
countries, countries,
defaultCountry: phoneNumberCC defaultCountry: phoneNumberCC ? phoneNumberCC : defaultCountryCode,
? phoneNumberCC
: getDefaultCountryFromLang(lang),
}) })
function handleSelectCountry(value: ParsedCountry) { function handleSelectCountry(value: ParsedCountry) {
@@ -98,7 +91,7 @@ export default function Phone({
dropdownArrowClassName={styles.arrow} dropdownArrowClassName={styles.arrow}
flagClassName={styles.flag} flagClassName={styles.flag}
onSelect={handleSelectCountry} onSelect={handleSelectCountry}
preferredCountries={["de", "dk", "fi", "no", "se", "gb"]} preferredCountries={['de', 'dk', 'fi', 'no', 'se', 'gb']}
selectedCountry={country.iso2} selectedCountry={country.iso2}
renderButtonWrapper={(props) => ( renderButtonWrapper={(props) => (
<button <button
@@ -109,9 +102,7 @@ export default function Phone({
data-testid="country-selector" data-testid="country-selector"
> >
<Label required={!!registerOptions.required} size="small"> <Label required={!!registerOptions.required} size="small">
{intl.formatMessage({ {countryLabel}
defaultMessage: "Country code",
})}
</Label> </Label>
<span className={styles.selectContainer}> <span className={styles.selectContainer}>
{props.children} {props.children}
@@ -153,10 +144,7 @@ export default function Phone({
<ErrorMessage <ErrorMessage
errors={formState.errors} errors={formState.errors}
name={name} name={name}
messageLabel={getErrorMessage( messageLabel={errorMessage}
intl,
formState.errors[name]?.message?.toString()
)}
/> />
</TextField> </TextField>
</div> </div>

View File

@@ -79,7 +79,7 @@
} }
} }
.select[aria-expanded="true"] .chevron { .select[aria-expanded='true'] .chevron {
transform: rotate(180deg); transform: rotate(180deg);
} }

View File

@@ -1,14 +1,19 @@
import type { CountryCode } from "libphonenumber-js" import type { RegisterOptions } from 'react-hook-form'
import type { RegisterOptions } from "react-hook-form"
export type LowerCaseCountryCode = Lowercase<CountryCode>
export interface PhoneProps { export interface PhoneProps {
ariaLabel?: string ariaLabel?: string
className?: string className?: string
countryLabel?: string
countrySelectorName?: string countrySelectorName?: string
countriesWithTranslatedName: {
code: string
displayName?: string
name: string
}[]
disabled?: boolean disabled?: boolean
errorMessage?: string
label: string label: string
defaultCountryCode: string
name?: string name?: string
placeholder?: string placeholder?: string
readOnly?: boolean readOnly?: boolean

View File

@@ -17,6 +17,7 @@
"./Form/Checkbox": "./dist/components/Form/Checkbox/index.js", "./Form/Checkbox": "./dist/components/Form/Checkbox/index.js",
"./Form/Country": "./dist/components/Form/Country/index.js", "./Form/Country": "./dist/components/Form/Country/index.js",
"./Form/ErrorMessage": "./dist/components/Form/ErrorMessage/index.js", "./Form/ErrorMessage": "./dist/components/Form/ErrorMessage/index.js",
"./Form/Phone": "./dist/components/Form/Phone/index.js",
"./Form/RadioCard": "./dist/components/Form/RadioCard/index.js", "./Form/RadioCard": "./dist/components/Form/RadioCard/index.js",
"./Input": "./dist/components/Input/index.js", "./Input": "./dist/components/Input/index.js",
"./Label": "./dist/components/Label/index.js", "./Label": "./dist/components/Label/index.js",
@@ -152,7 +153,8 @@
"react": "^19.1.0", "react": "^19.1.0",
"react-aria-components": "^1.8.0", "react-aria-components": "^1.8.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-hook-form": "^7.56.2" "react-hook-form": "^7.56.2",
"react-international-phone": "^4.5.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",

View File

@@ -6734,6 +6734,7 @@ __metadata:
react-aria-components: ^1.8.0 react-aria-components: ^1.8.0
react-dom: ^19.1.0 react-dom: ^19.1.0
react-hook-form: ^7.56.2 react-hook-form: ^7.56.2
react-international-phone: ^4.5.0
languageName: unknown languageName: unknown
linkType: soft linkType: soft