Search code examples
reactjsgoogle-mapsreact-google-maps

Set z-index of OverlayView in react-google-maps


I am using react-google-maps and I want to accomplish something similar to Airbnb where when you hover over a search result and then a "marker" (aka OverlayView) is highlighted on the map. But the issue I am trying to solve is if an OverlayView is underneath another OverlayView, I want to bring that "active" OverlayView to the top (like by adjusting the z-index). The map on Airbnb does this very thing, which is when you hover over the search result and inspect the marker the z-index is altered to be 9001 to ensure it is brought to the front of all other markers.

There are a few issues related to this from years ago that have not received any movement:

tomchentw/react-google-maps#199 tomchentw/react-google-maps#93

In issue #199 it was mentioned you could hack around it with this.refs.childDiv.parentNode and setting z-index on that, but in React v16 this.refs is no longer a thing from what I can tell (it was deprecated). The original commenter attached a jsfiddle with the code sample which was:

class OverlayViewExample extends React.Component {
  render () {
    const pos = {lat: -34.397, lng: 150.644};
    const mapPane = OverlayView.OVERLAY_MOUSE_TARGET;
    const getOffset = this.getPixelPositionOffset.bind(this);

    return (
      <GoogleMap
        defaultZoom={8}
        defaultCenter={pos}
      >
        <OverlayView
          position={pos}
          mapPaneName={mapPane}
          getPixelPositionOffset={getOffset}
        >
          <div style={{zIndex: 2}} className="overlay" ref="childDiv">This should be in front</div>
        </OverlayView>

        <OverlayView
          position={pos}
          mapPaneName={mapPane}
          getPixelPositionOffset={getOffset}
        >
          <div style={{zIndex: 1}} className="overlay">Another overlay should be in front of me</div>
        </OverlayView>
      </GoogleMap>
    );
  }

  getPixelPositionOffset (width, height) {
    // this.refs is an empty object when I tried this :(
    if (this.refs.childDiv) {
        this.refs.childDiv.parentNode.style.zIndex = 2;
    }
    return { x: -(width / 2), y: -(height / 2) };
  }
}

When I tried this workaround, this.refs was an empty object and therefore I could not alter the underlying zIndex of that node.

Is there another way to ensure when two OverlayViews are near each other that I can bring the one in the background to the foreground?


Solution

  • The answer for this was actually in my question (I should've tested the example code from Github)...

    On this line: <div style={{zIndex: 2}} className="overlay" ref="childDiv">This should be in front</div> the zIndex was actually doing what I wanted (it would bring forward whichever element I wanted in the foreground).

    So within each OverlayView, just apply a z-index to the first child element and that will effect the ordering of each OverlayView.