fix(SW-3707): fix footer LanguageSwitcher icon colors * fix(SW-3707): fix footer LanguageSwitcher icon colors Approved-by: Anton Gunnarsson
222 lines
6.1 KiB
TypeScript
222 lines
6.1 KiB
TypeScript
"use client"
|
|
|
|
import { usePathname } from "next/navigation"
|
|
import {
|
|
Dialog,
|
|
DialogTrigger,
|
|
Modal,
|
|
ModalOverlay,
|
|
Popover,
|
|
} from "react-aria-components"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import {
|
|
type Lang,
|
|
languages,
|
|
type LanguageSwitcherData,
|
|
} from "@scandic-hotels/common/constants/language"
|
|
import { Button } from "@scandic-hotels/design-system/Button"
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
import Link from "@scandic-hotels/design-system/OldDSLink"
|
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
|
|
import { languageSwitcherVariants } from "./variants"
|
|
|
|
import styles from "./languageSwitcher.module.css"
|
|
|
|
type LanguageSwitcherProps = {
|
|
currentLanguage: Lang
|
|
isMobile?: boolean
|
|
type?: "footer" | "header"
|
|
}
|
|
|
|
function replaceUrlPart(currentPath: string, newPart: string): string {
|
|
const pathSegments = currentPath.split("/").filter((segment) => segment)
|
|
|
|
const newPathSegments = newPart
|
|
.replace(/\/$/, "")
|
|
.split("/")
|
|
.filter((segment) => segment)
|
|
|
|
const isFullPathReplacement = newPathSegments.length > 1
|
|
|
|
if (isFullPathReplacement) {
|
|
return `/${newPathSegments.join("/")}`
|
|
}
|
|
|
|
const updatedPathSegments = pathSegments.slice(1)
|
|
const updatedPath = `/${newPathSegments.concat(updatedPathSegments).join("/")}`
|
|
|
|
return updatedPath
|
|
}
|
|
|
|
export function LanguageSwitcher({
|
|
currentLanguage,
|
|
isMobile = false,
|
|
type = "header",
|
|
}: LanguageSwitcherProps) {
|
|
const classNames = languageSwitcherVariants({ position: type })
|
|
const isFooter = type === "footer"
|
|
|
|
return (
|
|
<div className={classNames}>
|
|
<DialogTrigger>
|
|
<Button className={styles.triggerButton} variant="Text">
|
|
{isMobile && !isFooter ? null : (
|
|
<MaterialIcon icon="globe" size={16} className={styles.globeIcon} />
|
|
)}
|
|
<Typography
|
|
variant={
|
|
isMobile
|
|
? "Body/Paragraph/mdRegular"
|
|
: "Body/Supporting text (caption)/smRegular"
|
|
}
|
|
>
|
|
<span className={styles.triggerText}>
|
|
{languages[currentLanguage]}
|
|
<MaterialIcon
|
|
className={styles.chevron}
|
|
icon="keyboard_arrow_down"
|
|
size={isMobile ? 24 : 20}
|
|
/>
|
|
</span>
|
|
</Typography>
|
|
</Button>
|
|
{isMobile ? (
|
|
<ModalOverlay
|
|
isDismissable
|
|
className={`${styles.languageModalOverlay} ${isFooter ? styles.footer : null}`}
|
|
>
|
|
<Modal className={styles.languageModal}>
|
|
<Dialog>
|
|
{({ close }) => (
|
|
<LanguageSwitcherContent
|
|
closeModal={close}
|
|
isMobile={true}
|
|
currentLanguage={currentLanguage}
|
|
/>
|
|
)}
|
|
</Dialog>
|
|
</Modal>
|
|
</ModalOverlay>
|
|
) : (
|
|
<Popover
|
|
offset={isFooter ? 0 : 21}
|
|
className={styles.languageSwitcherPopover}
|
|
placement="bottom right"
|
|
>
|
|
<Dialog>
|
|
{({ close }) => (
|
|
<LanguageSwitcherContent
|
|
closeModal={close}
|
|
isMobile={false}
|
|
currentLanguage={currentLanguage}
|
|
/>
|
|
)}
|
|
</Dialog>
|
|
</Popover>
|
|
)}
|
|
</DialogTrigger>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function LanguageSwitcherContent({
|
|
closeModal,
|
|
currentLanguage,
|
|
isMobile,
|
|
}: {
|
|
closeModal: () => void
|
|
currentLanguage: Lang
|
|
isMobile?: boolean
|
|
}) {
|
|
const intl = useIntl()
|
|
const pathname = usePathname()
|
|
|
|
const urls: LanguageSwitcherData = {
|
|
da: { url: "/da/" },
|
|
de: { url: "/de/" },
|
|
en: { url: "/en/" },
|
|
fi: { url: "/fi/" },
|
|
no: { url: "/no/" },
|
|
sv: { url: "/sv/" },
|
|
}
|
|
|
|
const urlKeys = (Object.keys(urls) as (keyof typeof urls)[]).sort((a, b) => {
|
|
return languages[a].localeCompare(languages[b])
|
|
})
|
|
|
|
return (
|
|
<div className={styles.languageSwitcherContent}>
|
|
{isMobile ? (
|
|
<>
|
|
<div className={styles.closeModalWrapper}>
|
|
<Button
|
|
variant="Text"
|
|
size="md"
|
|
onPress={closeModal}
|
|
className={styles.closeModal}
|
|
>
|
|
<MaterialIcon
|
|
icon="chevron_left"
|
|
size={28}
|
|
className={styles.arrowBackIcon}
|
|
color="CurrentColor"
|
|
/>
|
|
<MaterialIcon
|
|
icon="close"
|
|
size={32}
|
|
className={styles.closeIcon}
|
|
color="CurrentColor"
|
|
/>
|
|
</Button>
|
|
</div>
|
|
<Typography variant="Title/Subtitle/md">
|
|
<h3 className={styles.title}>
|
|
{intl.formatMessage({
|
|
id: "common.selectYourLanguage",
|
|
defaultMessage: "Select your language",
|
|
})}
|
|
</h3>
|
|
</Typography>
|
|
</>
|
|
) : null}
|
|
<ul className={styles.languageSwitcherListContainer}>
|
|
{urlKeys.map((key) => {
|
|
const url = urls[key]?.url
|
|
const isActive = currentLanguage === key
|
|
|
|
if (url) {
|
|
return (
|
|
<li key={key} className={styles.languageSwitcherListItem}>
|
|
<Typography
|
|
variant={
|
|
isActive
|
|
? "Body/Paragraph/mdBold"
|
|
: "Body/Paragraph/mdRegular"
|
|
}
|
|
>
|
|
<Link
|
|
className={`${styles.link} ${isActive ? styles.active : ""}`}
|
|
href={replaceUrlPart(pathname, url)}
|
|
variant="languageSwitcher"
|
|
keepSearchParams
|
|
>
|
|
{languages[key]}
|
|
{isActive ? (
|
|
<MaterialIcon
|
|
icon="check"
|
|
color="Icon/Interactive/Default"
|
|
/>
|
|
) : null}
|
|
</Link>
|
|
</Typography>
|
|
</li>
|
|
)
|
|
}
|
|
})}
|
|
</ul>
|
|
</div>
|
|
)
|
|
}
|