Move static outside HTML. Start work on TypeScript bundle

It's not strictly HTML, so that's just correct.

This is just worth doing while building the new TypeScript bundle
This commit is contained in:
Eli Ribble 2026-03-21 03:06:59 +00:00
parent 976a29b7d7
commit 31947c848a
No known key found for this signature in database
53 changed files with 7100 additions and 73 deletions

View file

@ -0,0 +1,167 @@
// A map that shows multiple single point locations.
// Points have additional detail popups.
// The background layer is proxied from Arcgis
class MapProxiedArcgisTile extends HTMLElement {
static observedAttributes = ["latitude", "longitude"];
constructor() {
super();
// Create a shadow DOM
this.attachShadow({ mode: "open" });
// Initial render
this.render();
// Keep track of any 'on' calls to add to the map as soon as we create it.
this._preOns = [];
this._map = null;
this._markers = [];
}
attributeChangedCallback(name, old_value, new_value) {
//console.log("map-arcgis-tile: attribute changed", name, old_value, new_value);
if ((name == "latitude" || name == "longitude") && this._map != null) {
const latitude = parseFloat(this.getAttribute("latitude"));
const longitude = parseFloat(this.getAttribute("longitude"));
this._map.jumpTo({
center: [longitude, latitude],
zoom: 19,
});
}
}
// Lifecycle: when element is added to the DOM
connectedCallback() {
// Initialize the map when the element is added to the DOM
setTimeout(() => this._initializeMap(), 0);
}
disconnectedCallback() {
if (this._map) {
this._map.remove();
}
}
_initializeMap() {
const latitude = parseFloat(this.getAttribute("latitude"));
const longitude = parseFloat(this.getAttribute("longitude"));
const organization_id = Number(this.getAttribute("organization-id") || 0);
const tegola = this.getAttribute("tegola");
const url_tiles = this.getAttribute("url-tiles");
const mapElement = this.shadowRoot.querySelector("#map");
this._map = new maplibregl.Map({
center: [longitude, latitude],
container: mapElement,
style: "https://tiles.stadiamaps.com/styles/osm_bright.json",
zoom: 19,
});
this._map.on("load", () => {
if (organization_id != 0) {
this._map.addSource("tegola", {
type: "vector",
tiles: [
`${tegola}maps/nidus/{z}/{x}/{y}?id=${organization_id}&organization_id=${organization_id}`,
],
});
this._map.addLayer({
id: "service-area",
source: "tegola",
"source-layer": "service-area-bounds",
type: "line",
paint: {
"line-color": "#f00",
},
});
}
this._map.addSource("flyover", {
type: "raster",
tiles: [url_tiles],
});
this._map.addLayer({
id: "flyover-layer",
source: "flyover",
type: "raster",
});
this.dispatchEvent(new CustomEvent("load"), {
bubbles: true,
composed: true, // Allows event to cross shadow DOM boundary
detail: {
map: this,
},
});
this._map.on("click", (e) => {
this.dispatchEvent(
new CustomEvent("map-click", {
bubbles: true,
composed: true,
detail: {
lng: e.lngLat.lng,
lat: e.lngLat.lat,
map: this,
point: e.point,
},
}),
);
});
});
for (const on of this._preOns) {
this._map.on(...on);
}
}
// Initial render of component
render() {
this.shadowRoot.innerHTML = `
<style>
@import url("//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.css");
#map {
height: 100%;
width: 100%;
}
</style>
<div id="map"></div>
`;
}
addLayer(a) {
return this._map.addLayer(a);
}
addSource(a, b) {
return this._map.addSource(a, b);
}
jumpTo(args) {
return this._map.jumpTo(args);
}
on(...args) {
if (this._map != null) {
return this._map.on(...args);
} else {
this._preOns.push(args);
}
}
once(a, b) {
return this._map.once(a, b);
}
queryRenderedFeatures(a) {
return this._map.queryRenderedFeatures(a);
}
FitBounds(bounds, options) {
return this._map.fitBounds(bounds, options);
}
SetLayoutProperty(layout, property, value) {
return this._map.setLayoutProperty(layout, property, value);
}
SetMarkers(markers) {
console.log("Setting map markers", markers);
this._markers.forEach((marker) => marker.remove());
this._markers = markers;
for (let m of markers) {
m.addTo(this._map);
}
}
}
customElements.define("map-proxied-arcgis-tile", MapProxiedArcgisTile);