diff --git a/components/Header/MainMenu/MobileMenu/index.tsx b/components/Header/MainMenu/MobileMenu/index.tsx
index d9e63fc5b..216bd7ac9 100644
--- a/components/Header/MainMenu/MobileMenu/index.tsx
+++ b/components/Header/MainMenu/MobileMenu/index.tsx
@@ -21,7 +21,12 @@ export default function MobileMenu({
languageUrls,
}: MobileMenuProps) {
const intl = useIntl()
- const { isHamburgerMenuOpen, toggleHamburgerMenu } = useDropdownStore()
+ const {
+ isHamburgerMenuOpen,
+ isMyPagesMobileMenuOpen,
+ toggleHamburgerMenu,
+ toggleMyPagesMobileMenu,
+ } = useDropdownStore()
useHandleKeyUp((event: KeyboardEvent) => {
if (event.key === "Escape" && isHamburgerMenuOpen) {
@@ -29,11 +34,19 @@ export default function MobileMenu({
}
})
+ function handleHamburgerClick() {
+ if (isMyPagesMobileMenuOpen) {
+ toggleMyPagesMobileMenu()
+ } else {
+ toggleHamburgerMenu()
+ }
+ }
+
return (
<>
{intl.formatMessage({ id: "Customer service" })}
-
+
diff --git a/components/Header/MainMenu/MyPagesMenu/index.tsx b/components/Header/MainMenu/MyPagesMenu/index.tsx
index 02d30cad7..78a8987db 100644
--- a/components/Header/MainMenu/MyPagesMenu/index.tsx
+++ b/components/Header/MainMenu/MyPagesMenu/index.tsx
@@ -41,15 +41,15 @@ export default function MyPagesMenu({ navigation, user }: MyPagesMenuProps) {
color="red"
/>
-
-
-
+ {isMyPagesMenuOpen ? (
+
+
+
+ ) : null}
)
}
diff --git a/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css b/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css
index d322955e3..6f5a1805b 100644
--- a/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css
+++ b/components/Header/MainMenu/MyPagesMenu/myPagesMenu.module.css
@@ -25,7 +25,6 @@
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
min-width: 20rem;
z-index: 1;
- display: none;
}
/* Triangle above dropdown */
diff --git a/components/Header/TopMenu/index.tsx b/components/Header/TopMenu/index.tsx
index b47a6d36d..cf2fd38ac 100644
--- a/components/Header/TopMenu/index.tsx
+++ b/components/Header/TopMenu/index.tsx
@@ -19,7 +19,7 @@ export default async function TopMenu({ languageUrls }: TopMenuProps) {
{intl.formatMessage({ id: "Join Scandic Friends" })}
-
+
{intl.formatMessage({ id: "Find booking" })}
diff --git a/components/LanguageSwitcher/LanguageSwitcherContent/index.tsx b/components/LanguageSwitcher/LanguageSwitcherContent/index.tsx
new file mode 100644
index 000000000..6c54735d4
--- /dev/null
+++ b/components/LanguageSwitcher/LanguageSwitcherContent/index.tsx
@@ -0,0 +1,77 @@
+"use client"
+
+import { useIntl } from "react-intl"
+
+import { Lang, languages } from "@/constants/languages"
+import useDropdownStore from "@/stores/main-menu"
+
+import { CheckIcon, ChevronLeftIcon } from "@/components/Icons"
+import Link from "@/components/TempDesignSystem/Link"
+import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
+import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
+import useLang from "@/hooks/useLang"
+import { useTrapFocus } from "@/hooks/useTrapFocus"
+
+import styles from "./languageSwitcher.module.css"
+
+import { LanguageSwitcherProps } from "@/types/components/header/languageSwitcher"
+
+export default function LanguageSwitcherContent({
+ urls,
+ variant,
+}: LanguageSwitcherProps) {
+ const intl = useIntl()
+ const currentLanguage = useLang()
+ const { isLanguageSwitcherOpen, toggleLanguageSwitcher } = useDropdownStore()
+ const languageSwitcherRef = useTrapFocus()
+ const urlKeys = Object.keys(urls) as Lang[]
+
+ useHandleKeyUp((event: KeyboardEvent) => {
+ if (event.key === "Escape" && isLanguageSwitcherOpen) {
+ toggleLanguageSwitcher()
+ }
+ })
+
+ return (
+
+ {variant === "mobileHeader" ? (
+
+
+
+ ) : null}
+
+
+
+ {intl.formatMessage({ id: "Select your language" })}
+
+
+ {urlKeys.map((key) => {
+ const url = urls[key]?.url
+ const isActive = currentLanguage === key
+ if (url) {
+ return (
+ -
+
+ {languages[key]}
+ {isActive ? : null}
+
+
+ )
+ }
+ })}
+
+
+
+ )
+}
diff --git a/components/LanguageSwitcher/LanguageSwitcherContent/languageSwitcher.module.css b/components/LanguageSwitcher/LanguageSwitcherContent/languageSwitcher.module.css
new file mode 100644
index 000000000..4f253bd4b
--- /dev/null
+++ b/components/LanguageSwitcher/LanguageSwitcherContent/languageSwitcher.module.css
@@ -0,0 +1,160 @@
+@keyframes slide-in {
+ from {
+ right: -100vw;
+ }
+
+ to {
+ right: 0;
+ }
+}
+
+.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: 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;
+}
+
+.chevron.isExpanded {
+ transform: rotate(180deg);
+}
+
+.dropdown {
+ position: fixed;
+ top: var(--main-menu-mobile-height);
+ right: -100vw;
+ bottom: 0;
+ width: 100%;
+ background-color: var(--Base-Surface-Primary-light-Normal);
+ transition: right 0.3s;
+}
+
+.dropdown.isExpanded {
+ display: block;
+ right: 0;
+}
+
+.backWrapper {
+ background-color: var(--Base-Surface-Secondary-light-Normal);
+ padding: var(--Spacing-x2);
+}
+
+.backButton {
+ background-color: transparent;
+ border: none;
+ color: var(--Base-Text-High-contrast);
+ font-family: var(--typography-Subtitle-1-fontFamily);
+ font-weight: var(--typography-Subtitle-1-fontWeight);
+ font-size: var(--typography-Subtitle-1-Mobile-fontSize);
+ padding: 0;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: var(--Spacing-x1);
+}
+
+.languageWrapper {
+ display: grid;
+ gap: var(--Spacing-x3);
+ padding: var(--Spacing-x3) var(--Spacing-x2);
+}
+
+.subtitle {
+ font-family: var(--typography-Subtitle-2-fontFamily);
+ font-size: var(--typography-Subtitle-2-Mobile-fontSize);
+ font-weight: var(--typography-Subtitle-2-fontWeight);
+ color: var(--Base-Text-High-contrast, #4d001b);
+}
+
+.list {
+ list-style: none;
+}
+
+.link {
+ color: var(--Scandic-Brand-Burgundy);
+ font-family: var(--typography-Body-Regular-fontFamily);
+ font-size: var(--typography-Body-Regular-fontSize);
+ line-height: var(--typography-Body-Regular-lineHeight);
+ letter-spacing: var(--typography-Body-Regular-letterSpacing);
+ padding: var(--Spacing-x1);
+ border-radius: var(--Corner-radius-Medium);
+ display: flex;
+ gap: var(--Spacing-x1);
+ justify-content: space-between;
+ align-items: center;
+ text-decoration: none;
+ border-radius: var(--Corner-radius-Medium);
+}
+
+.link.active,
+.link:hover {
+ background-color: var(--Base-Surface-Primary-light-Hover-alt);
+ font-weight: 600;
+}
+
+@media screen and (min-width: 768px) {
+ .languageSwitcher {
+ position: relative;
+ }
+
+ .backWrapper,
+ .backButton {
+ display: none;
+ }
+
+ .languageWrapper {
+ padding: var(--Spacing-x2) var(--Spacing-x3);
+ }
+
+ .subtitle {
+ display: none;
+ }
+
+ .dropdown {
+ position: absolute;
+ top: 2.25rem;
+ background-color: var(--Base-Surface-Primary-light-Normal);
+ border-radius: var(--Corner-radius-Large);
+ box-shadow: 0px 0px 14px 6px #0000001a;
+ display: none;
+ min-width: 12.5rem;
+ z-index: 1;
+ bottom: auto;
+ }
+
+ /* Triangle above dropdown */
+ .dropdown::before {
+ content: "";
+ position: absolute;
+ top: -1.25rem;
+ right: 2.4rem;
+ transform: rotate(180deg);
+ border-width: 0.75rem;
+ border-style: solid;
+ border-color: var(--Base-Surface-Primary-light-Normal) transparent
+ transparent transparent;
+ }
+
+ .button {
+ grid-template-columns: repeat(3, max-content);
+ font-size: var(--typography-Body-Bold-fontSize);
+ font-family: var(--typography-Body-Bold-fontFamily);
+ }
+
+ .link.active:not(:hover) {
+ background-color: transparent;
+ }
+}
diff --git a/components/LanguageSwitcher/LanguageSwitcherContent/variants.ts b/components/LanguageSwitcher/LanguageSwitcherContent/variants.ts
new file mode 100644
index 000000000..b0c919382
--- /dev/null
+++ b/components/LanguageSwitcher/LanguageSwitcherContent/variants.ts
@@ -0,0 +1,17 @@
+import { cva } from "class-variance-authority"
+
+import styles from "./languageSwitcher.module.css"
+
+export const languageSwitcherContentVariants = cva(styles.languageSwitcher, {
+ variants: {
+ variant: {
+ mobileHeader: styles.mobileHeader,
+ mobileFooter: styles.mobileFooter,
+ desktopHeader: styles.desktopHeader,
+ desktopFooter: styles.desktopFooter,
+ },
+ },
+ defaultVariants: {
+ variant: "desktopHeader",
+ },
+})
diff --git a/components/LanguageSwitcher/index.tsx b/components/LanguageSwitcher/index.tsx
index 2b13fb306..04be38d0d 100644
--- a/components/LanguageSwitcher/index.tsx
+++ b/components/LanguageSwitcher/index.tsx
@@ -1,44 +1,27 @@
"use client"
-import Link from "next/link"
import { useIntl } from "react-intl"
-import { Lang, languages } from "@/constants/languages"
+import { languages } from "@/constants/languages"
import useDropdownStore from "@/stores/main-menu"
-import {
- CheckIcon,
- ChevronDownIcon,
- ChevronLeftIcon,
- GlobeIcon,
-} from "@/components/Icons"
-import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
+import { ChevronDownIcon, GlobeIcon } from "@/components/Icons"
import useLang from "@/hooks/useLang"
-import { useTrapFocus } from "@/hooks/useTrapFocus"
-import Subtitle from "../TempDesignSystem/Text/Subtitle"
+import LanguageSwitcherContent from "./LanguageSwitcherContent"
import styles from "./languageSwitcher.module.css"
-import { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
+import { LanguageSwitcherProps } from "@/types/components/header/languageSwitcher"
export default function LanguageSwitcher({
urls,
- location = "header",
+ variant,
}: LanguageSwitcherProps) {
const intl = useIntl()
- const languageSwitcherRef = useTrapFocus()
const currentLanguage = useLang()
const { toggleLanguageSwitcher, isLanguageSwitcherOpen } = useDropdownStore()
- const urlKeys = Object.keys(urls) as Lang[]
-
- useHandleKeyUp((event: KeyboardEvent) => {
- if (event.key === "Escape" && isLanguageSwitcherOpen) {
- toggleLanguageSwitcher()
- }
- })
-
return (
)
diff --git a/components/LanguageSwitcher/variants.ts b/components/LanguageSwitcher/variants.ts
new file mode 100644
index 000000000..9338ea6d0
--- /dev/null
+++ b/components/LanguageSwitcher/variants.ts
@@ -0,0 +1,17 @@
+import { cva } from "class-variance-authority"
+
+import styles from "./languageSwitcher.module.css"
+
+export const languageSwitcherVariants = cva(styles.languageSwitcher, {
+ variants: {
+ variant: {
+ mobileHeader: styles.mobileHeader,
+ mobileFooter: styles.mobileFooter,
+ desktopHeader: styles.desktopHeader,
+ desktopFooter: styles.desktopFooter,
+ },
+ },
+ defaultVariants: {
+ variant: "desktopHeader",
+ },
+})
diff --git a/hooks/useTrapFocus.ts b/hooks/useTrapFocus.ts
index b7d1311c8..767143105 100644
--- a/hooks/useTrapFocus.ts
+++ b/hooks/useTrapFocus.ts
@@ -45,6 +45,7 @@ export function useTrapFocus(opts?: OptionsType) {
const first = tabbableElements[0]
const last = tabbableElements[tabbableElements.length - 1]
+ console.log(tabbableElements)
const currentActiveElement = document.activeElement
// Scope current tabs to current root element
if (isWithinCurrentElementScope([...tabbableElements, ref.current])) {
diff --git a/types/components/current/languageSwitcher.ts b/types/components/current/languageSwitcher.ts
index dd39494a9..44b49fff6 100644
--- a/types/components/current/languageSwitcher.ts
+++ b/types/components/current/languageSwitcher.ts
@@ -7,5 +7,4 @@ export type LanguageSwitcherLink = {
export type LanguageSwitcherProps = {
urls: LanguageSwitcherData
- location?: "header" | "footer"
}
diff --git a/types/components/header/languageSwitcher.ts b/types/components/header/languageSwitcher.ts
index 819090906..694e12b48 100644
--- a/types/components/header/languageSwitcher.ts
+++ b/types/components/header/languageSwitcher.ts
@@ -1,5 +1,10 @@
+import { VariantProps } from "class-variance-authority"
+
+import { languageSwitcherVariants } from "@/components/LanguageSwitcher/variants"
+
import { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
-export interface LanguageSwitcherProps {
+export interface LanguageSwitcherProps
+ extends VariantProps {
urls: LanguageSwitcherData
}
diff --git a/utils/tabbable.ts b/utils/tabbable.ts
index b38352c99..30ebfbd9f 100644
--- a/utils/tabbable.ts
+++ b/utils/tabbable.ts
@@ -20,9 +20,19 @@ function hidesContents(element: HTMLElement) {
// Otherwise we need to check some styles
const style = window.getComputedStyle(element)
- return zeroSize
- ? style.getPropertyValue("overflow") !== "visible"
- : style.getPropertyValue("display") === "none"
+ console.log({
+ element,
+ zeroSize,
+ display: style.display,
+ overflow: style.overflow,
+ returns:
+ style.getPropertyValue("display") === "none" ||
+ (zeroSize && style.getPropertyValue("overflow") !== "visible"),
+ })
+ return (
+ style.getPropertyValue("display") === "none" ||
+ (zeroSize && style.getPropertyValue("overflow") !== "visible")
+ )
}
function visible(element: any) {