refactor(SW-337): css only approach for sticky tab navigation

This commit is contained in:
Chuma McPhoy
2024-09-06 09:52:21 +02:00
parent 9a0768b49e
commit 0ddbd3c549
4 changed files with 44 additions and 63 deletions

View File

@@ -1,5 +1,4 @@
"use client"
import { useEffect, useRef } from "react"
import { useIntl } from "react-intl"
import Link from "@/components/TempDesignSystem/Link"
@@ -12,25 +11,6 @@ import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
export default function TabNavigation() {
const hash = useHash()
const intl = useIntl()
const navRef = useRef<HTMLElement>(null)
useEffect(() => {
const nav = navRef.current
if (!nav) return
const sticky = nav.offsetTop
const handleScroll = () => {
if (window.scrollY > sticky) {
nav.classList.add(styles.sticky)
} else {
nav.classList.remove(styles.sticky)
}
}
window.addEventListener("scroll", handleScroll)
return () => window.removeEventListener("scroll", handleScroll)
}, [])
const hotelTabLinks: { href: HotelHashValues; text: string }[] = [
{ href: HotelHashValues.overview, text: "Overview" },
@@ -43,24 +23,26 @@ export default function TabNavigation() {
]
return (
<nav ref={navRef} className={styles.tabsContainer}>
{hotelTabLinks.map((link) => {
const isActive =
hash === link.href ||
(hash === "" && link.href === HotelHashValues.overview)
return (
<Link
key={link.href}
href={link.href}
active={isActive}
variant="tab"
color="burgundy"
textDecoration="none"
>
{intl.formatMessage({ id: link.text })}
</Link>
)
})}
</nav>
<div className={styles.stickyWrapper}>
<nav className={styles.tabsContainer}>
{hotelTabLinks.map((link) => {
const isActive =
hash === link.href ||
(hash === "" && link.href === HotelHashValues.overview)
return (
<Link
key={link.href}
href={link.href}
active={isActive}
variant="tab"
color="burgundy"
textDecoration="none"
>
{intl.formatMessage({ id: link.text })}
</Link>
)
})}
</nav>
</div>
)
}

View File

@@ -1,30 +1,24 @@
.tabsContainer {
display: flex;
.stickyWrapper {
position: sticky;
top: 0;
z-index: 10;
background-color: var(--Base-Surface-Subtle-Normal);
border-bottom: 1px solid var(--Base-Border-Subtle);
overflow-x: auto;
white-space: nowrap;
}
.tabsContainer {
display: flex;
gap: var(--Spacing-x4);
justify-content: flex-start;
padding: 0 var(--Spacing-x2);
max-width: 100vw;
width: 100%;
background-color: var(--Base-Surface-Subtle-Normal);
z-index: 1000;
}
.sticky {
position: fixed;
top: 0;
left: 0;
right: 0;
border-bottom: 1px solid var(--Base-Border-Subtle);
width: 100%;
}
@media screen and (min-width: 1367px) {
.tabsContainer {
padding: 0 var(--Spacing-x5);
}
.sticky {
max-width: calc(100% - var(--hotel-page-map-desktop-width));
}
}

View File

@@ -2,20 +2,27 @@
display: grid;
max-width: var(--max-width);
margin: 0 auto;
grid-template-areas:
"hotelImages"
"tabNavigation"
"mainSection"
"mapContainer";
}
.topSection {
.hotelImages {
grid-area: hotelImages;
background-color: var(--Base-Surface-Subtle-Normal);
border-bottom: 1px solid var(--Base-Border-Subtle);
}
.mainSection {
grid-area: mainSection;
display: grid;
gap: var(--Spacing-x9);
padding: var(--Spacing-x4) var(--Spacing-x2);
}
.mapContainer {
grid-area: mapContainer;
display: none;
}
@@ -27,13 +34,11 @@
@media screen and (min-width: 1367px) {
.pageContainer {
grid-template-areas:
"topSection mapContainer"
"hotelImages mapContainer"
"tabNavigation mapContainer"
"mainSection mapContainer";
grid-template-columns: 1fr var(--hotel-page-map-desktop-width);
}
.topSection {
grid-area: topSection;
}
.mainSection {
grid-area: mainSection;
padding: var(--Spacing-x6) 0;

View File

@@ -32,10 +32,10 @@ export default async function HotelPage() {
return (
<div className={styles.pageContainer}>
<div className={styles.topSection}>
<div className={styles.hotelImages}>
<PreviewImages images={hotelImages} />
<TabNavigation />
</div>
<TabNavigation />
<main className={styles.mainSection}>
<div className={styles.introContainer}>
<IntroSection