import { Polyline } from 'leaflet'; import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; import { isPathStyleAttr, updatePathStyle } from '../core/attributes.ts'; import type { LeafletLine } from './leaflet-line.ts'; const PROPS = defineProps({ color: str('#3388ff'), weight: num(3), opacity: num(1.0), fill: on(), fillColor: str('#3388ff'), fillOpacity: num(0.2), }); export class LeafletPolyline extends WithProps(HTMLElement, PROPS) { #obj?: Polyline; #observer?: MutationObserver; connectedCallback() { this.#obj = new Polyline(this.#getCoords(), buildOptions(this, PROPS)); registerChildren(this, this.#obj); this.addEventListener('line-updated', this.#syncCoords); this.#observer = new MutationObserver(() => { this.#syncCoords(); }); this.#observer.observe(this, { childList: true }); } disconnectedCallback() { this.#observer?.disconnect(); this.#observer = undefined; this.removeEventListener('line-updated', this.#syncCoords); unregisterChildren(this); this.#obj?.remove(); this.#obj = undefined; } get leafletObject() { return this.#obj; } attributeChangedCallback(name: string, _old: string | null, val: string | null) { if (!this.#obj) return; if (isPathStyleAttr(name)) { updatePathStyle(this.#obj, name, val); } } #syncCoords = () => { this.#obj?.setLatLngs(this.#getCoords()); }; #getCoords(): [number, number][] { const lines = Array.from(this.querySelectorAll('leaflet-line')); return lines.map((line) => line.latlng); } } customElements.define('leaflet-polyline', LeafletPolyline);