From 99fa5a93d0287f4ab52e95445e5591e73b31fe0a Mon Sep 17 00:00:00 2001 From: C4rnivore Date: Mon, 28 Jul 2025 17:47:50 +0500 Subject: [PATCH] hover and selected states for markers --- src/components/google-map/GoogleMap.tsx | 6 ++-- .../google-map/GoogleMapMarkers.tsx | 5 +++ src/components/google-map/MapMarker.tsx | 36 ++++++++++++++----- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/components/google-map/GoogleMap.tsx b/src/components/google-map/GoogleMap.tsx index bf7690d..62826b0 100644 --- a/src/components/google-map/GoogleMap.tsx +++ b/src/components/google-map/GoogleMap.tsx @@ -34,7 +34,7 @@ export default function GoogleMap({ map.panTo(mapCenter); map.setZoom(defaultZoom); } - }, [mobile, mobileActive, map]); + }, [mobile, mobileActive, defaultZoom, mapCenter, map]); useEffect(() => { if (!mobileActive) setMapMarkersFilter("All"); @@ -52,7 +52,9 @@ export default function GoogleMap({ defaultZoom={defaultZoom} disableDefaultUI={true} minZoom={minZoom} - gestureHandling={!mobile || mobileActive ? "greedy" : "none"} + gestureHandling={ + mobile ? (mobileActive ? "greedy" : "none") : "cooperative" + } > {markers && ( diff --git a/src/components/google-map/GoogleMapMarkers.tsx b/src/components/google-map/GoogleMapMarkers.tsx index dbb55cb..d160f9a 100644 --- a/src/components/google-map/GoogleMapMarkers.tsx +++ b/src/components/google-map/GoogleMapMarkers.tsx @@ -42,6 +42,7 @@ export default function GoogleMapMarkers({ }) { const map = useMap(); const [markers, setMarkers] = useState<{ [key: string]: Marker }>({}); + const [selectedMarker, setSelectedMarker] = useState(null); const clusterer = useRef(null); useEffect(() => { @@ -64,6 +65,8 @@ export default function GoogleMapMarkers({ if (!marker && !markers[key]) return; setMarkers((prev) => { + if (prev[key] === marker) return prev; + if (marker) { return { ...prev, [key]: marker }; } else { @@ -84,6 +87,8 @@ export default function GoogleMapMarkers({ markerKey={index} poi={poi} setMarkerRef={setMarkerRef} + isSelected={selectedMarker === index} + setSelectedMarker={setSelectedMarker} > {poi.customMarker} diff --git a/src/components/google-map/MapMarker.tsx b/src/components/google-map/MapMarker.tsx index ed40045..13207e5 100644 --- a/src/components/google-map/MapMarker.tsx +++ b/src/components/google-map/MapMarker.tsx @@ -1,5 +1,6 @@ import { AdvancedMarker, useMap } from "@vis.gl/react-google-maps"; import type { Marker } from "@googlemaps/markerclusterer"; +import { useEffect, useRef, useState } from "react"; import IGMapPoi from "../../types/IGMapPoi"; interface IGMapMarker { @@ -7,6 +8,8 @@ interface IGMapMarker { poi: IGMapPoi; setMarkerRef: (marker: Marker | null, key: string) => void | undefined; children: React.ReactNode; + isSelected: boolean; + setSelectedMarker: React.Dispatch>; } export default function MapMarker({ @@ -14,30 +17,47 @@ export default function MapMarker({ children, markerKey, setMarkerRef, + isSelected, + setSelectedMarker, }: IGMapMarker) { const map = useMap(); const { location, ignoreClusterization, label } = poi; + const [isHovered, setIsHovered] = useState(false); + const markerRef = useRef(null); + + useEffect(() => { + if (!ignoreClusterization) { + setMarkerRef(markerRef.current, markerKey.toString()); + } + }, [ignoreClusterization, markerKey, setMarkerRef]); return ( { - if (!ignoreClusterization) { - setMarkerRef(marker, markerKey.toString()); - } - }} + ref={markerRef} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} onClick={() => { - map?.panTo(location); + map?.panTo({ lat: location.lat, lng: location.lng + 0.001 }); // 0.001 is a small align to fit long labels (generally for mobile devices) map?.setZoom(17); + setSelectedMarker(markerKey); }} >
.label-container]:opacity-100 hover:[&>.label-container]:left-[calc(100%-38px)] hover:[&>.label-container]:pointer-events-auto hover:[&>.label-container]:z-140 hover:[&>.gmap-img-container]:z-150`} + className={`relative flex items-center gap-x-2 ${ + isHovered || isSelected ? "[&>.gmap-img-container]:z-150" : "" + }`} > {children} {label && ( -
+
{label}
)}