refactor(SW-337): css only approach for sticky tab navigation
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user