import { Control, type ControlPosition } from 'leaflet'; import { bool, choice } from '../core/props.ts'; import { WithProps } from '../core/with-props.ts'; import type { LeafletRegisterEvent } from '../core/register.ts'; export class LeafletControlLayers extends WithProps( { position: choice('topright'), collapsed: bool(true), autoZIndex: bool(true), hideSingleBase: bool(), sortLayers: bool(), }, { attach: 'self' }, ) { declare readonly leafletObject?: Control.Layers; createLeafletObject(options: Control.LayersOptions): Control.Layers { return new Control.Layers({}, {}, options); } connectedCallback(): void { super.connectedCallback(); this.addEventListener('leaflet-register', this.#onChildRegister); } disconnectedCallback(): void { this.removeEventListener('leaflet-register', this.#onChildRegister); super.disconnectedCallback(); } // Every child -- present at construction or added later -- announces // itself this way: a parent's connectedCallback always finishes before a // child's does (even for an already-built subtree attached in one go), so // there is no "read the children that are already here" case to handle // separately. #onChildRegister = (e: LeafletRegisterEvent) => { e.stopPropagation(); const el = e.detail.element; const layer = e.detail.leafletObject; const name = el.getAttribute('name'); if (!name) return; if (el.getAttribute('type') === 'base') this.leafletObject?.addBaseLayer(layer, name); else this.leafletObject?.addOverlay(layer, name); if (el.hasAttribute('active')) { this.dispatchEvent( new CustomEvent('leaflet-add-layer', { bubbles: true, detail: { layer } }), ); } }; } customElements.define('leaflet-control-layers', LeafletControlLayers);