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 ( <> + + ) : null} + +
+ + {intl.formatMessage({ id: "Select your language" })} + + +
+ + ) +} 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 (
-
+ {isLanguageSwitcherOpen ? ( + ) : null} - -
- - {intl.formatMessage({ id: "Select your language" })} - - -
) 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) {