import { Circle } from 'leaflet'; import { WithProps, defineProps, num, str, on } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; import { buildOptions, isPathStyleAttr, numAttr, updatePathStyle } from '../core/utils.ts'; const PROPS = defineProps({ lat: num(), lng: num(), radius: num(1000), color: str('#3388ff'), weight: num(3), opacity: num(1.0), fill: on(), fillColor: str('#3388ff'), fillOpacity: num(0.2), }); export class LeafletCircle extends WithProps(HTMLElement, PROPS) { #obj?: Circle; #syncing = false; connectedCallback() { this.#obj = new Circle( [numAttr(this, PROPS, 'lat'), numAttr(this, PROPS, 'lng')], buildOptions(this, PROPS, ['lat', 'lng']), ); this.#obj.on('move', this.#onMove, this); registerChildren(this, this.#obj); } disconnectedCallback() { this.#obj?.off('move', this.#onMove, this); 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 || this.#syncing) return; if (name === 'lat' || name === 'lng') { this.#obj.setLatLng([numAttr(this, PROPS, 'lat'), numAttr(this, PROPS, 'lng')]); } else if (name === 'radius') { this.#obj.setRadius(numAttr(this, PROPS, 'radius')); } else if (isPathStyleAttr(name)) { updatePathStyle(this.#obj, name, val); } } #onMove() { if (!this.#obj || this.#syncing) return; this.#syncing = true; const pos = this.#obj.getLatLng(); this.setAttribute('lat', `${pos.lat}`); this.setAttribute('lng', `${pos.lng}`); this.#syncing = false; } } customElements.define('leaflet-circle', LeafletCircle);