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; } }