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:
@@ -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",
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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",
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -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",
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.select[aria-expanded="true"] .chevron {
|
.select[aria-expanded='true'] .chevron {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user