@deepfuture/dui-map 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +214 -0
  2. package/cluster-layer/index.d.ts +2 -0
  3. package/cluster-layer/index.js +2 -0
  4. package/cluster-layer/map-cluster-layer.d.ts +53 -0
  5. package/cluster-layer/map-cluster-layer.js +337 -0
  6. package/controls/index.d.ts +2 -0
  7. package/controls/index.js +2 -0
  8. package/controls/map-controls.d.ts +37 -0
  9. package/controls/map-controls.js +344 -0
  10. package/heatmap/index.d.ts +2 -0
  11. package/heatmap/index.js +2 -0
  12. package/heatmap/map-heatmap.d.ts +39 -0
  13. package/heatmap/map-heatmap.js +330 -0
  14. package/index.d.ts +10 -0
  15. package/index.js +9 -0
  16. package/map/index.d.ts +5 -0
  17. package/map/index.js +3 -0
  18. package/map/map-context.d.ts +8 -0
  19. package/map/map-context.js +2 -0
  20. package/map/map.d.ts +120 -0
  21. package/map/map.js +628 -0
  22. package/marker/index.d.ts +9 -0
  23. package/marker/index.js +7 -0
  24. package/marker/map-marker-content.d.ts +20 -0
  25. package/marker/map-marker-content.js +135 -0
  26. package/marker/map-marker-label.d.ts +21 -0
  27. package/marker/map-marker-label.js +126 -0
  28. package/marker/map-marker-popup.d.ts +25 -0
  29. package/marker/map-marker-popup.js +158 -0
  30. package/marker/map-marker-tooltip.d.ts +22 -0
  31. package/marker/map-marker-tooltip.js +159 -0
  32. package/marker/map-marker.d.ts +48 -0
  33. package/marker/map-marker.js +220 -0
  34. package/marker/marker-context.d.ts +8 -0
  35. package/marker/marker-context.js +2 -0
  36. package/package.json +70 -0
  37. package/popup/index.d.ts +2 -0
  38. package/popup/index.js +2 -0
  39. package/popup/map-popup.d.ts +29 -0
  40. package/popup/map-popup.js +184 -0
  41. package/region/index.d.ts +2 -0
  42. package/region/index.js +2 -0
  43. package/region/map-region.d.ts +41 -0
  44. package/region/map-region.js +276 -0
  45. package/route/index.d.ts +2 -0
  46. package/route/index.js +2 -0
  47. package/route/map-route.d.ts +33 -0
  48. package/route/map-route.js +245 -0
  49. package/theme/map-theme.d.ts +16 -0
  50. package/theme/map-theme.js +233 -0
