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.
main
Buddy 3 months ago
parent 80c87468b6
commit 78c39f33a3

@ -25,6 +25,7 @@ const PROP_BY_ATTR = new Map<string, string>(
export class LeafletMarker extends withProps(HTMLElement, PROPS) { export class LeafletMarker extends withProps(HTMLElement, PROPS) {
#obj?: Marker; #obj?: Marker;
#syncing = false;
#children = new Map<HTMLElement, ChildEntry>(); #children = new Map<HTMLElement, ChildEntry>();
#childHandler?: (e: LeafletRegisterEvent) => void; #childHandler?: (e: LeafletRegisterEvent) => void;
@ -33,6 +34,7 @@ export class LeafletMarker extends withProps(HTMLElement, PROPS) {
[this.#num('lat'), this.#num('lng')], [this.#num('lat'), this.#num('lng')],
buildOptions(this, PROPS, ['lat', 'lng']), buildOptions(this, PROPS, ['lat', 'lng']),
); );
this.#obj.on('dragend', this.#onDragEnd);
this.#childHandler = createChildRegisterHandler(this.#obj, this.#children); this.#childHandler = createChildRegisterHandler(this.#obj, this.#children);
this.addEventListener('leaflet-register', this.#childHandler); this.addEventListener('leaflet-register', this.#childHandler);
registerWithParent(this, this.#obj); registerWithParent(this, this.#obj);
@ -40,13 +42,14 @@ export class LeafletMarker extends withProps(HTMLElement, PROPS) {
disconnectedCallback() { disconnectedCallback() {
if (this.#childHandler) this.removeEventListener('leaflet-register', this.#childHandler); if (this.#childHandler) this.removeEventListener('leaflet-register', this.#childHandler);
this.#obj?.off('dragend', this.#onDragEnd);
this.#children.clear(); this.#children.clear();
this.#obj?.remove(); this.#obj?.remove();
this.#obj = undefined; this.#obj = undefined;
} }
attributeChangedCallback(name: string, _old: string | null, val: string | null) { attributeChangedCallback(name: string, _old: string | null, val: string | null) {
if (!this.#obj) return; if (!this.#obj || this.#syncing) return;
if (name === 'lat' || name === 'lng') { if (name === 'lat' || name === 'lng') {
this.#obj.setLatLng([this.#num('lat'), this.#num('lng')]); this.#obj.setLatLng([this.#num('lat'), this.#num('lng')]);
} else { } 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 { #num(name: string): number {
const v = this.getAttribute(name); const v = this.getAttribute(name);
return v !== null return v !== null

Loading…
Cancel
Save