diff --git a/apps/scandic-web/components/Maps/InteractiveMap/index.tsx b/apps/scandic-web/components/Maps/InteractiveMap/index.tsx index a0efdac1e..27648bc86 100644 --- a/apps/scandic-web/components/Maps/InteractiveMap/index.tsx +++ b/apps/scandic-web/components/Maps/InteractiveMap/index.tsx @@ -4,10 +4,17 @@ import { Map, type MapProps, useMap } from "@vis.gl/react-google-maps" import { useEffect, useState } from "react" import { useIntl } from "react-intl" +import { IconButton } from "@scandic-hotels/design-system/IconButton" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton" -import { MAP_RESTRICTIONS } from "@/constants/map" +import { + DEFAULT_ZOOM, + MAP_RESTRICTIONS, + MAX_ZOOM, + MIN_ZOOM, +} from "@/constants/map" + +import { useZoomControls } from "@/hooks/maps/useZoomControls" import HotelListingMapContent from "./HotelListingMapContent" import PoiMapMarkers from "./PoiMapMarkers" @@ -31,9 +38,12 @@ export default function InteractiveMap({ const intl = useIntl() const map = useMap() const [hasInitializedBounds, setHasInitializedBounds] = useState(false) + const { zoomIn, zoomOut, isMaxZoom, isMinZoom } = useZoomControls() const mapOptions: MapProps = { - defaultZoom: 14, + defaultZoom: DEFAULT_ZOOM, + minZoom: MIN_ZOOM, + maxZoom: MAX_ZOOM, defaultCenter: coordinates, disableDefaultUI: true, clickableIcons: false, @@ -42,19 +52,6 @@ export default function InteractiveMap({ restriction: MAP_RESTRICTIONS, } - function zoomIn() { - const currentZoom = map && map.getZoom() - if (currentZoom) { - map.setZoom(currentZoom + 1) - } - } - function zoomOut() { - const currentZoom = map && map.getZoom() - if (currentZoom) { - map.setZoom(currentZoom - 1) - } - } - useEffect(() => { if (map && hotelPins?.length && !hasInitializedBounds) { if (fitBounds) { @@ -62,7 +59,6 @@ export default function InteractiveMap({ hotelPins.forEach((marker) => { bounds.extend(marker.coordinates) }) - map.fitBounds(bounds, 100) } setHasInitializedBounds(true) @@ -86,32 +82,31 @@ export default function InteractiveMap({
{closeButton}
- - +
diff --git a/apps/scandic-web/components/Maps/InteractiveMap/interactiveMap.module.css b/apps/scandic-web/components/Maps/InteractiveMap/interactiveMap.module.css index edad6cffd..3c4b9516b 100644 --- a/apps/scandic-web/components/Maps/InteractiveMap/interactiveMap.module.css +++ b/apps/scandic-web/components/Maps/InteractiveMap/interactiveMap.module.css @@ -59,8 +59,8 @@ } .zoomButton { - width: var(--Spacing-x5); - height: var(--Spacing-x5); + width: var(--Space-x5); + height: var(--Space-x5); padding: 0; pointer-events: initial; box-shadow: var(--button-box-shadow); diff --git a/apps/scandic-web/constants/map.ts b/apps/scandic-web/constants/map.ts index 7fec60287..9069f6316 100644 --- a/apps/scandic-web/constants/map.ts +++ b/apps/scandic-web/constants/map.ts @@ -3,3 +3,7 @@ export const MAP_RESTRICTIONS = { // See https://developers.google.com/maps/documentation/javascript/reference/map#MapRestriction.latLngBounds latLngBounds: { north: 85, south: -85, west: -180, east: 180 }, } + +export const DEFAULT_ZOOM = 14 +export const MAX_ZOOM = 18 +export const MIN_ZOOM = 8 diff --git a/apps/scandic-web/hooks/maps/useZoomControls.ts b/apps/scandic-web/hooks/maps/useZoomControls.ts new file mode 100644 index 000000000..d9608b9cc --- /dev/null +++ b/apps/scandic-web/hooks/maps/useZoomControls.ts @@ -0,0 +1,43 @@ +import { useMap } from "@vis.gl/react-google-maps" +import { useEffect, useState } from "react" + +import { DEFAULT_ZOOM, MAX_ZOOM, MIN_ZOOM } from "@/constants/map" + +export function useZoomControls() { + const map = useMap() + const [zoomLevel, setZoomLevel] = useState(DEFAULT_ZOOM) + + const zoomIn = () => { + if (map && zoomLevel < MAX_ZOOM) { + map.setZoom(zoomLevel + 1) + } + } + + const zoomOut = () => { + if (map && zoomLevel > MIN_ZOOM) { + map.setZoom(zoomLevel - 1) + } + } + + useEffect(() => { + if (!map) return + + const handleZoomChanged = () => { + const currentZoom = map.getZoom() + if (currentZoom != null) { + setZoomLevel(currentZoom) + } + } + + const listener = map.addListener("zoom_changed", handleZoomChanged) + return () => listener.remove() + }, [map]) + + return { + zoomLevel, + zoomIn, + zoomOut, + isMinZoom: zoomLevel <= MIN_ZOOM, + isMaxZoom: zoomLevel >= MAX_ZOOM, + } +}