JSFiddle - React, Tailwind, and code Playground

by Tristen Brown

HTML

<link rel="stylesheet" href="https://api.mapbox.com/mapbox-assembly/mbx/v1.2.0/assembly.min.css">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.3/mapbox-gl.js"></script>
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.9.3/mapbox-gl.css">
<div id="map" class="absolute top bottom left right w-full"></div>

JavaScript

mapboxgl.accessToken =
  "pk.eyJ1IjoibWFwYm94c2F0ZWxsaXRlIiwiYSI6ImNqZWZ0MHg0djFqZWoyeG9kN3ZiMmkyd3cifQ.y2HNjGo7FcKQ7psI_BfGqQ"

const style = {
  version: 8,
  center: [-104.1498, 44.7627],
  zoom: 6,
  terrain: null,
  imports: [{ id: "basemap", url: "mapbox://styles/mapbox/standard" }],
  sources: {
    composite: {
      url: "mapbox://mapbox.mapbox-streets-v8",
      type: "vector",
    },
  },
  glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
  projection: { name: "globe" },
  layers: [
    {
      id: "natural-label",
      type: "circle",
      source: "composite",
      "source-layer": "natural_label",
      minzoom: 3,
      layout: {},
      paint: {
        "circle-radius": 10,
        "circle-color": [
          "case",
          ["to-boolean", ["feature-state", "hover"]],
          "red",
          "#000000",
        ],
      },
    },
  ],
}

const map = (window.map = new mapboxgl.Map({
  container: "map",
  hash: true,
  style,
}))

const onHover = (layerId, featureStateId, target) => {
  let feature = null
  map.addInteraction(`${layerId}-out`, {
    type: "mouseleave",
    target,
    handler: (e) => {
      if (feature) {
        map.setFeatureState(feature, { [featureStateId]: false })
        feature = null
      }
    },
  })

  return (e) => {
    if (feature) {
      map.setFeatureState(feature, { [featureStateId]: false })
      feature = null
    }

    map.setFeatureState(e.feature, { [featureStateId]: true })
    feature = e.feature
  }
}

const naturalLabelTarget = {
	layerId: "natural-label"
};

map.addInteraction("natural-label-hover", {
  type: "mouseover",
  target: naturalLabelTarget,
  handler: onHover("natural-label", "hover", naturalLabelTarget),
});

const placeLabelTarget = {
  importId: 'basemap',
  featuresetId: 'place-labels'
};

map.addInteraction("place-name-hover", {
  type: "mouseover",
  target: placeLabelTarget,
  handler: onHover("place-name", "highlight", placeLabelTarget),
});