Files
web/apps/scandic-web/components/Header/MainMenu/MobileMenu/index.tsx
Joakim Jäderberg 7dee6d5083 Merged in chore/move-enter-details (pull request #2778)
Chore/move enter details

Approved-by: Anton Gunnarsson
2025-09-11 07:16:24 +00:00

137 lines
3.9 KiB
TypeScript

"use client"
import { useEffect } from "react"
import { Dialog, Modal } from "react-aria-components"
import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"
import { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { findMyBookingRoutes } from "@scandic-hotels/common/constants/routes/findMyBookingRoutes"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import useDropdownStore from "@/stores/main-menu"
import LanguageSwitcher from "@/components/LanguageSwitcher"
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
import useLang from "@/hooks/useLang"
import HeaderLink from "../../HeaderLink"
import TopLink from "../../TopLink"
import styles from "./mobileMenu.module.css"
import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown"
import type { MobileMenuProps } from "@/types/components/header/mobileMenu"
export default function MobileMenu({
children,
topLink,
isLoggedIn,
}: React.PropsWithChildren<MobileMenuProps>) {
const lang = useLang()
const intl = useIntl()
const {
toggleDropdown,
isHamburgerMenuOpen,
isMyPagesMobileMenuOpen,
isHeaderLanguageSwitcherMobileOpen,
isFooterLanguageSwitcherOpen,
} = useDropdownStore()
const isHamburgerExtended =
isHamburgerMenuOpen ||
isMyPagesMobileMenuOpen ||
isHeaderLanguageSwitcherMobileOpen ||
isFooterLanguageSwitcherOpen
const isAboveMobile = useMediaQuery("(min-width: 768px)")
useEffect(() => {
if (isAboveMobile && isHamburgerMenuOpen) {
toggleDropdown(DropdownTypeEnum.HamburgerMenu)
}
}, [isAboveMobile, isHamburgerMenuOpen, toggleDropdown])
useHandleKeyUp((event: KeyboardEvent) => {
if (event.key === "Escape" && isHamburgerMenuOpen) {
toggleDropdown(DropdownTypeEnum.HamburgerMenu)
}
})
// Making sure the menu is always opened at the top of the page, just below the header.
useEffect(() => {
if (isHamburgerMenuOpen) {
window.scrollTo({ top: 0, behavior: "instant" })
}
}, [isHamburgerMenuOpen])
const closeMsg = intl.formatMessage({
defaultMessage: "Close menu",
})
const openMsg = intl.formatMessage({
defaultMessage: "Open menu",
})
const findMyBookingUrl = findMyBookingRoutes[lang]
return (
<>
<button
type="button"
className={`${styles.hamburger} ${isHamburgerExtended ? styles.isExpanded : ""}`}
aria-label={isHamburgerExtended ? closeMsg : openMsg}
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
>
<span className={styles.bar} />
</button>
<Modal className={styles.modal} isOpen={isHamburgerMenuOpen}>
<Dialog
className={styles.dialog}
aria-label={intl.formatMessage({
defaultMessage: "Menu",
})}
>
{children}
<footer className={styles.footer}>
<HeaderLink
href={findMyBookingUrl}
iconName={IconName.Search}
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
>
{intl.formatMessage({
defaultMessage: "Find booking",
})}
</HeaderLink>
<TopLink isLoggedIn={isLoggedIn} topLink={topLink} iconSize={20} />
<HeaderLink
href={customerService[lang]}
iconName={IconName.Service}
>
{intl.formatMessage({
defaultMessage: "Customer service",
})}
</HeaderLink>
<LanguageSwitcher type="mobileHeader" />
</footer>
</Dialog>
</Modal>
</>
)
}
export function MobileMenuSkeleton() {
const intl = useIntl()
return (
<button
type="button"
disabled
className={styles.hamburger}
aria-label={intl.formatMessage({
defaultMessage: "Open menu",
})}
>
<span className={styles.bar} />
</button>
)
}