From 78c39f33a32d47ad447d2f693f92c1accd58e844 Mon Sep 17 00:00:00 2001 From: Buddy Date: Mon, 8 Jun 2026 22:11:45 -0700 Subject: [PATCH] fix: sync lat/lng attributes on marker dragend LeafletMarker now listens for Leaflet's 'dragend' event and writes the final position back to the lat/lng attributes, using a #syncing guard to prevent re-entrant setLatLng calls. --- src/components/leaflet-marker.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/leaflet-marker.ts b/src/components/leaflet-marker.ts index 8fd3ae1..4523e49 100644 --- a/src/components/leaflet-marker.ts +++ b/src/components/leaflet-marker.ts @@ -25,6 +25,7 @@ const PROP_BY_ATTR = new Map( export class LeafletMarker extends withProps(HTMLElement, PROPS) { #obj?: Marker; + #syncing = false; #children = new Map(); #childHandler?: (e: LeafletRegisterEvent) => void; @@ -33,6 +34,7 @@ export class LeafletMarker extends withProps(HTMLElement, PROPS) { [this.#num('lat'), this.#num('lng')], buildOptions(this, PROPS, ['lat', 'lng']), ); + this.#obj.on('dragend', this.#onDragEnd); this.#childHandler = createChildRegisterHandler(this.#obj, this.#children); this.addEventListener('leaflet-register', this.#childHandler); registerWithParent(this, this.#obj); @@ -40,13 +42,14 @@ export class LeafletMarker extends withProps(HTMLElement, PROPS) { disconnectedCallback() { if (this.#childHandler) this.removeEventListener('leaflet-register', this.#childHandler); + this.#obj?.off('dragend', this.#onDragEnd); this.#children.clear(); this.#obj?.remove(); this.#obj = undefined; } attributeChangedCallback(name: string, _old: string | null, val: string | null) { - if (!this.#obj) return; + if (!this.#obj || this.#syncing) return; if (name === 'lat' || name === 'lng') { this.#obj.setLatLng([this.#num('lat'), this.#num('lng')]); } else { @@ -59,6 +62,15 @@ export class LeafletMarker extends withProps(HTMLElement, PROPS) { } } + #onDragEnd = () => { + if (!this.#obj || this.#syncing) return; + this.#syncing = true; + const pos = this.#obj.getLatLng(); + this.setAttribute('lat', String(pos.lat)); + this.setAttribute('lng', String(pos.lng)); + this.#syncing = false; + }; + #num(name: string): number { const v = this.getAttribute(name); return v !== null