@@ -0,0 +1,159 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { css, LitElement, html } from "lit";
36
+ import { property } from "lit/decorators.js";
37
+ import { consume } from "@lit/context";
38
+ import { base } from "@deepfuture/dui-primitives/core/base";
39
+ import MapLibreGL from "maplibre-gl";
40
+ import { markerContext } from "./marker-context.js";
41
+ const styles = css `
42
+ :host {
43
+ display: contents;
44
+ }
45
+ `;
46
+ /**
47
+ * `<dui-map-marker-tooltip>` — Hover tooltip on a marker.
48
+ *
49
+ * Shows a popup when the user hovers over the parent marker.
50
+ *
51
+ * @slot - Tooltip content.
52
+ * @csspart tooltip - The tooltip content wrapper.
53
+ */
54
+ let DuiMapMarkerTooltip = (() => {
55
+ let _classSuper = LitElement;
56
+ let _tooltipOffset_decorators;
57
+ let _tooltipOffset_initializers = [];
58
+ let _tooltipOffset_extraInitializers = [];
59
+ let __markerCtx_decorators;
60
+ let __markerCtx_initializers = [];
61
+ let __markerCtx_extraInitializers = [];
62
+ return class DuiMapMarkerTooltip extends _classSuper {
63
+ static {
64
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
65
+ _tooltipOffset_decorators = [property({ type: Number, attribute: "tooltip-offset" })];
66
+ __markerCtx_decorators = [consume({ context: markerContext, subscribe: true })];
67
+ __esDecorate(this, null, _tooltipOffset_decorators, { kind: "accessor", name: "tooltipOffset", static: false, private: false, access: { has: obj => "tooltipOffset" in obj, get: obj => obj.tooltipOffset, set: (obj, value) => { obj.tooltipOffset = value; } }, metadata: _metadata }, _tooltipOffset_initializers, _tooltipOffset_extraInitializers);
68
+ __esDecorate(this, null, __markerCtx_decorators, { kind: "accessor", name: "_markerCtx", static: false, private: false, access: { has: obj => "_markerCtx" in obj, get: obj => obj._markerCtx, set: (obj, value) => { obj._markerCtx = value; } }, metadata: _metadata }, __markerCtx_initializers, __markerCtx_extraInitializers);
69
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
70
+ }
71
+ static tagName = "dui-map-marker-tooltip";
72
+ static styles = [base, styles];
73
+ #tooltipOffset_accessor_storage = __runInitializers(this, _tooltipOffset_initializers, 16);
74
+ /** Tooltip offset from the marker in pixels. */
75
+ get tooltipOffset() { return this.#tooltipOffset_accessor_storage; }
76
+ set tooltipOffset(value) { this.#tooltipOffset_accessor_storage = value; }
77
+ #_markerCtx_accessor_storage = (__runInitializers(this, _tooltipOffset_extraInitializers), __runInitializers(this, __markerCtx_initializers, void 0));
78
+ get _markerCtx() { return this.#_markerCtx_accessor_storage; }
79
+ set _markerCtx(value) { this.#_markerCtx_accessor_storage = value; }
80
+ #tooltip = (__runInitializers(this, __markerCtx_extraInitializers), null);
81
+ #container = document.createElement("div");
82
+ #mouseEnterHandler = null;
83
+ #mouseLeaveHandler = null;
84
+ #bound = false;
85
+ connectedCallback() {
86
+ super.connectedCallback();
87
+ this.#tooltip = new MapLibreGL.Popup({
88
+ offset: this.tooltipOffset,
89
+ closeOnClick: true,
90
+ closeButton: false,
91
+ className: "dui-tooltip",
92
+ }).setMaxWidth("none");
93
+ }
94
+ disconnectedCallback() {
95
+ super.disconnectedCallback();
96
+ this.#unbindEvents();
97
+ this.#tooltip?.remove();
98
+ this.#tooltip = null;
99
+ }
100
+ updated() {
101
+ if (!this._markerCtx?.marker || !this._markerCtx?.map || !this.#tooltip)
102
+ return;
103
+ this.#tooltip.setDOMContent(this.#container);
104
+ if (!this.#bound) {
105
+ this.#bindEvents();
106
+ }
107
+ // Update offset if changed
108
+ if (this.#tooltip.options?.offset !== this.tooltipOffset) {
109
+ this.#tooltip.setOffset(this.tooltipOffset);
110
+ }
111
+ this.#renderIntoPortal();
112
+ }
113
+ #bindEvents() {
114
+ const el = this._markerCtx?.marker?.getElement();
115
+ const map = this._markerCtx?.map;
116
+ if (!el || !map)
117
+ return;
118
+ this.#mouseEnterHandler = () => {
119
+ this.#tooltip.setLngLat(this._markerCtx.marker.getLngLat()).addTo(map);
120
+ };
121
+ this.#mouseLeaveHandler = () => {
122
+ this.#tooltip.remove();
123
+ };
124
+ el.addEventListener("mouseenter", this.#mouseEnterHandler);
125
+ el.addEventListener("mouseleave", this.#mouseLeaveHandler);
126
+ this.#bound = true;
127
+ }
128
+ #unbindEvents() {
129
+ const el = this._markerCtx?.marker?.getElement();
130
+ if (!el)
131
+ return;
132
+ if (this.#mouseEnterHandler)
133
+ el.removeEventListener("mouseenter", this.#mouseEnterHandler);
134
+ if (this.#mouseLeaveHandler)
135
+ el.removeEventListener("mouseleave", this.#mouseLeaveHandler);
136
+ this.#mouseEnterHandler = null;
137
+ this.#mouseLeaveHandler = null;
138
+ this.#bound = false;
139
+ }
140
+ #renderIntoPortal() {
141
+ const slot = this.shadowRoot.querySelector("slot");
142
+ if (!slot)
143
+ return;
144
+ const assigned = slot.assignedNodes({ flatten: true });
145
+ this.#container.innerHTML = "";
146
+ const wrapper = document.createElement("div");
147
+ wrapper.setAttribute("part", "tooltip");
148
+ for (const node of assigned) {
149
+ wrapper.appendChild(node.cloneNode(true));
150
+ }
151
+ this.#container.appendChild(wrapper);
152
+ }
153
+ render() {
154
+ return html `<slot style="display:none" @slotchange=${this.#renderIntoPortal}></slot>`;
155
+ }
156
+ };
157
+ })();
158
+ export { DuiMapMarkerTooltip };
159
+ customElements.define(DuiMapMarkerTooltip.tagName, DuiMapMarkerTooltip);
@@ -0,0 +1,48 @@
1
+ import { LitElement, type PropertyValues, type TemplateResult } from "lit";
2
+ import MapLibreGL from "maplibre-gl";
3
+ import { type MapContext } from "../map/map-context.js";
4
+ import { type MarkerContext } from "./marker-context.js";
5
+ export type LngLat = {
6
+ lng: number;
7
+ lat: number;
8
+ };
9
+ /** Fired when marker drag starts. */
10
+ export declare const dragStartEvent: (detail: LngLat) => CustomEvent<LngLat>;
11
+ /** Fired during marker drag. */
12
+ export declare const dragEvent: (detail: LngLat) => CustomEvent<LngLat>;
13
+ /** Fired when marker drag ends. */
14
+ export declare const dragEndEvent: (detail: LngLat) => CustomEvent<LngLat>;
15
+ /**
16
+ * `<dui-map-marker>` — Places a marker at a coordinate on the map.
17
+ *
18
+ * Contains sub-components: `<dui-map-marker-content>`, `<dui-map-marker-popup>`,
19
+ * `<dui-map-marker-tooltip>`, `<dui-map-marker-label>`.
20
+ *
21
+ * @slot - Marker sub-components.
22
+ * @fires dui-marker-dragstart - Drag started. Detail: { lng, lat }
23
+ * @fires dui-marker-drag - Dragging. Detail: { lng, lat }
24
+ * @fires dui-marker-dragend - Drag ended. Detail: { lng, lat }
25
+ */
26
+ export declare class DuiMapMarker extends LitElement {
27
+ #private;
28
+ static tagName: "dui-map-marker";
29
+ static styles: import("lit").CSSResult[];
30
+ /** Longitude coordinate. */
31
+ accessor longitude: number;
32
+ /** Latitude coordinate. */
33
+ accessor latitude: number;
34
+ /** Whether the marker can be dragged. */
35
+ accessor draggable: boolean;
36
+ /** Marker rotation in degrees. */
37
+ accessor rotation: number;
38
+ /** Offset from the marker center as `[x, y]`. */
39
+ accessor offset: [number, number];
40
+ accessor _mapCtx: MapContext;
41
+ accessor _markerCtx: MarkerContext;
42
+ connectedCallback(): void;
43
+ disconnectedCallback(): void;
44
+ updated(changed: PropertyValues): void;
45
+ /** Get the underlying MapLibre Marker instance. */
46
+ getMarkerInstance(): MapLibreGL.Marker | null;
47
+ render(): TemplateResult;
48
+ }
@@ -0,0 +1,220 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { css, LitElement, html } from "lit";
36
+ import { property, state } from "lit/decorators.js";
37
+ import { provide, consume } from "@lit/context";
38
+ import { base } from "@deepfuture/dui-primitives/core/base";
39
+ import { customEvent } from "@deepfuture/dui-primitives/core/event";
40
+ import MapLibreGL from "maplibre-gl";
41
+ import { mapContext } from "../map/map-context.js";
42
+ import { markerContext } from "./marker-context.js";
43
+ /** Fired when marker drag starts. */
44
+ export const dragStartEvent = customEvent("dui-marker-dragstart", { bubbles: true, composed: true });
45
+ /** Fired during marker drag. */
46
+ export const dragEvent = customEvent("dui-marker-drag", { bubbles: true, composed: true });
47
+ /** Fired when marker drag ends. */
48
+ export const dragEndEvent = customEvent("dui-marker-dragend", { bubbles: true, composed: true });
49
+ const styles = css `
50
+ :host {
51
+ display: contents;
52
+ }
53
+ `;
54
+ /**
55
+ * `<dui-map-marker>` — Places a marker at a coordinate on the map.
56
+ *
57
+ * Contains sub-components: `<dui-map-marker-content>`, `<dui-map-marker-popup>`,
58
+ * `<dui-map-marker-tooltip>`, `<dui-map-marker-label>`.
59
+ *
60
+ * @slot - Marker sub-components.
61
+ * @fires dui-marker-dragstart - Drag started. Detail: { lng, lat }
62
+ * @fires dui-marker-drag - Dragging. Detail: { lng, lat }
63
+ * @fires dui-marker-dragend - Drag ended. Detail: { lng, lat }
64
+ */
65
+ let DuiMapMarker = (() => {
66
+ let _classSuper = LitElement;
67
+ let _longitude_decorators;
68
+ let _longitude_initializers = [];
69
+ let _longitude_extraInitializers = [];
70
+ let _latitude_decorators;
71
+ let _latitude_initializers = [];
72
+ let _latitude_extraInitializers = [];
73
+ let _draggable_decorators;
74
+ let _draggable_initializers = [];
75
+ let _draggable_extraInitializers = [];
76
+ let _rotation_decorators;
77
+ let _rotation_initializers = [];
78
+ let _rotation_extraInitializers = [];
79
+ let _offset_decorators;
80
+ let _offset_initializers = [];
81
+ let _offset_extraInitializers = [];
82
+ let __mapCtx_decorators;
83
+ let __mapCtx_initializers = [];
84
+ let __mapCtx_extraInitializers = [];
85
+ let __markerCtx_decorators;
86
+ let __markerCtx_initializers = [];
87
+ let __markerCtx_extraInitializers = [];
88
+ return class DuiMapMarker extends _classSuper {
89
+ static {
90
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
91
+ _longitude_decorators = [property({ type: Number })];
92
+ _latitude_decorators = [property({ type: Number })];
93
+ _draggable_decorators = [property({ type: Boolean })];
94
+ _rotation_decorators = [property({ type: Number })];
95
+ _offset_decorators = [property({ type: Array })];
96
+ __mapCtx_decorators = [consume({ context: mapContext, subscribe: true })];
97
+ __markerCtx_decorators = [provide({ context: markerContext }), state()];
98
+ __esDecorate(this, null, _longitude_decorators, { kind: "accessor", name: "longitude", static: false, private: false, access: { has: obj => "longitude" in obj, get: obj => obj.longitude, set: (obj, value) => { obj.longitude = value; } }, metadata: _metadata }, _longitude_initializers, _longitude_extraInitializers);
99
+ __esDecorate(this, null, _latitude_decorators, { kind: "accessor", name: "latitude", static: false, private: false, access: { has: obj => "latitude" in obj, get: obj => obj.latitude, set: (obj, value) => { obj.latitude = value; } }, metadata: _metadata }, _latitude_initializers, _latitude_extraInitializers);
100
+ __esDecorate(this, null, _draggable_decorators, { kind: "accessor", name: "draggable", static: false, private: false, access: { has: obj => "draggable" in obj, get: obj => obj.draggable, set: (obj, value) => { obj.draggable = value; } }, metadata: _metadata }, _draggable_initializers, _draggable_extraInitializers);
101
+ __esDecorate(this, null, _rotation_decorators, { kind: "accessor", name: "rotation", static: false, private: false, access: { has: obj => "rotation" in obj, get: obj => obj.rotation, set: (obj, value) => { obj.rotation = value; } }, metadata: _metadata }, _rotation_initializers, _rotation_extraInitializers);
102
+ __esDecorate(this, null, _offset_decorators, { kind: "accessor", name: "offset", static: false, private: false, access: { has: obj => "offset" in obj, get: obj => obj.offset, set: (obj, value) => { obj.offset = value; } }, metadata: _metadata }, _offset_initializers, _offset_extraInitializers);
103
+ __esDecorate(this, null, __mapCtx_decorators, { kind: "accessor", name: "_mapCtx", static: false, private: false, access: { has: obj => "_mapCtx" in obj, get: obj => obj._mapCtx, set: (obj, value) => { obj._mapCtx = value; } }, metadata: _metadata }, __mapCtx_initializers, __mapCtx_extraInitializers);
104
+ __esDecorate(this, null, __markerCtx_decorators, { kind: "accessor", name: "_markerCtx", static: false, private: false, access: { has: obj => "_markerCtx" in obj, get: obj => obj._markerCtx, set: (obj, value) => { obj._markerCtx = value; } }, metadata: _metadata }, __markerCtx_initializers, __markerCtx_extraInitializers);
105
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
106
+ }
107
+ static tagName = "dui-map-marker";
108
+ static styles = [base, styles];
109
+ #longitude_accessor_storage = __runInitializers(this, _longitude_initializers, 0);
110
+ /** Longitude coordinate. */
111
+ get longitude() { return this.#longitude_accessor_storage; }
112
+ set longitude(value) { this.#longitude_accessor_storage = value; }
113
+ #latitude_accessor_storage = (__runInitializers(this, _longitude_extraInitializers), __runInitializers(this, _latitude_initializers, 0));
114
+ /** Latitude coordinate. */
115
+ get latitude() { return this.#latitude_accessor_storage; }
116
+ set latitude(value) { this.#latitude_accessor_storage = value; }
117
+ #draggable_accessor_storage = (__runInitializers(this, _latitude_extraInitializers), __runInitializers(this, _draggable_initializers, false));
118
+ /** Whether the marker can be dragged. */
119
+ get draggable() { return this.#draggable_accessor_storage; }
120
+ set draggable(value) { this.#draggable_accessor_storage = value; }
121
+ #rotation_accessor_storage = (__runInitializers(this, _draggable_extraInitializers), __runInitializers(this, _rotation_initializers, 0));
122
+ /** Marker rotation in degrees. */
123
+ get rotation() { return this.#rotation_accessor_storage; }
124
+ set rotation(value) { this.#rotation_accessor_storage = value; }
125
+ #offset_accessor_storage = (__runInitializers(this, _rotation_extraInitializers), __runInitializers(this, _offset_initializers, [0, 0]));
126
+ /** Offset from the marker center as `[x, y]`. */
127
+ get offset() { return this.#offset_accessor_storage; }
128
+ set offset(value) { this.#offset_accessor_storage = value; }
129
+ #_mapCtx_accessor_storage = (__runInitializers(this, _offset_extraInitializers), __runInitializers(this, __mapCtx_initializers, void 0));
130
+ get _mapCtx() { return this.#_mapCtx_accessor_storage; }
131
+ set _mapCtx(value) { this.#_mapCtx_accessor_storage = value; }
132
+ #marker = (__runInitializers(this, __mapCtx_extraInitializers), null);
133
+ #addedToMap = false;
134
+ #_markerCtx_accessor_storage = __runInitializers(this, __markerCtx_initializers, { marker: null, map: null });
135
+ get _markerCtx() { return this.#_markerCtx_accessor_storage; }
136
+ set _markerCtx(value) { this.#_markerCtx_accessor_storage = value; }
137
+ connectedCallback() {
138
+ super.connectedCallback();
139
+ this.#createMarker();
140
+ }
141
+ disconnectedCallback() {
142
+ super.disconnectedCallback();
143
+ this.#destroyMarker();
144
+ }
145
+ updated(changed) {
146
+ const map = this._mapCtx?.map;
147
+ // Add to map once available
148
+ if (this.#marker && map && !this.#addedToMap) {
149
+ this.#marker.addTo(map);
150
+ this.#addedToMap = true;
151
+ }
152
+ // Update position
153
+ if (this.#marker) {
154
+ const current = this.#marker.getLngLat();
155
+ if (current.lng !== this.longitude || current.lat !== this.latitude) {
156
+ this.#marker.setLngLat([this.longitude, this.latitude]);
157
+ }
158
+ }
159
+ // Update draggable
160
+ if (this.#marker && this.#marker.isDraggable() !== this.draggable) {
161
+ this.#marker.setDraggable(this.draggable);
162
+ }
163
+ // Update offset
164
+ if (this.#marker) {
165
+ const cur = this.#marker.getOffset();
166
+ if (cur.x !== this.offset[0] || cur.y !== this.offset[1]) {
167
+ this.#marker.setOffset(this.offset);
168
+ }
169
+ }
170
+ // Update rotation
171
+ if (this.#marker && this.#marker.getRotation() !== this.rotation) {
172
+ this.#marker.setRotation(this.rotation);
173
+ }
174
+ // Update context only when values actually change
175
+ if (this.#marker && (this._markerCtx.marker !== this.#marker || this._markerCtx.map !== map)) {
176
+ this._markerCtx = { marker: this.#marker, map };
177
+ }
178
+ }
179
+ /** Get the underlying MapLibre Marker instance. */
180
+ getMarkerInstance() {
181
+ return this.#marker;
182
+ }
183
+ #createMarker() {
184
+ this.#marker = new MapLibreGL.Marker({
185
+ element: document.createElement("div"),
186
+ draggable: this.draggable,
187
+ }).setLngLat([this.longitude, this.latitude]);
188
+ // Drag events
189
+ this.#marker.on("dragstart", () => {
190
+ const ll = this.#marker.getLngLat();
191
+ this.dispatchEvent(dragStartEvent({ lng: ll.lng, lat: ll.lat }));
192
+ });
193
+ this.#marker.on("drag", () => {
194
+ const ll = this.#marker.getLngLat();
195
+ this.dispatchEvent(dragEvent({ lng: ll.lng, lat: ll.lat }));
196
+ });
197
+ this.#marker.on("dragend", () => {
198
+ const ll = this.#marker.getLngLat();
199
+ this.dispatchEvent(dragEndEvent({ lng: ll.lng, lat: ll.lat }));
200
+ });
201
+ this._markerCtx = { marker: this.#marker, map: this._mapCtx?.map ?? null };
202
+ }
203
+ #destroyMarker() {
204
+ if (this.#marker) {
205
+ this.#marker.remove();
206
+ this.#marker = null;
207
+ this.#addedToMap = false;
208
+ }
209
+ }
210
+ render() {
211
+ return html `<slot></slot>`;
212
+ }
213
+ constructor() {
214
+ super(...arguments);
215
+ __runInitializers(this, __markerCtx_extraInitializers);
216
+ }
217
+ };
218
+ })();
219
+ export { DuiMapMarker };
220
+ customElements.define(DuiMapMarker.tagName, DuiMapMarker);
@@ -0,0 +1,8 @@
1
+ import type MapLibreGL from "maplibre-gl";
2
+ export type MarkerContext = {
3
+ readonly marker: MapLibreGL.Marker;
4
+ readonly map: MapLibreGL.Map | null;
5
+ };
6
+ export declare const markerContext: {
7
+ __context__: MarkerContext;
8
+ };
@@ -0,0 +1,2 @@
1
+ import { createContext } from "@lit/context";
2
+ export const markerContext = createContext(Symbol("dui-map-marker"));
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@deepfuture/dui-map",
3
+ "version": "1.1.0",
4
+ "description": "DUI map components — MapLibre GL wrapper with markers, routes, regions, and clustering",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/deepfuturenow/dui.git",
10
+ "directory": "packages/map"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": "./index.js",
15
+ "types": "./index.d.ts"
16
+ },
17
+ "./map": {
18
+ "import": "./map/index.js",
19
+ "types": "./map/index.d.ts"
20
+ },
21
+ "./marker": {
22
+ "import": "./marker/index.js",
23
+ "types": "./marker/index.d.ts"
24
+ },
25
+ "./controls": {
26
+ "import": "./controls/index.js",
27
+ "types": "./controls/index.d.ts"
28
+ },
29
+ "./popup": {
30
+ "import": "./popup/index.js",
31
+ "types": "./popup/index.d.ts"
32
+ },
33
+ "./route": {
34
+ "import": "./route/index.js",
35
+ "types": "./route/index.d.ts"
36
+ },
37
+ "./region": {
38
+ "import": "./region/index.js",
39
+ "types": "./region/index.d.ts"
40
+ },
41
+ "./cluster-layer": {
42
+ "import": "./cluster-layer/index.js",
43
+ "types": "./cluster-layer/index.d.ts"
44
+ },
45
+ "./heatmap": {
46
+ "import": "./heatmap/index.js",
47
+ "types": "./heatmap/index.d.ts"
48
+ }
49
+ },
50
+ "files": [
51
+ "**/*.js",
52
+ "**/*.d.ts",
53
+ "**/*.css",
54
+ "README.md"
55
+ ],
56
+ "dependencies": {
57
+ "@deepfuture/dui-primitives": "1.1.0",
58
+ "lit": "^3.3.2",
59
+ "@lit/context": "^1.1.3",
60
+ "maplibre-gl": "^5.15.0"
61
+ },
62
+ "keywords": [
63
+ "web-components",
64
+ "lit",
65
+ "unstyled",
66
+ "components",
67
+ "dui",
68
+ "theme"
69
+ ]
70
+ }
@@ -0,0 +1,2 @@
1
+ import { DuiMapPopup, popupCloseEvent } from "./map-popup.js";
2
+ export { DuiMapPopup, popupCloseEvent };
package/popup/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { DuiMapPopup, popupCloseEvent } from "./map-popup.js";
2
+ export { DuiMapPopup, popupCloseEvent };
@@ -0,0 +1,29 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ import { type MapContext } from "../map/map-context.js";
3
+ /** Fired when the popup is closed. */
4
+ export declare const popupCloseEvent: (detail: void) => CustomEvent<void>;
5
+ /**
6
+ * `<dui-map-popup>` — Standalone popup at coordinates on the map.
7
+ *
8
+ * @slot - Popup content.
9
+ * @csspart popup - The popup content wrapper.
10
+ * @fires dui-map-popup-close - Fired when the popup is closed.
11
+ */
12
+ export declare class DuiMapPopup extends LitElement {
13
+ #private;
14
+ static tagName: "dui-map-popup";
15
+ static styles: import("lit").CSSResult[];
16
+ /** Longitude coordinate for popup position. */
17
+ accessor longitude: number;
18
+ /** Latitude coordinate for popup position. */
19
+ accessor latitude: number;
20
+ /** Popup offset from the anchor in pixels. */
21
+ accessor popupOffset: number;
22
+ /** Show a close button. */
23
+ accessor closeButton: boolean;
24
+ accessor _mapCtx: MapContext;
25
+ connectedCallback(): void;
26
+ disconnectedCallback(): void;
27
+ updated(): void;
28
+ render(): TemplateResult;
29
+ }