Fix/SW-2682 map fixes

* fix(SW-2682): Added overflow-y: hidden to body on destination and hotel map pages
* fix(SW-2682): Added scroll to top functionality on map components with reason why

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-05-14 12:06:41 +00:00
parent a66b632875
commit 211cd5270b
5 changed files with 71 additions and 28 deletions

View File

@@ -46,6 +46,9 @@ export default function BookingWidgetClient({
const [isOpen, setIsOpen] = useState(false)
const bookingWidgetRef = useRef(null)
const lang = useLang()
const [originalOverflowY, setOriginalOverflowY] = useState<string | null>(
null
)
const params = convertSearchParamsToObj<BookingWidgetSearchData>(
bookingWidgetSearchParams
@@ -147,11 +150,13 @@ export default function BookingWidgetClient({
function closeMobileSearch() {
setIsOpen(false)
document.body.style.overflowY = "visible"
const overflowY = originalOverflowY ?? "visible"
document.body.style.overflowY = overflowY
}
function openMobileSearch() {
setIsOpen(true)
setOriginalOverflowY(document.body.style.overflowY)
document.body.style.overflowY = "hidden"
}

View File

@@ -5,6 +5,7 @@ import {
type PropsWithChildren,
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react"
@@ -80,8 +81,30 @@ export default function Map({
// Calculate the height of the map based on the viewport height from the start-point (below the header and booking widget)
const handleMapHeight = useCallback(() => {
const topPosition = rootDiv.current?.getBoundingClientRect().top ?? 0
const scrollY = window.scrollY
setMapHeight(`calc(100dvh - ${topPosition + scrollY}px)`)
setMapHeight(`calc(100dvh - ${topPosition}px)`)
}, [])
function handleClose() {
const url = new URL(window.location.href)
url.searchParams.delete("view")
router.push(url.toString())
setActiveMarker(null)
}
useLayoutEffect(() => {
const originalOverflowY = document.body.style.overflowY
document.body.style.overflowY = "hidden"
// Making sure the map is always opened at the top of the page,
// just below the header and booking widget as these should stay visible.
// Reason for this is that we're using the hash property on pages which we preserve
// when navigating between pages.
window.scrollTo({ top: 0, behavior: "instant" })
return () => {
document.body.style.overflowY = originalOverflowY
}
}, [])
useEffect(() => {
@@ -90,7 +113,6 @@ export default function Map({
})
const observer = new ResizeObserver(debouncedResizeHandler)
observer.observe(document.documentElement)
return () => {
@@ -100,13 +122,6 @@ export default function Map({
}
}, [rootDiv, handleMapHeight])
function handleClose() {
const url = new URL(window.location.href)
url.searchParams.delete("view")
router.push(url.toString())
setActiveMarker(null)
}
return (
<MapProvider apiKey={apiKey} pageType={pageType}>
<div

View File

@@ -1,7 +1,13 @@
"use client"
import { APIProvider } from "@vis.gl/react-google-maps"
import { useRouter } from "next/navigation"
import { useCallback, useEffect, useRef, useState } from "react"
import {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react"
import { useIntl } from "react-intl"
import { Button } from "@scandic-hotels/design-system/Button"
@@ -41,8 +47,7 @@ export default function HotelMapPageClient({
// Calculate the height of the map based on the viewport height from the start-point (below the header and booking widget)
const handleMapHeight = useCallback(() => {
const topPosition = rootDiv.current?.getBoundingClientRect().top ?? 0
const scrollY = window.scrollY
setMapHeight(`calc(100dvh - ${topPosition + scrollY}px)`)
setMapHeight(`calc(100dvh - ${topPosition}px)`)
}, [])
function handleClose() {
@@ -51,6 +56,22 @@ export default function HotelMapPageClient({
router.push(url.toString())
}
useLayoutEffect(() => {
const originalOverflowY = document.body.style.overflowY
document.body.style.overflowY = "hidden"
// Making sure the map is always opened at the top of the page,
// just below the header and booking widget as these should stay visible.
// Reason for this is that we're using the hash property on pages which we preserve
// when navigating between pages.
window.scrollTo({ top: 0, behavior: "instant" })
return () => {
document.body.style.overflowY = originalOverflowY
}
}, [])
useEffect(() => {
const debouncedResizeHandler = debounce(function () {
handleMapHeight()

View File

@@ -56,19 +56,16 @@
@media screen and (max-width: 767px) {
.sidebar {
--sidebar-mobile-toggle-height: 84px;
--sidebar-mobile-top-space: 40px;
--sidebar-mobile-toggle-height: 88px;
--sidebar-mobile-empty-space: 32px;
--sidebar-mobile-content-height: calc(
var(--hotel-map-height) - var(--sidebar-mobile-toggle-height) -
var(--sidebar-mobile-top-space)
var(--sidebar-mobile-empty-space)
);
position: absolute;
bottom: calc(-1 * var(--sidebar-mobile-content-height));
bottom: 0;
width: 100%;
transition:
bottom 0.3s,
top 0.3s;
border-radius: var(--Corner-radius-lg) var(--Corner-radius-lg) 0 0;
}
@@ -82,32 +79,38 @@
z-index: 1;
}
.sidebar.fullscreen {
bottom: 0;
}
.sidebarToggle {
position: relative;
color: var(--Text-Secondary);
background-color: var(--Base-Surface-Primary-light-Normal);
border-width: 0;
margin-top: var(--Space-x4);
margin: var(--Space-x2) 0;
padding: var(--Space-x2);
width: 100%;
}
.sidebarToggle::before {
content: "";
position: absolute;
display: block;
top: -0.5rem;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 46px;
height: 3px;
background-color: var(--Icon-Interactive-Disabled);
}
.sidebar:not(.fullscreen) .sidebarContent {
height: 0;
padding-top: 0;
padding-bottom: 0;
}
.sidebarContent {
padding: var(--Space-x3) var(--Space-x2);
height: var(--sidebar-mobile-content-height);
transition: height 0.3s ease-in-out;
}
}

View File

@@ -54,7 +54,6 @@ export default function MobileMapToggle() {
<Link
className={styles.link}
href={mapUrl}
scroll={true}
onClick={trackHotelMapClick}
>
<MaterialIcon