2025-08-19 16:45:03 -07:00
|
|
|
import { useMap } from "react-leaflet";
|
|
|
|
|
import L from "leaflet";
|
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
import { createPortal } from "react-dom";
|
|
|
|
|
|
|
|
|
|
// props contain title of btn (which can be an icon), the onClick fn (what should happen)
|
|
|
|
|
// when the settings btn is clicked, and it's positioning with the default being topright
|
|
|
|
|
export default function MapButtonControls({settingsBtn, position = "topright"}) {
|
|
|
|
|
const map = useMap(); // retrieves the map instance that is mounted
|
|
|
|
|
const [container, setContainer] = useState(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// extending the leaflet control class
|
|
|
|
|
const customControl = L.Control.extend({
|
|
|
|
|
onAdd: () => {
|
|
|
|
|
// create button element with className 'leaflet-bar'
|
|
|
|
|
const dv = L.DomUtil.create("div", "layer-selector");
|
|
|
|
|
dv.style.cursor = "pointer";
|
|
|
|
|
|
|
|
|
|
// prevent map interactions when clicking on settings btn
|
|
|
|
|
L.DomEvent.disableClickPropagation(dv);
|
|
|
|
|
// L.DomEvent.on(dv, "click", onClick); // pass your own onClick fn
|
|
|
|
|
|
|
|
|
|
// pass button to container for react to render
|
|
|
|
|
setContainer(dv);
|
|
|
|
|
return dv;
|
|
|
|
|
},
|
|
|
|
|
onRemove: () => {
|
|
|
|
|
setContainer(null);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// instantiate new customControl object
|
|
|
|
|
const control = new customControl({ position });
|
|
|
|
|
// method inside og class that we extended above
|
|
|
|
|
control.addTo(map);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
control.remove();
|
|
|
|
|
};
|
2026-01-30 19:02:31 +00:00
|
|
|
}, [map, position]);
|
2025-08-19 16:45:03 -07:00
|
|
|
|
|
|
|
|
return container ? createPortal(
|
|
|
|
|
settingsBtn,
|
|
|
|
|
container)
|
|
|
|
|
: null;
|
|
|
|
|
}
|