"use client" import { useCallback, useEffect, useRef, useState } from "react" import { debounce } from "@/utils/debounce" import styles from "./mapModal.module.css" export function MapContainer({ children }: { children: React.ReactNode }) { const [mapHeight, setMapHeight] = useState("") const [mapTop, setMapTop] = useState("") const [mapZIndex, setMapZIndex] = useState(0) const [scrollHeightWhenOpened, setScrollHeightWhenOpened] = useState(0) const rootDiv = useRef(null) // 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)`) setMapTop(`${topPosition + scrollY}px`) setMapZIndex(11) }, []) useEffect(() => { const originalOverflowY = document.body.style.overflowY // Function to enforce overflowY to hidden const enforceOverflowHidden = () => { if (document.body.style.overflowY !== "hidden") { document.body.style.overflowY = "hidden" } } // Set overflowY to hidden initially enforceOverflowHidden() // Create a MutationObserver to watch for changes to the style attribute const observer = new MutationObserver(() => { enforceOverflowHidden() }) // Observe changes to the style attribute of the body observer.observe(document.body, { attributes: true, attributeFilter: ["style"], }) return () => { // Disconnect the observer on cleanup observer.disconnect() // Restore the original overflowY style document.body.style.overflowY = originalOverflowY } }, []) // 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. // When closing, the page should scroll back to the position it was before opening the map. useEffect(() => { // Skip the first render if (!rootDiv.current) { return } if (scrollHeightWhenOpened === 0) { const scrollY = window.scrollY setScrollHeightWhenOpened(scrollY) window.scrollTo({ top: 0, behavior: "instant" }) } }, [scrollHeightWhenOpened, rootDiv]) useEffect(() => { const debouncedResizeHandler = debounce(function () { handleMapHeight() }) const observer = new ResizeObserver(debouncedResizeHandler) observer.observe(document.documentElement) return () => { if (observer) { observer.unobserve(document.documentElement) } } }, [rootDiv, handleMapHeight]) return (
{children}
) }