import { ImageOverlay, LatLngBounds, LatLngExpression } from 'leaflet'; import type { ImageOverlayOptions } from 'leaflet'; import { defineProps, num, str, on } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; import { WithProps, buildAttrMap, buildOptions, parseBoundsAttr, setLayerAttr, } from '../core/utils.ts'; const PROPS = defineProps({ url: str(), bounds: str(), opacity: num(1.0), alt: str(), interactive: on(), crossOrigin: str(), errorOverlayUrl: str(), zIndex: num(), className: str(), }); const PROP_BY_ATTR = buildAttrMap(PROPS); export class LeafletImageOverlay extends WithProps(HTMLElement, PROPS) { #obj?: ImageOverlay; connectedCallback() { const url = this.getAttribute('url') || ''; this.#obj = new ImageOverlay( url, parseBoundsAttr(this), buildOptions(this, PROPS, ['url', 'bounds']) as ImageOverlayOptions, ); registerChildren(this, this.#obj); } disconnectedCallback() { 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 (name === 'url') { if (val) this.#obj.setUrl(val); } else if (name === 'bounds') { this.#obj.setBounds(new LatLngBounds(parseBoundsAttr(this) as LatLngExpression[])); } else if (name === 'alt') { const el = this.#obj.getElement(); if (el) (el as HTMLImageElement).alt = val ?? ''; } else { setLayerAttr(this.#obj!, PROPS, PROP_BY_ATTR, name, val); } } } customElements.define('leaflet-image-overlay', LeafletImageOverlay);