"use client" import { useRouter } from "next/navigation" import { useCallback, useEffect, useRef, useState } from "react" import { Dialog, Modal } from "react-aria-components" import { debounce } from "@/utils/debounce" import styles from "./mapModal.module.css" export function MapModal({ children }: { children: React.ReactNode }) { const router = useRouter() const [mapHeight, setMapHeight] = useState("0px") const [mapTop, setMapTop] = useState("0px") const [isOpen, setIsOpen] = useState(true) const [scrollHeightWhenOpened, setScrollHeightWhenOpened] = useState(0) const rootDiv = useRef(null) const handleOnOpenChange = (open: boolean) => { setIsOpen(open) if (!open) { router.back() } } // 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`) }, []) // 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}
) }