react-google-maps-api
react-google-maps-api copied to clipboard
Right click doesn't work in InfoBox component
Bug description
When using the InfoBoxF component mouse right-click does not work. Selecting text doesn't work either. The InfoBoxF uses component uses the OverlayViewf component.
See my question in the discussion tab for more context here: https://github.com/JustFly1984/react-google-maps-api/discussions/3327
Here is a recorded video of the issue. InfoWindowF (which works) on the left, and InfoBoxF on the right:
https://github.com/JustFly1984/react-google-maps-api/assets/4746639/f7ba9ccb-d6fb-4665-a594-45785e27da92
Environment
os: mac
node --version v20.9.0
react version v18.2.0
webpack version vite 5.0.8
@babel version
@react-google-maps/api version "@react-google-maps/api": "^2.19.2", "@react-google-maps/infobox": "^2.19.2",
How does it behave?
Right-click doesn't work
How should it behave correctly?
Right-click should bring up the native browser context menu. I want to open a link in new tab
Basic implementation of incorrect behavior in codesandbox.com
I was unable to get codesandbox to work, here is a basic implementation:
import {
GoogleMap,
InfoBoxF,
InfoWindowF,
useLoadScript,
} from "@react-google-maps/api";
import styled from "styled-components";
const Container = styled.div`
&&& {
.gm-style-iw {
background-color: orangered;
}
}
`;
function App() {
const { loadError, isLoaded } = useLoadScript({
id: "google-maps-script",
googleMapsApiKey: "insert-your-google-maps-api-key-here",
});
const center = {
lat: -3.745,
lng: -38.523,
};
return (
<Container>
<h1>map</h1>
{loadError && <div>load error</div>}
<div>isLoaded: {isLoaded ? "yes" : "no"}</div>
{!isLoaded && <div>loading</div>}
{isLoaded && (
<div
style={{ width: 500, height: 500, background: "pink" }}
className={"box1"}
>
<GoogleMap
mapContainerStyle={{
width: "500px",
height: "500px",
}}
options={{
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
panControl: false,
zoomControl: false,
minZoom: 3,
}}
zoom={3}
center={center}
>
<InfoWindowF position={center} options={{}}>
<div
style={{
width: 100,
height: 100,
borderRadius: 16,
background: "orange",
}}
>
<a href={"/test"}>link iw</a>
</div>
</InfoWindowF>
<InfoBoxF
position={new google.maps.LatLng(center)}
options={{
enableEventPropagation: false,
pane: "floatPane",
}}
>
<div
style={{
width: 100,
height: 100,
borderRadius: 16,
background: "aqua",
}}
>
<a href={"/test"}>link iw</a>
</div>
</InfoBoxF>
</GoogleMap>
</div>
)}
</Container>
);
}
export default App;
Maybe this can be used? google.maps.OverlayView.preventMapHitsAndGesturesFrom(element)
I finally figured this out.
const MapInfoWindow: React.FC<Props> = ({ position, children, style }) => {
const map = useGoogleMap();
if (map === null) {
throw new Error('MapInfoWindow cannot be used outside a google map context');
}
const myRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (myRef.current) {
// This prevents mouse and tocuh events to pass through the custom OverlayView to the map:
google.maps.OverlayView.preventMapHitsAndGesturesFrom(myRef.current);
}
}, [myRef]);
return (
<OverlayViewF
mapPaneName={'overlayMouseTarget'}
position={{
lat: position.lat,
lng: position.lng,
}}
>
<div
ref={myRef}
onContextMenu={(event) => {
// This stop the right click event from propagating, and will enable the native browser right click menu
event.stopPropagation();
}}
>
{children}
</div>
</OverlayViewF>
);
};
I'm writing my own "InfoBox" component based on the OverlayViewF component, and therefore I don't need this to be handled in the "InfoBox" any longer. It still would be nice if this worked out of the box in my opinion, but I'll leave that to someone else ;)