66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { Map } from "mapbox-gl";
|
|
|
|
/* Idea from Stack Overflow https://stackoverflow.com/a/51683226 */
|
|
export class CustomControl {
|
|
private _className: string;
|
|
private _title: string;
|
|
private _eventHandler: (event: MouseEvent) => void;
|
|
private _btn!: HTMLButtonElement;
|
|
private _container!: HTMLDivElement;
|
|
private _map?: Map;
|
|
private _root: any; // React root for rendering our component
|
|
|
|
constructor({
|
|
className = "",
|
|
title = "",
|
|
eventHandler = () => { }
|
|
}: {
|
|
className?: string;
|
|
title?: string;
|
|
eventHandler?: (event: MouseEvent) => void;
|
|
}) {
|
|
this._className = className;
|
|
this._title = title;
|
|
this._eventHandler = eventHandler;
|
|
}
|
|
|
|
onAdd(map: Map) {
|
|
this._map = map;
|
|
this._btn = document.createElement("button");
|
|
this._btn.className = "mapboxgl-ctrl-icon" + " " + this._className;
|
|
this._btn.type = "button";
|
|
this._btn.title = this._title;
|
|
this._btn.onclick = this._eventHandler;
|
|
|
|
// Apply pointer-events: auto; style dynamically
|
|
this._btn.style.pointerEvents = "auto";
|
|
|
|
// Dynamically append the style to the auto-generated className
|
|
const styleSheet = document.styleSheets[0];
|
|
styleSheet.insertRule(
|
|
`.${this._className} { pointer-events: auto; }`,
|
|
styleSheet.cssRules.length
|
|
);
|
|
|
|
this._container = document.createElement("div");
|
|
this._container.className = "mapboxgl-ctrl-group mapboxgl-ctrl";
|
|
this._container.appendChild(this._btn);
|
|
|
|
return this._container;
|
|
}
|
|
|
|
onRemove() {
|
|
if (this._container && this._container.parentNode) {
|
|
this._container.parentNode.removeChild(this._container);
|
|
}
|
|
|
|
// Defer unmounting React component to prevent race conditions
|
|
if (this._root) {
|
|
setTimeout(() => {
|
|
this._root.unmount();
|
|
});
|
|
}
|
|
|
|
this._map = undefined;
|
|
}
|
|
} |