From a2e2cf575e960196ae2b716d15c33d463fd2e066 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Wed, 21 Aug 2024 14:38:29 +0200 Subject: [PATCH] feat(SW-184): implementing mobile design --- app/globals.css | 1 + .../Header/HeaderLink/headerLink.module.css | 6 + components/Header/HeaderLink/index.tsx | 13 +++ .../MainMenuButton/menuButton.module.css | 1 + .../Header/MainMenu/MobileMenu/index.tsx | 65 +++++++++++ .../MainMenu/MobileMenu/mobileMenu.module.css | 109 ++++++++++++++++++ .../Header/MainMenu/MyPagesMenu/index.tsx | 14 ++- .../MyPagesMenu/myPagesMenu.module.css | 24 +++- .../NavigationMenuItem/index.tsx | 29 +++-- .../navigationMenuItem.module.css | 7 ++ .../NavigationMenuItem/variants.ts | 15 +++ .../Header/MainMenu/NavigationMenu/index.tsx | 12 +- .../NavigationMenu/navigationMenu.module.css | 20 +++- .../MainMenu/NavigationMenu/variants.ts | 15 +++ components/Header/MainMenu/index.tsx | 19 ++- .../Header/MainMenu/mainMenu.module.css | 33 +++++- components/Header/TopMenu/Search/index.tsx | 6 +- .../Header/TopMenu/Search/search.module.css | 11 ++ .../Header/TopMenu/TopMenuButton/index.tsx | 14 --- .../TopMenuButton/topMenuButton.module.css | 9 -- components/Header/TopMenu/index.tsx | 29 +++-- components/Header/TopMenu/topMenu.module.css | 7 ++ components/Header/index.tsx | 12 +- components/Icons/ChevronRight.tsx | 41 +++---- components/Icons/Search.tsx | 2 +- components/Icons/Service.tsx | 36 ++++++ components/Icons/get-icon-by-icon-name.ts | 3 + components/Icons/index.tsx | 1 + .../TopMenu => }/LanguageSwitcher/index.tsx | 11 +- .../languageSwitcher.module.css | 16 ++- i18n/dictionaries/da.json | 2 + i18n/dictionaries/de.json | 2 + i18n/dictionaries/en.json | 2 + i18n/dictionaries/fi.json | 2 + i18n/dictionaries/no.json | 2 + i18n/dictionaries/sv.json | 2 + stores/main-menu.ts | 8 +- types/components/header/headerLink.ts | 3 + types/components/header/mainMenu.ts | 5 + types/components/header/mobileMenu.ts | 8 ++ types/components/header/navigationMenu.ts | 7 +- types/components/header/navigationMenuItem.ts | 7 +- types/components/header/topMenu.ts | 5 + types/components/icon.ts | 1 + 44 files changed, 526 insertions(+), 111 deletions(-) create mode 100644 components/Header/HeaderLink/headerLink.module.css create mode 100644 components/Header/HeaderLink/index.tsx create mode 100644 components/Header/MainMenu/MobileMenu/index.tsx create mode 100644 components/Header/MainMenu/MobileMenu/mobileMenu.module.css create mode 100644 components/Header/MainMenu/NavigationMenu/NavigationMenuItem/variants.ts create mode 100644 components/Header/MainMenu/NavigationMenu/variants.ts delete mode 100644 components/Header/TopMenu/TopMenuButton/index.tsx delete mode 100644 components/Header/TopMenu/TopMenuButton/topMenuButton.module.css create mode 100644 components/Icons/Service.tsx rename components/{Header/TopMenu => }/LanguageSwitcher/index.tsx (93%) rename components/{Header/TopMenu => }/LanguageSwitcher/languageSwitcher.module.css (78%) create mode 100644 types/components/header/headerLink.ts create mode 100644 types/components/header/mainMenu.ts create mode 100644 types/components/header/mobileMenu.ts create mode 100644 types/components/header/topMenu.ts diff --git a/app/globals.css b/app/globals.css index 58a807453..0c84c08ec 100644 --- a/app/globals.css +++ b/app/globals.css @@ -104,6 +104,7 @@ --max-width-text-block: 49.5rem; --mobile-site-header-height: 70.047px; --max-width-navigation: 89.5rem; + --main-menu-mobile-height: 75px; } * { diff --git a/components/Header/HeaderLink/headerLink.module.css b/components/Header/HeaderLink/headerLink.module.css new file mode 100644 index 000000000..7049d4857 --- /dev/null +++ b/components/Header/HeaderLink/headerLink.module.css @@ -0,0 +1,6 @@ +.topLink { + display: flex; + align-items: center; + gap: var(--Spacing-x1); + font-size: var(--typography-Caption-Regular-fontSize); +} diff --git a/components/Header/HeaderLink/index.tsx b/components/Header/HeaderLink/index.tsx new file mode 100644 index 000000000..9b2195ebb --- /dev/null +++ b/components/Header/HeaderLink/index.tsx @@ -0,0 +1,13 @@ +import Link from "@/components/TempDesignSystem/Link" + +import styles from "./headerLink.module.css" + +import { HeaderLinkProps } from "@/types/components/header/headerLink" + +export default function HeaderLink({ children, ...props }: HeaderLinkProps) { + return ( + + {children} + + ) +} diff --git a/components/Header/MainMenu/MainMenuButton/menuButton.module.css b/components/Header/MainMenu/MainMenuButton/menuButton.module.css index 9746f1808..1d999b3ad 100644 --- a/components/Header/MainMenu/MainMenuButton/menuButton.module.css +++ b/components/Header/MainMenu/MainMenuButton/menuButton.module.css @@ -2,6 +2,7 @@ display: flex; gap: var(--Spacing-x1); align-items: center; + width: 100%; background-color: transparent; color: var(--Base-Text-High-contrast); border-width: 0; diff --git a/components/Header/MainMenu/MobileMenu/index.tsx b/components/Header/MainMenu/MobileMenu/index.tsx new file mode 100644 index 000000000..616cd10bb --- /dev/null +++ b/components/Header/MainMenu/MobileMenu/index.tsx @@ -0,0 +1,65 @@ +"use client" + +import { Dialog, Modal } from "react-aria-components" +import { useIntl } from "react-intl" + +import useDropdownStore from "@/stores/main-menu" + +import { GiftIcon, SearchIcon, ServiceIcon } from "@/components/Icons" +import LanguageSwitcher from "@/components/LanguageSwitcher" + +import HeaderLink from "../../HeaderLink" +import NavigationMenu from "../NavigationMenu" + +import styles from "./mobileMenu.module.css" + +import { MobileMenuProps } from "@/types/components/header/mobileMenu" + +export default function MobileMenu({ + mainNavigation, + languageUrls, +}: MobileMenuProps) { + const intl = useIntl() + const { isHamburgerMenuOpen, toggleHamburgerMenu } = useDropdownStore() + + return ( + <> + + + + +
+ + + {intl.formatMessage({ id: "Find booking" })} + + + + {intl.formatMessage({ id: "Join Scandic Friends" })} + + + + {intl.formatMessage({ id: "Customer service" })} + + +
+
+
+ + ) +} diff --git a/components/Header/MainMenu/MobileMenu/mobileMenu.module.css b/components/Header/MainMenu/MobileMenu/mobileMenu.module.css new file mode 100644 index 000000000..a36886e21 --- /dev/null +++ b/components/Header/MainMenu/MobileMenu/mobileMenu.module.css @@ -0,0 +1,109 @@ +@keyframes slide-in { + from { + right: -100vw; + } + + to { + right: 0; + } +} + +.hamburger { + background-color: transparent; + border: none; + cursor: pointer; + justify-self: flex-start; + padding: 11px 8px 16px; + user-select: none; +} + +.bar, +.bar::after, +.bar::before { + background: var(--Base-Text-High-contrast); + border-radius: 2.3px; + display: inline-block; + height: 3px; + position: relative; + transition: all 0.2s; + width: 32px; +} + +.bar::after, +.bar::before { + content: ""; + left: 0; + position: absolute; + transform-origin: 2.286px center; +} + +.bar::after { + top: -8px; +} + +.bar::before { + top: 8px; +} + +.isExpanded .bar { + background: transparent; +} + +.isExpanded .bar::after, +.isExpanded .bar::before { + top: 0; + transform-origin: 50% 50%; + width: 32px; +} + +.isExpanded .bar::after { + transform: rotate(-45deg); +} + +.isExpanded .bar::before { + transform: rotate(45deg); +} + +@media screen and (min-width: 768px) { + .hamburger { + display: none; + } +} + +.overlay { + position: absolute; + top: var(--main-menu-mobile-height); + bottom: 0; + left: 0; + right: 0; +} + +.modal { + position: fixed; + right: auto; + top: var(--main-menu-mobile-height); + bottom: 0; + width: 100%; + background-color: var(--Base-Surface-Primary-light-Normal); +} + +.modal[data-entering] { + animation: slide-in 0.3s; +} +.modal[data-exiting] { + animation: slide-in 0.3s reverse; +} + +.dialog { + height: 100%; + overflow-y: auto; + display: grid; + align-content: space-between; +} + +.footer { + background-color: var(--Base-Surface-Subtle-Normal); + padding: var(--Spacing-x4) var(--Spacing-x2); + display: grid; + gap: var(--Spacing-x2); +} diff --git a/components/Header/MainMenu/MyPagesMenu/index.tsx b/components/Header/MainMenu/MyPagesMenu/index.tsx index 6407cf382..42cd370ab 100644 --- a/components/Header/MainMenu/MyPagesMenu/index.tsx +++ b/components/Header/MainMenu/MyPagesMenu/index.tsx @@ -35,7 +35,9 @@ export default function MyPagesMenu({ navigation, user }: MyPagesMenuProps) {
- {intl.formatMessage({ id: "Hi" })} {user.firstName}! + + {intl.formatMessage({ id: "Hi" })} {user.firstName}! +
) : ( - + - {intl.formatMessage({ id: "Log in/Join" })} + + {intl.formatMessage({ id: "Log in/Join" })} + ) } diff --git a/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css b/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css index 459fb6d9f..8d6b2fe1c 100644 --- a/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css +++ b/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css @@ -2,11 +2,8 @@ position: relative; } -.button { - font-weight: 600; -} - .chevron { + display: none; transition: transform 0.2s; } @@ -14,6 +11,12 @@ transform: rotate(180deg); } +.userName { + display: none; + font-weight: 600; + color: var(--Base-Text-High-contrast); +} + .dropdown { position: absolute; top: 46px; @@ -80,6 +83,15 @@ opacity: 0; } -.link:hover .arrow { - opacity: 1; +.loginLink { + display: flex; + align-items: center; + gap: var(--Spacing-x1); +} + +@media screen and (min-width: 768px) { + .userName, + .chevron { + display: initial; + } } diff --git a/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/index.tsx b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/index.tsx index 6d00244ff..4efc44086 100644 --- a/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/index.tsx +++ b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/index.tsx @@ -2,33 +2,46 @@ import { useState } from "react" -import { ChevronDownIcon } from "@/components/Icons" +import { ChevronDownIcon, ChevronRightIcon } from "@/components/Icons" import Link from "@/components/TempDesignSystem/Link" import MainMenuButton from "../../MainMenuButton" +import { navigationMenuItemVariants } from "./variants" import styles from "./navigationMenuItem.module.css" import { NavigationMenuItemProps } from "@/types/components/header/navigationMenuItem" -export default function MenuItem({ item }: NavigationMenuItemProps) { +export default function MenuItem({ item, variant }: NavigationMenuItemProps) { const { children, title, href, seeAllLinkText, infoCard } = item const [isExpanded, setIsExpanded] = useState(false) + const isMobile = variant === "mobile" function handleButtonClick() { setIsExpanded((prev) => !prev) } return children?.length ? ( - + {title} - + {isMobile ? ( + + ) : ( + + )} ) : ( - + {title} ) diff --git a/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/navigationMenuItem.module.css b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/navigationMenuItem.module.css index c743f0649..b509f4e73 100644 --- a/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/navigationMenuItem.module.css +++ b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/navigationMenuItem.module.css @@ -1,3 +1,10 @@ +.navigationMenuItem.mobile { + display: flex; + justify-content: space-between; + padding: var(--Spacing-x2) 0; + font-size: var(--typography-Subtitle-1-Mobile-fontSize); +} + .chevron { transition: transform 0.2s; } diff --git a/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/variants.ts b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/variants.ts new file mode 100644 index 000000000..06eead455 --- /dev/null +++ b/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/variants.ts @@ -0,0 +1,15 @@ +import { cva } from "class-variance-authority" + +import styles from "./navigationMenuItem.module.css" + +export const navigationMenuItemVariants = cva(styles.navigationMenuItem, { + variants: { + variant: { + default: styles.default, + mobile: styles.mobile, + }, + }, + defaultVariants: { + variant: "default", + }, +}) diff --git a/components/Header/MainMenu/NavigationMenu/index.tsx b/components/Header/MainMenu/NavigationMenu/index.tsx index f5168ab21..08534f56e 100644 --- a/components/Header/MainMenu/NavigationMenu/index.tsx +++ b/components/Header/MainMenu/NavigationMenu/index.tsx @@ -1,15 +1,19 @@ import NavigationMenuItem from "./NavigationMenuItem" +import { navigationMenuVariants } from "./variants" import styles from "./navigationMenu.module.css" import { NavigationMenuProps } from "@/types/components/header/navigationMenu" -export default function NavigationMenu({ items }: NavigationMenuProps) { +export default function NavigationMenu({ + items, + variant, +}: NavigationMenuProps) { return ( -
    +
      {items.map((item) => ( -
    • - +
    • +
    • ))}
    diff --git a/components/Header/MainMenu/NavigationMenu/navigationMenu.module.css b/components/Header/MainMenu/NavigationMenu/navigationMenu.module.css index 066aca610..6c554acde 100644 --- a/components/Header/MainMenu/NavigationMenu/navigationMenu.module.css +++ b/components/Header/MainMenu/NavigationMenu/navigationMenu.module.css @@ -1,8 +1,26 @@ .navigationMenu { list-style: none; margin: 0; - display: flex; justify-content: space-between; align-items: center; gap: var(--Spacing-x4); + display: none; +} + +.navigationMenu.mobile { + display: grid; + width: 100%; + gap: 0; + justify-content: stretch; + padding: var(--Spacing-x-one-and-half) var(--Spacing-x2) var(--Spacing-x2); +} + +.navigationMenu.mobile .item { + border-bottom: 1px solid var(--Base-Border-Subtle); +} + +@media screen and (min-width: 768px) { + .navigationMenu.default { + display: flex; + } } diff --git a/components/Header/MainMenu/NavigationMenu/variants.ts b/components/Header/MainMenu/NavigationMenu/variants.ts new file mode 100644 index 000000000..b1c37d49b --- /dev/null +++ b/components/Header/MainMenu/NavigationMenu/variants.ts @@ -0,0 +1,15 @@ +import { cva } from "class-variance-authority" + +import styles from "./navigationMenu.module.css" + +export const navigationMenuVariants = cva(styles.navigationMenu, { + variants: { + variant: { + default: styles.default, + mobile: styles.mobile, + }, + }, + defaultVariants: { + variant: "default", + }, +}) diff --git a/components/Header/MainMenu/index.tsx b/components/Header/MainMenu/index.tsx index 288400a4b..db7d448d2 100644 --- a/components/Header/MainMenu/index.tsx +++ b/components/Header/MainMenu/index.tsx @@ -6,12 +6,15 @@ import Image from "@/components/Image" import { getIntl } from "@/i18n" import { navigationMenuItems } from "../tempHeaderData" +import MobileMenu from "./MobileMenu" import MyPagesMenu from "./MyPagesMenu" import NavigationMenu from "./NavigationMenu" import styles from "./mainMenu.module.css" -export default async function MainMenu() { +import { MainMenuProps } from "@/types/components/header/mainMenu" + +export default async function MainMenu({ languageUrls }: MainMenuProps) { const intl = await getIntl() const myPagesNavigation = await serverClient().contentstack.myPages.navigation.get() @@ -28,13 +31,19 @@ export default async function MainMenu() { data-js="scandiclogoimg" data-nosvgsrc="/_static/img/scandic-logotype.png" itemProp="logo" - height={24} + height={22} src="/_static/img/scandic-logotype.svg" - width={113} + width={103} /> - - +
    + + + +
    ) diff --git a/components/Header/MainMenu/mainMenu.module.css b/components/Header/MainMenu/mainMenu.module.css index ddcb33627..26c13c8e3 100644 --- a/components/Header/MainMenu/mainMenu.module.css +++ b/components/Header/MainMenu/mainMenu.module.css @@ -7,8 +7,35 @@ .nav { max-width: var(--max-width-navigation); margin: 0 auto; - display: flex; - justify-content: space-between; + display: grid; + grid-template-columns: max-content 1fr; align-items: center; - gap: var(--Spacing-x3); + gap: var(--Spacing-x2); +} + +.menus { + display: flex; + justify-self: end; + align-items: center; + gap: var(--Spacing-x2); +} + +.logoLink { + display: inline-flex; + width: auto; +} + +.logo { + width: 6.4375rem; +} + +@media screen and (min-width: 768px) { + .nav { + display: flex; + justify-content: space-between; + gap: var(--Spacing-x3); + } + .menus { + display: contents; + } } diff --git a/components/Header/TopMenu/Search/index.tsx b/components/Header/TopMenu/Search/index.tsx index f0b3316a7..abd840bc0 100644 --- a/components/Header/TopMenu/Search/index.tsx +++ b/components/Header/TopMenu/Search/index.tsx @@ -4,15 +4,15 @@ import { useIntl } from "react-intl" import { SearchIcon } from "@/components/Icons" -import TopMenuButton from "../TopMenuButton" +import styles from "./search.module.css" export default function Search() { const intl = useIntl() return ( - + ) } diff --git a/components/Header/TopMenu/Search/search.module.css b/components/Header/TopMenu/Search/search.module.css index 004e01d19..45d5bb1b1 100644 --- a/components/Header/TopMenu/Search/search.module.css +++ b/components/Header/TopMenu/Search/search.module.css @@ -1,9 +1,20 @@ .button { background-color: transparent; color: var(--Base-Text-High-contrast); + font-family: var(--typography-Caption-Regular-fontFamily); + font-size: var(--typography-Caption-Regular-fontSize); border-width: 0; + padding: 0; cursor: pointer; display: flex; gap: var(--Spacing-x1); align-items: center; + width: 100%; +} + +@media screen and (min-width: 768px) { + .button { + font-size: var(--typography-Body-Bold-fontSize); + font-family: var(--typography-Body-Bold-fontFamily); + } } diff --git a/components/Header/TopMenu/TopMenuButton/index.tsx b/components/Header/TopMenu/TopMenuButton/index.tsx deleted file mode 100644 index 4e42b05e0..000000000 --- a/components/Header/TopMenu/TopMenuButton/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import styles from "./topMenuButton.module.css" - -import { TopMenuButtonProps } from "@/types/components/header/topMenuButton" - -export default function TopMenuButton({ - children, - ...props -}: TopMenuButtonProps) { - return ( - - ) -} diff --git a/components/Header/TopMenu/TopMenuButton/topMenuButton.module.css b/components/Header/TopMenu/TopMenuButton/topMenuButton.module.css deleted file mode 100644 index 004e01d19..000000000 --- a/components/Header/TopMenu/TopMenuButton/topMenuButton.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.button { - background-color: transparent; - color: var(--Base-Text-High-contrast); - border-width: 0; - cursor: pointer; - display: flex; - gap: var(--Spacing-x1); - align-items: center; -} diff --git a/components/Header/TopMenu/index.tsx b/components/Header/TopMenu/index.tsx index f1555a5bf..b47a6d36d 100644 --- a/components/Header/TopMenu/index.tsx +++ b/components/Header/TopMenu/index.tsx @@ -1,32 +1,29 @@ -import { serverClient } from "@/lib/trpc/server" - -import { GiftIcon } from "@/components/Icons" -import Link from "@/components/TempDesignSystem/Link" +import { GiftIcon, SearchIcon } from "@/components/Icons" +import LanguageSwitcher from "@/components/LanguageSwitcher" import { getIntl } from "@/i18n" -import LanguageSwitcher from "./LanguageSwitcher" -import Search from "./Search" +import HeaderLink from "../HeaderLink" import styles from "./topMenu.module.css" -export default async function TopMenu() { - const intl = await getIntl() - const languages = await serverClient().contentstack.languageSwitcher.get() +import { TopMenuProps } from "@/types/components/header/topMenu" - if (!languages) { - return null - } +export default async function TopMenu({ languageUrls }: TopMenuProps) { + const intl = await getIntl() return (
    - + {intl.formatMessage({ id: "Join Scandic Friends" })} - +
    - - + + + + {intl.formatMessage({ id: "Find booking" })} +
    diff --git a/components/Header/TopMenu/topMenu.module.css b/components/Header/TopMenu/topMenu.module.css index e78f57d92..17a739989 100644 --- a/components/Header/TopMenu/topMenu.module.css +++ b/components/Header/TopMenu/topMenu.module.css @@ -1,4 +1,5 @@ .topMenu { + display: none; background-color: var(--Base-Surface-Subtle-Normal); padding: var(--Spacing-x2) var(--Spacing-x-one-and-half); border-bottom: 1px solid var(--Base-Border-Subtle); @@ -17,3 +18,9 @@ gap: var(--Spacing-x2); align-items: center; } + +@media screen and (min-width: 768px) { + .topMenu { + display: block; + } +} diff --git a/components/Header/index.tsx b/components/Header/index.tsx index d6693a52b..d4e01de0f 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -1,13 +1,21 @@ +import { serverClient } from "@/lib/trpc/server" + import MainMenu from "./MainMenu" import TopMenu from "./TopMenu" import styles from "./header.module.css" export default async function Header() { + const languages = await serverClient().contentstack.languageSwitcher.get() + + if (!languages) { + return null + } + return (
    - - + +
    ) } diff --git a/components/Icons/ChevronRight.tsx b/components/Icons/ChevronRight.tsx index 1b66b90a3..9930ac095 100644 --- a/components/Icons/ChevronRight.tsx +++ b/components/Icons/ChevronRight.tsx @@ -11,32 +11,29 @@ export default function ChevronRightIcon({ return ( - - - - - - - + + + + + ) diff --git a/components/Icons/Search.tsx b/components/Icons/Search.tsx index 3e91f1f5c..aa9f15e52 100644 --- a/components/Icons/Search.tsx +++ b/components/Icons/Search.tsx @@ -2,7 +2,7 @@ import { iconVariants } from "./variants" import type { IconProps } from "@/types/components/icon" -export default function GiftIcon({ className, color, ...props }: IconProps) { +export default function SearchIcon({ className, color, ...props }: IconProps) { const classNames = iconVariants({ className, color }) return ( + + + + + + + + ) +} diff --git a/components/Icons/get-icon-by-icon-name.ts b/components/Icons/get-icon-by-icon-name.ts index 3c7a37d7e..79feb4b0c 100644 --- a/components/Icons/get-icon-by-icon-name.ts +++ b/components/Icons/get-icon-by-icon-name.ts @@ -41,6 +41,7 @@ import { RestaurantIcon, SaunaIcon, SearchIcon, + ServiceIcon, TshirtWashIcon, WarningTriangle, WifiIcon, @@ -128,6 +129,8 @@ export function getIconByIconName(icon?: IconName): FC | null { return SaunaIcon case IconName.Search: return SearchIcon + case IconName.Service: + return ServiceIcon case IconName.Tripadvisor: return TripAdvisorIcon case IconName.TshirtWash: diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx index 0dbb3b628..31abcd5ca 100644 --- a/components/Icons/index.tsx +++ b/components/Icons/index.tsx @@ -39,6 +39,7 @@ export { default as RestaurantIcon } from "./Restaurant" export { default as SaunaIcon } from "./Sauna" export { default as ScandicLogoIcon } from "./ScandicLogo" export { default as SearchIcon } from "./Search" +export { default as ServiceIcon } from "./Service" export { default as TshirtWashIcon } from "./TshirtWash" export { default as WarningTriangle } from "./WarningTriangle" export { default as WifiIcon } from "./Wifi" diff --git a/components/Header/TopMenu/LanguageSwitcher/index.tsx b/components/LanguageSwitcher/index.tsx similarity index 93% rename from components/Header/TopMenu/LanguageSwitcher/index.tsx rename to components/LanguageSwitcher/index.tsx index 638a58dba..e5ab88c5e 100644 --- a/components/Header/TopMenu/LanguageSwitcher/index.tsx +++ b/components/LanguageSwitcher/index.tsx @@ -8,8 +8,6 @@ import useDropdownStore from "@/stores/main-menu" import { CheckIcon, ChevronDownIcon, GlobeIcon } from "@/components/Icons" import useLang from "@/hooks/useLang" -import TopMenuButton from "../TopMenuButton" - import styles from "./languageSwitcher.module.css" import { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher" @@ -22,7 +20,11 @@ export default function LanguageSwitcher({ urls }: LanguageSwitcherProps) { return (
    - + +
    diff --git a/components/Header/TopMenu/LanguageSwitcher/languageSwitcher.module.css b/components/LanguageSwitcher/languageSwitcher.module.css similarity index 78% rename from components/Header/TopMenu/LanguageSwitcher/languageSwitcher.module.css rename to components/LanguageSwitcher/languageSwitcher.module.css index ff2301963..1eeeab77b 100644 --- a/components/Header/TopMenu/LanguageSwitcher/languageSwitcher.module.css +++ b/components/LanguageSwitcher/languageSwitcher.module.css @@ -5,14 +5,20 @@ .button { background-color: transparent; color: var(--Base-Text-High-contrast); + font-family: var(--typography-Caption-Regular-fontFamily); + font-size: var(--typography-Caption-Regular-fontSize); border-width: 0; + padding: 0; cursor: pointer; - display: flex; + display: grid; + grid-template-columns: repeat(2, max-content) 1fr; gap: var(--Spacing-x1); align-items: center; + width: 100%; } .chevron { + justify-self: end; transition: transform 0.2s; } @@ -78,3 +84,11 @@ .link:hover { font-weight: 600; } + +@media screen and (min-width: 768px) { + .button { + grid-template-columns: repeat(3, max-content); + font-size: var(--typography-Body-Bold-fontSize); + font-family: var(--typography-Body-Bold-fontFamily); + } +} diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index f4553b9ce..43b927104 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -44,6 +44,7 @@ "Country code": "Landekode", "Credit card deleted successfully": "Kreditkort blev slettet", "Current password": "Nuværende kodeord", + "Customer service": "Kundeservice", "Date of Birth": "Fødselsdato", "Day": "Dag", "Description": "Beskrivelse", @@ -94,6 +95,7 @@ "Members": "Medlemmer", "Membership cards": "Medlemskort", "Membership ID": "Medlems-id", + "Menu": "Menu", "Modify": "Ændre", "Month": "Måned", "My communication preferences": "Mine kommunikationspræferencer", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index b80e56960..8814ff721 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -43,6 +43,7 @@ "Country code": "Landesvorwahl", "Credit card deleted successfully": "Kreditkarte erfolgreich gelöscht", "Current password": "Aktuelles Passwort", + "Customer service": "Kundendienst", "Date of Birth": "Geburtsdatum", "Day": "Tag", "Description": "Beschreibung", @@ -92,6 +93,7 @@ "Members": "Mitglieder", "Membership cards": "Mitgliedskarten", "Membership ID": "Mitglieds-ID", + "Menu": "Menu", "Modify": "Ändern", "Month": "Monat", "My communication preferences": "Meine Kommunikationseinstellungen", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index f86bab933..ea205dd05 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -44,6 +44,7 @@ "Country code": "Country code", "Credit card deleted successfully": "Credit card deleted successfully", "Current password": "Current password", + "Customer service": "Customer service", "Date of Birth": "Date of Birth", "Day": "Day", "Description": "Description", @@ -99,6 +100,7 @@ "Members": "Members", "Membership cards": "Membership cards", "Membership ID": "Membership ID", + "Menu": "Menu", "Modify": "Modify", "Month": "Month", "My communication preferences": "My communication preferences", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index a3dd9cff8..5781dea73 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -44,6 +44,7 @@ "Country code": "Maatunnus", "Credit card deleted successfully": "Luottokortti poistettu onnistuneesti", "Current password": "Nykyinen salasana", + "Customer service": "Asiakaspalvelu", "Date of Birth": "Syntymäaika", "Day": "Päivä", "Description": "Kuvaus", @@ -93,6 +94,7 @@ "Members": "Jäsenet", "Membership cards": "Jäsenkortit", "Membership ID": "Jäsentunnus", + "Menu": "Menu", "Modify": "Muokkaa", "Month": "Kuukausi", "My communication preferences": "Viestintämieltymykseni", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index 8dbf2cb2c..0f38a89b0 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -42,6 +42,7 @@ "Could not find requested resource": "Kunne ikke finne den forespurte ressursen", "Country": "Land", "Country code": "Landskode", + "Customer service": "Kundeservice", "Credit card deleted successfully": "Kredittkort slettet", "Current password": "Nåværende passord", "Date of Birth": "Fødselsdato", @@ -94,6 +95,7 @@ "Members": "Medlemmer", "Membership cards": "Medlemskort", "Membership ID": "Medlems-ID", + "Menu": "Menu", "Modify": "Endre", "Month": "Måned", "My communication preferences": "Mine kommunikasjonspreferanser", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 25eb5acf5..53f38241e 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -44,6 +44,7 @@ "Country code": "Landskod", "Credit card deleted successfully": "Kreditkort har tagits bort", "Current password": "Nuvarande lösenord", + "Customer service": "Kundservice", "Date of Birth": "Födelsedatum", "Day": "Dag", "Description": "Beskrivning", @@ -96,6 +97,7 @@ "Members": "Medlemmar", "Membership cards": "Medlemskort", "Membership ID": "Medlems-ID", + "Menu": "Meny", "Modify": "Ändra", "Month": "Månad", "My communication preferences": "Mina kommunikationspreferenser", diff --git a/stores/main-menu.ts b/stores/main-menu.ts index fe9fc50f3..008cce9b7 100644 --- a/stores/main-menu.ts +++ b/stores/main-menu.ts @@ -19,13 +19,7 @@ const useDropdownStore = create((set) => ({ isMyPagesMenuOpen: false, isLanguageSwitcherOpen: false, toggleHamburgerMenu: () => - set((state) => { - // Close the other dropdown if it's open - if (!state.isHamburgerMenuOpen && state.isMyPagesMobileMenuOpen) { - set({ isMyPagesMobileMenuOpen: false }) - } - return { isHamburgerMenuOpen: !state.isHamburgerMenuOpen } - }), + set((state) => ({ isHamburgerMenuOpen: !state.isHamburgerMenuOpen })), toggleMyPagesMobileMenu: () => set((state) => { // Close the other dropdown if it's open diff --git a/types/components/header/headerLink.ts b/types/components/header/headerLink.ts new file mode 100644 index 000000000..671ab6d0e --- /dev/null +++ b/types/components/header/headerLink.ts @@ -0,0 +1,3 @@ +import { LinkProps } from "@/components/TempDesignSystem/Link/link" + +export interface HeaderLinkProps extends React.PropsWithChildren {} diff --git a/types/components/header/mainMenu.ts b/types/components/header/mainMenu.ts new file mode 100644 index 000000000..a867be31b --- /dev/null +++ b/types/components/header/mainMenu.ts @@ -0,0 +1,5 @@ +import { LanguageSwitcherData } from "@/types/requests/languageSwitcher" + +export interface MainMenuProps { + languageUrls: LanguageSwitcherData +} diff --git a/types/components/header/mobileMenu.ts b/types/components/header/mobileMenu.ts new file mode 100644 index 000000000..79f11a563 --- /dev/null +++ b/types/components/header/mobileMenu.ts @@ -0,0 +1,8 @@ +import { MainNavigationItem } from "./mainNavigationItem" + +import { LanguageSwitcherData } from "@/types/requests/languageSwitcher" + +export interface MobileMenuProps { + languageUrls: LanguageSwitcherData + mainNavigation: MainNavigationItem[] +} diff --git a/types/components/header/navigationMenu.ts b/types/components/header/navigationMenu.ts index f429d557d..11642b11f 100644 --- a/types/components/header/navigationMenu.ts +++ b/types/components/header/navigationMenu.ts @@ -1,5 +1,10 @@ +import { VariantProps } from "class-variance-authority" + +import { navigationMenuVariants } from "@/components/Header/MainMenu/NavigationMenu/variants" + import { MainNavigationItem } from "@/types/components/header/mainNavigationItem" -export interface NavigationMenuProps { +export interface NavigationMenuProps + extends VariantProps { items: MainNavigationItem[] } diff --git a/types/components/header/navigationMenuItem.ts b/types/components/header/navigationMenuItem.ts index d53c2313a..942b706c8 100644 --- a/types/components/header/navigationMenuItem.ts +++ b/types/components/header/navigationMenuItem.ts @@ -1,5 +1,10 @@ +import { VariantProps } from "class-variance-authority" + +import { navigationMenuItemVariants } from "@/components/Header/MainMenu/NavigationMenu/NavigationMenuItem/variants" + import { MainNavigationItem } from "@/types/components/header/mainNavigationItem" -export interface NavigationMenuItemProps { +export interface NavigationMenuItemProps + extends VariantProps { item: MainNavigationItem } diff --git a/types/components/header/topMenu.ts b/types/components/header/topMenu.ts new file mode 100644 index 000000000..4e20a6e7f --- /dev/null +++ b/types/components/header/topMenu.ts @@ -0,0 +1,5 @@ +import { LanguageSwitcherData } from "@/types/requests/languageSwitcher" + +export interface TopMenuProps { + languageUrls: LanguageSwitcherData +} diff --git a/types/components/icon.ts b/types/components/icon.ts index ed0d3da3b..0e705b7e6 100644 --- a/types/components/icon.ts +++ b/types/components/icon.ts @@ -46,6 +46,7 @@ export enum IconName { Restaurant = "Restaurant", Sauna = "Sauna", Search = "Search", + Service = "Service", Tripadvisor = "Tripadvisor", TshirtWash = "TshirtWash", Wifi = "Wifi",