You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
leaflet-components/src/elements/leaflet-marker.ts

70 lines
2.3 KiB
TypeScript

import { Icon, Marker, type MarkerOptions } from 'leaflet';
import { bool, num, str, type PropDef } from '../core/props.ts';
import { latLngProps } from '../core/shared-props.ts';
import {
WithProps,
type LeafletAddEventListener,
type LeafletElementConstructor,
type LeafletRemoveEventListener,
} from '../core/with-props.ts';
import type { LeafletIconChangedEvent } from '../core/register.ts';
import type { MarkerEvents } from '../core/event-types.ts';
const PROPS: typeof latLngProps & {
title: PropDef<string, Marker>;
alt: PropDef<string, Marker>;
draggable: PropDef<boolean, Marker>;
opacity: PropDef<number>;
zIndexOffset: PropDef<number>;
} = {
...latLngProps,
// title and alt end up on the <img> Leaflet renders, so live updates go there.
title: str('', {
set: (obj: Marker, value) => {
const el = obj.getElement();
if (el) el.title = value;
},
}),
alt: str('', {
set: (obj: Marker, value) => {
const el = obj.getElement() as HTMLImageElement | undefined;
if (el) el.alt = value;
},
}),
draggable: bool(false, {
set(obj: Marker, value) {
if (value) obj.dragging?.enable();
else obj.dragging?.disable();
},
}),
opacity: num(1.0),
zIndexOffset: num(),
};
const Base: LeafletElementConstructor<Marker, typeof PROPS> = WithProps(PROPS);
/** `<leaflet-marker>` — a Leaflet `Marker`. Accepts `<leaflet-popup>`, `<leaflet-tooltip>`, and `<leaflet-icon>` / `<leaflet-div-icon>` children. */
export default class LeafletMarkerElement extends Base {
declare readonly leafletObject?: Marker;
declare addEventListener: LeafletAddEventListener<MarkerEvents>;
declare removeEventListener: LeafletRemoveEventListener<MarkerEvents>;
createLeafletObject(options: MarkerOptions): Marker {
return new Marker([this.lat, this.lng], options);
}
connectedCallback(): void {
super.connectedCallback();
this.addEventListener('icon-changed', this.#onIconChanged);
}
disconnectedCallback(): void {
this.removeEventListener('icon-changed', this.#onIconChanged);
super.disconnectedCallback();
}
// A <leaflet-icon> or <leaflet-div-icon> child announces itself this way.
#onIconChanged = (e: LeafletIconChangedEvent) => {
this.leafletObject?.setIcon(e.detail.icon ?? new Icon.Default());
};
}