feat(SW-441): Implemented useScrollSpy hook
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
.cardContainer {
|
||||
scroll-margin-top: var(--hotel-page-scroll-margin-top);
|
||||
}
|
||||
|
||||
.spanOne {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function FacilitiesCardGrid({
|
||||
}
|
||||
|
||||
return (
|
||||
<section id={imageCard.card.id}>
|
||||
<section id={imageCard.card.id} className={styles.cardContainer}>
|
||||
<Grids.Stackable className={styles.desktopGrid}>
|
||||
{facilitiesCardGrid.map((card: FacilityCardType) => (
|
||||
<Card {...card} key={card.id} className={getCardClassName(card)} />
|
||||
|
||||
@@ -13,6 +13,7 @@ import { RoomCard } from "./RoomCard"
|
||||
|
||||
import styles from "./rooms.module.css"
|
||||
|
||||
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
||||
import type { RoomsProps } from "./types"
|
||||
|
||||
export function Rooms({ rooms }: RoomsProps) {
|
||||
@@ -50,8 +51,11 @@ export function Rooms({ rooms }: RoomsProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionContainer id="rooms-section">
|
||||
<div ref={scrollRef}></div>
|
||||
<SectionContainer
|
||||
id={HotelHashValues.rooms}
|
||||
className={styles.roomsContainer}
|
||||
>
|
||||
<div ref={scrollRef} className={styles.scrollRef}></div>
|
||||
<SectionHeader
|
||||
textTransform="capitalize"
|
||||
title={intl.formatMessage({ id: "Rooms" })}
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
.roomsContainer {
|
||||
position: relative;
|
||||
scroll-margin-top: var(--hotel-page-scroll-margin-top);
|
||||
}
|
||||
|
||||
.scrollRef {
|
||||
position: absolute;
|
||||
top: calc(-1 * var(--hotel-page-scroll-margin-top));
|
||||
}
|
||||
|
||||
.ctaContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"use client"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { useEffect } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import useHash from "@/hooks/useHash"
|
||||
import useScrollSpy from "@/hooks/useScrollSpy"
|
||||
|
||||
import styles from "./tabNavigation.module.css"
|
||||
|
||||
@@ -18,46 +20,58 @@ export default function TabNavigation({ restaurantTitle }: TabNavigationProps) {
|
||||
const router = useRouter()
|
||||
// const [isObserverActive, setIsObserverActive] = useState<boolean>(true)
|
||||
|
||||
const hotelTabLinks: { href: HotelHashValues | string; text: string }[] = [
|
||||
const hotelTabLinks: { hash: HotelHashValues | string; text: string }[] = [
|
||||
{
|
||||
href: HotelHashValues.overview,
|
||||
hash: HotelHashValues.overview,
|
||||
text: intl.formatMessage({ id: "Overview" }),
|
||||
},
|
||||
{ href: HotelHashValues.rooms, text: intl.formatMessage({ id: "Rooms" }) },
|
||||
{ hash: HotelHashValues.rooms, text: intl.formatMessage({ id: "Rooms" }) },
|
||||
{
|
||||
href: HotelHashValues.restaurant,
|
||||
hash: HotelHashValues.restaurant,
|
||||
text: intl.formatMessage({ id: restaurantTitle }, { count: 1 }),
|
||||
},
|
||||
{
|
||||
href: HotelHashValues.meetings,
|
||||
hash: HotelHashValues.meetings,
|
||||
text: intl.formatMessage({ id: "Meetings & Conferences" }),
|
||||
},
|
||||
{
|
||||
href: HotelHashValues.wellness,
|
||||
hash: HotelHashValues.wellness,
|
||||
text: intl.formatMessage({ id: "Wellness & Exercise" }),
|
||||
},
|
||||
{
|
||||
href: HotelHashValues.activities,
|
||||
hash: HotelHashValues.activities,
|
||||
text: intl.formatMessage({ id: "Activities" }),
|
||||
},
|
||||
{ href: HotelHashValues.faq, text: intl.formatMessage({ id: "FAQ" }) },
|
||||
{ hash: HotelHashValues.faq, text: intl.formatMessage({ id: "FAQ" }) },
|
||||
]
|
||||
|
||||
const { activeSectionId, pauseScrollSpy } = useScrollSpy(
|
||||
hotelTabLinks.map(({ hash }) => hash)
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (activeSectionId) {
|
||||
router.replace(`#${activeSectionId}`, { scroll: false })
|
||||
}
|
||||
}, [activeSectionId, router])
|
||||
|
||||
return (
|
||||
<div className={styles.stickyWrapper}>
|
||||
<nav className={styles.tabsContainer}>
|
||||
{hotelTabLinks.map((link) => {
|
||||
const isActive =
|
||||
hash === link.href ||
|
||||
(hash === "" && link.href === HotelHashValues.overview)
|
||||
hash === link.hash ||
|
||||
(!hash && link.hash === HotelHashValues.overview)
|
||||
return (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
key={link.hash}
|
||||
href={`#${link.hash}`}
|
||||
active={isActive}
|
||||
variant="tab"
|
||||
color="burgundy"
|
||||
textDecoration="none"
|
||||
scroll={true}
|
||||
onClick={pauseScrollSpy}
|
||||
>
|
||||
{intl.formatMessage({ id: link.text })}
|
||||
</Link>
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
.pageContainer {
|
||||
--hotel-page-navigation-height: 59px;
|
||||
--hotel-page-scroll-margin-top: calc(
|
||||
var(--hotel-page-navigation-height) + var(--Spacing-x2)
|
||||
);
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"hotelImages"
|
||||
@@ -26,6 +30,7 @@
|
||||
.introContainer {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x4);
|
||||
scroll-margin-top: var(--hotel-page-scroll-margin-top);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
|
||||
@@ -21,6 +21,8 @@ import TabNavigation from "./TabNavigation"
|
||||
|
||||
import styles from "./hotelPage.module.css"
|
||||
|
||||
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
||||
|
||||
export default async function HotelPage() {
|
||||
const intl = await getIntl()
|
||||
const lang = getLang()
|
||||
@@ -63,7 +65,7 @@ export default async function HotelPage() {
|
||||
restaurantTitle={getRestaurantHeading(hotelDetailedFacilities)}
|
||||
/>
|
||||
<main className={styles.mainSection}>
|
||||
<div id="overview" className={styles.introContainer}>
|
||||
<div id={HotelHashValues.overview} className={styles.introContainer}>
|
||||
<IntroSection
|
||||
hotelName={hotelName}
|
||||
hotelDescription={hotelDescription}
|
||||
|
||||
Reference in New Issue
Block a user