@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,20 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ import { type MarkerContext } from "./marker-context.js";
3
+ /**
4
+ * `<dui-map-marker-content>` — Custom marker DOM content.
5
+ *
6
+ * Renders slotted content into the marker's DOM element. If no content
7
+ * is provided, renders a default blue dot marker.
8
+ *
9
+ * @slot - Custom marker content.
10
+ * @csspart root - Wrapper div inside the marker element.
11
+ */
12
+ export declare class DuiMapMarkerContent extends LitElement {
13
+ #private;
14
+ static tagName: "dui-map-marker-content";
15
+ static styles: import("lit").CSSResult[];
16
+ accessor _markerCtx: MarkerContext;
17
+ connectedCallback(): void;
18
+ updated(): void;
19
+ render(): TemplateResult;
20
+ }
@@ -0,0 +1,135 @@
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 { consume } from "@lit/context";
37
+ import { base } from "@deepfuture/dui-primitives/core/base";
38
+ import { markerContext } from "./marker-context.js";
39
+ const styles = css `
40
+ :host {
41
+ display: contents;
42
+ }
43
+
44
+ [part="root"] {
45
+ position: relative;
46
+ cursor: pointer;
47
+ }
48
+
49
+ .default-marker {
50
+ width: 16px;
51
+ height: 16px;
52
+ border-radius: 50%;
53
+ border: 2px solid white;
54
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
55
+ }
56
+ `;
57
+ /**
58
+ * `<dui-map-marker-content>` — Custom marker DOM content.
59
+ *
60
+ * Renders slotted content into the marker's DOM element. If no content
61
+ * is provided, renders a default blue dot marker.
62
+ *
63
+ * @slot - Custom marker content.
64
+ * @csspart root - Wrapper div inside the marker element.
65
+ */
66
+ let DuiMapMarkerContent = (() => {
67
+ let _classSuper = LitElement;
68
+ let __markerCtx_decorators;
69
+ let __markerCtx_initializers = [];
70
+ let __markerCtx_extraInitializers = [];
71
+ return class DuiMapMarkerContent extends _classSuper {
72
+ static {
73
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
74
+ __markerCtx_decorators = [consume({ context: markerContext, subscribe: true })];
75
+ __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);
76
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
77
+ }
78
+ static tagName = "dui-map-marker-content";
79
+ static styles = [base, styles];
80
+ #_markerCtx_accessor_storage = __runInitializers(this, __markerCtx_initializers, void 0);
81
+ get _markerCtx() { return this.#_markerCtx_accessor_storage; }
82
+ set _markerCtx(value) { this.#_markerCtx_accessor_storage = value; }
83
+ #portalContainer = (__runInitializers(this, __markerCtx_extraInitializers), null);
84
+ #hasSlottedContent = false;
85
+ connectedCallback() {
86
+ super.connectedCallback();
87
+ this.#portalContainer = document.createElement("div");
88
+ this.#portalContainer.setAttribute("part", "root");
89
+ this.#portalContainer.style.position = "relative";
90
+ this.#portalContainer.style.cursor = "pointer";
91
+ }
92
+ updated() {
93
+ if (!this._markerCtx?.marker || !this.#portalContainer)
94
+ return;
95
+ const el = this._markerCtx.marker.getElement();
96
+ if (el && !el.contains(this.#portalContainer)) {
97
+ // Clear default MapLibre marker styling
98
+ el.style.backgroundImage = "none";
99
+ el.style.width = "";
100
+ el.style.height = "";
101
+ el.appendChild(this.#portalContainer);
102
+ }
103
+ this.#renderIntoPortal();
104
+ }
105
+ #renderIntoPortal() {
106
+ if (!this.#portalContainer)
107
+ return;
108
+ // Move slotted light DOM children into the marker element
109
+ const slot = this.shadowRoot.querySelector("slot");
110
+ if (!slot)
111
+ return;
112
+ const assigned = slot.assignedNodes({ flatten: true });
113
+ this.#hasSlottedContent = assigned.length > 0;
114
+ // Clear and re-append
115
+ this.#portalContainer.innerHTML = "";
116
+ if (this.#hasSlottedContent) {
117
+ for (const node of assigned) {
118
+ this.#portalContainer.appendChild(node.cloneNode(true));
119
+ }
120
+ }
121
+ else {
122
+ // Default marker — styled by the dui-map theme via .dui-default-marker
123
+ const dot = document.createElement("div");
124
+ dot.className = "dui-default-marker";
125
+ this.#portalContainer.appendChild(dot);
126
+ }
127
+ }
128
+ render() {
129
+ // Hidden slot — content is portaled into the marker element
130
+ return html `<slot style="display:none" @slotchange=${this.#renderIntoPortal}></slot>`;
131
+ }
132
+ };
133
+ })();
134
+ export { DuiMapMarkerContent };
135
+ customElements.define(DuiMapMarkerContent.tagName, DuiMapMarkerContent);
@@ -0,0 +1,21 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ import { type MarkerContext } from "./marker-context.js";
3
+ /**
4
+ * `<dui-map-marker-label>` — Static label above or below a marker.
5
+ *
6
+ * Renders slotted text content as a label positioned relative to the marker.
7
+ *
8
+ * @slot - Label text content.
9
+ * @csspart label - The label element.
10
+ */
11
+ export declare class DuiMapMarkerLabel extends LitElement {
12
+ #private;
13
+ static tagName: "dui-map-marker-label";
14
+ static styles: import("lit").CSSResult[];
15
+ /** Position of the label relative to the marker. */
16
+ accessor position: "top" | "bottom";
17
+ accessor _markerCtx: MarkerContext;
18
+ updated(): void;
19
+ disconnectedCallback(): void;
20
+ render(): TemplateResult;
21
+ }
@@ -0,0 +1,126 @@
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 { markerContext } from "./marker-context.js";
40
+ const styles = css `
41
+ :host {
42
+ display: contents;
43
+ }
44
+ `;
45
+ /**
46
+ * `<dui-map-marker-label>` — Static label above or below a marker.
47
+ *
48
+ * Renders slotted text content as a label positioned relative to the marker.
49
+ *
50
+ * @slot - Label text content.
51
+ * @csspart label - The label element.
52
+ */
53
+ let DuiMapMarkerLabel = (() => {
54
+ let _classSuper = LitElement;
55
+ let _position_decorators;
56
+ let _position_initializers = [];
57
+ let _position_extraInitializers = [];
58
+ let __markerCtx_decorators;
59
+ let __markerCtx_initializers = [];
60
+ let __markerCtx_extraInitializers = [];
61
+ return class DuiMapMarkerLabel extends _classSuper {
62
+ static {
63
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
64
+ _position_decorators = [property()];
65
+ __markerCtx_decorators = [consume({ context: markerContext, subscribe: true })];
66
+ __esDecorate(this, null, _position_decorators, { kind: "accessor", name: "position", static: false, private: false, access: { has: obj => "position" in obj, get: obj => obj.position, set: (obj, value) => { obj.position = value; } }, metadata: _metadata }, _position_initializers, _position_extraInitializers);
67
+ __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);
68
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
69
+ }
70
+ static tagName = "dui-map-marker-label";
71
+ static styles = [base, styles];
72
+ #position_accessor_storage = __runInitializers(this, _position_initializers, "top");
73
+ /** Position of the label relative to the marker. */
74
+ get position() { return this.#position_accessor_storage; }
75
+ set position(value) { this.#position_accessor_storage = value; }
76
+ #_markerCtx_accessor_storage = (__runInitializers(this, _position_extraInitializers), __runInitializers(this, __markerCtx_initializers, void 0));
77
+ get _markerCtx() { return this.#_markerCtx_accessor_storage; }
78
+ set _markerCtx(value) { this.#_markerCtx_accessor_storage = value; }
79
+ #labelEl = (__runInitializers(this, __markerCtx_extraInitializers), null);
80
+ updated() {
81
+ if (!this._markerCtx?.marker)
82
+ return;
83
+ const markerEl = this._markerCtx.marker.getElement();
84
+ if (!markerEl)
85
+ return;
86
+ if (!this.#labelEl) {
87
+ this.#labelEl = document.createElement("div");
88
+ this.#labelEl.setAttribute("part", "label");
89
+ this.#labelEl.className = "dui-marker-label";
90
+ markerEl.appendChild(this.#labelEl);
91
+ }
92
+ // Position — structural only (aesthetic styles in theme)
93
+ this.#labelEl.style.cssText = `
94
+ position: absolute;
95
+ left: 50%;
96
+ transform: translateX(-50%);
97
+ white-space: nowrap;
98
+ pointer-events: none;
99
+ ${this.position === "top" ? "bottom: 100%; margin-bottom: 4px;" : "top: 100%; margin-top: 4px;"}
100
+ `;
101
+ this.#renderIntoPortal();
102
+ }
103
+ disconnectedCallback() {
104
+ super.disconnectedCallback();
105
+ this.#labelEl?.remove();
106
+ this.#labelEl = null;
107
+ }
108
+ #renderIntoPortal() {
109
+ if (!this.#labelEl)
110
+ return;
111
+ const slot = this.shadowRoot.querySelector("slot");
112
+ if (!slot)
113
+ return;
114
+ const assigned = slot.assignedNodes({ flatten: true });
115
+ this.#labelEl.innerHTML = "";
116
+ for (const node of assigned) {
117
+ this.#labelEl.appendChild(node.cloneNode(true));
118
+ }
119
+ }
120
+ render() {
121
+ return html `<slot style="display:none" @slotchange=${this.#renderIntoPortal}></slot>`;
122
+ }
123
+ };
124
+ })();
125
+ export { DuiMapMarkerLabel };
126
+ customElements.define(DuiMapMarkerLabel.tagName, DuiMapMarkerLabel);
@@ -0,0 +1,25 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ import { type MarkerContext } from "./marker-context.js";
3
+ /**
4
+ * `<dui-map-marker-popup>` — Click-to-open popup on a marker.
5
+ *
6
+ * Slotted content is rendered inside a MapLibre popup attached to the parent marker.
7
+ * The popup opens when the marker is clicked.
8
+ *
9
+ * @slot - Popup content.
10
+ * @csspart popup - The popup content wrapper.
11
+ */
12
+ export declare class DuiMapMarkerPopup extends LitElement {
13
+ #private;
14
+ static tagName: "dui-map-marker-popup";
15
+ static styles: import("lit").CSSResult[];
16
+ /** Popup offset from the marker in pixels. */
17
+ accessor popupOffset: number;
18
+ /** Show a close button. */
19
+ accessor closeButton: boolean;
20
+ accessor _markerCtx: MarkerContext;
21
+ connectedCallback(): void;
22
+ disconnectedCallback(): void;
23
+ updated(): void;
24
+ render(): TemplateResult;
25
+ }
@@ -0,0 +1,158 @@
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-popup>` — Click-to-open popup on a marker.
48
+ *
49
+ * Slotted content is rendered inside a MapLibre popup attached to the parent marker.
50
+ * The popup opens when the marker is clicked.
51
+ *
52
+ * @slot - Popup content.
53
+ * @csspart popup - The popup content wrapper.
54
+ */
55
+ let DuiMapMarkerPopup = (() => {
56
+ let _classSuper = LitElement;
57
+ let _popupOffset_decorators;
58
+ let _popupOffset_initializers = [];
59
+ let _popupOffset_extraInitializers = [];
60
+ let _closeButton_decorators;
61
+ let _closeButton_initializers = [];
62
+ let _closeButton_extraInitializers = [];
63
+ let __markerCtx_decorators;
64
+ let __markerCtx_initializers = [];
65
+ let __markerCtx_extraInitializers = [];
66
+ return class DuiMapMarkerPopup extends _classSuper {
67
+ static {
68
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
69
+ _popupOffset_decorators = [property({ type: Number, attribute: "popup-offset" })];
70
+ _closeButton_decorators = [property({ type: Boolean, attribute: "close-button" })];
71
+ __markerCtx_decorators = [consume({ context: markerContext, subscribe: true })];
72
+ __esDecorate(this, null, _popupOffset_decorators, { kind: "accessor", name: "popupOffset", static: false, private: false, access: { has: obj => "popupOffset" in obj, get: obj => obj.popupOffset, set: (obj, value) => { obj.popupOffset = value; } }, metadata: _metadata }, _popupOffset_initializers, _popupOffset_extraInitializers);
73
+ __esDecorate(this, null, _closeButton_decorators, { kind: "accessor", name: "closeButton", static: false, private: false, access: { has: obj => "closeButton" in obj, get: obj => obj.closeButton, set: (obj, value) => { obj.closeButton = value; } }, metadata: _metadata }, _closeButton_initializers, _closeButton_extraInitializers);
74
+ __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);
75
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
76
+ }
77
+ static tagName = "dui-map-marker-popup";
78
+ static styles = [base, styles];
79
+ #popupOffset_accessor_storage = __runInitializers(this, _popupOffset_initializers, 16);
80
+ /** Popup offset from the marker in pixels. */
81
+ get popupOffset() { return this.#popupOffset_accessor_storage; }
82
+ set popupOffset(value) { this.#popupOffset_accessor_storage = value; }
83
+ #closeButton_accessor_storage = (__runInitializers(this, _popupOffset_extraInitializers), __runInitializers(this, _closeButton_initializers, false));
84
+ /** Show a close button. */
85
+ get closeButton() { return this.#closeButton_accessor_storage; }
86
+ set closeButton(value) { this.#closeButton_accessor_storage = value; }
87
+ #_markerCtx_accessor_storage = (__runInitializers(this, _closeButton_extraInitializers), __runInitializers(this, __markerCtx_initializers, void 0));
88
+ get _markerCtx() { return this.#_markerCtx_accessor_storage; }
89
+ set _markerCtx(value) { this.#_markerCtx_accessor_storage = value; }
90
+ #popup = (__runInitializers(this, __markerCtx_extraInitializers), null);
91
+ #container = document.createElement("div");
92
+ #attachedToMarker = false;
93
+ connectedCallback() {
94
+ super.connectedCallback();
95
+ this.#popup = new MapLibreGL.Popup({
96
+ offset: this.popupOffset,
97
+ closeButton: false,
98
+ closeOnClick: true,
99
+ className: "dui-popup",
100
+ })
101
+ .setMaxWidth("none")
102
+ .setDOMContent(this.#container);
103
+ }
104
+ disconnectedCallback() {
105
+ super.disconnectedCallback();
106
+ if (this._markerCtx?.marker) {
107
+ this._markerCtx.marker.setPopup(null);
108
+ }
109
+ this.#popup?.remove();
110
+ this.#popup = null;
111
+ this.#attachedToMarker = false;
112
+ }
113
+ updated() {
114
+ if (!this._markerCtx?.marker || !this._markerCtx?.map || !this.#popup)
115
+ return;
116
+ if (!this.#attachedToMarker) {
117
+ this.#popup.setDOMContent(this.#container);
118
+ this._markerCtx.marker.setPopup(this.#popup);
119
+ this.#attachedToMarker = true;
120
+ }
121
+ // Update offset if changed
122
+ if (this.#popup.options?.offset !== this.popupOffset) {
123
+ this.#popup.setOffset(this.popupOffset);
124
+ }
125
+ this.#renderIntoPortal();
126
+ }
127
+ #handleClose = () => {
128
+ this.#popup?.remove();
129
+ };
130
+ #renderIntoPortal() {
131
+ const slot = this.shadowRoot.querySelector("slot");
132
+ if (!slot)
133
+ return;
134
+ const assigned = slot.assignedNodes({ flatten: true });
135
+ this.#container.innerHTML = "";
136
+ const wrapper = document.createElement("div");
137
+ wrapper.setAttribute("part", "popup");
138
+ if (this.closeButton) {
139
+ const btn = document.createElement("button");
140
+ btn.setAttribute("aria-label", "Close popup");
141
+ btn.type = "button";
142
+ btn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>`;
143
+ btn.style.cssText = "position:absolute;top:4px;right:4px;z-index:10;background:none;border:none;cursor:pointer;padding:2px;opacity:0.7;color:inherit;";
144
+ btn.addEventListener("click", this.#handleClose);
145
+ wrapper.appendChild(btn);
146
+ }
147
+ for (const node of assigned) {
148
+ wrapper.appendChild(node.cloneNode(true));
149
+ }
150
+ this.#container.appendChild(wrapper);
151
+ }
152
+ render() {
153
+ return html `<slot style="display:none" @slotchange=${this.#renderIntoPortal}></slot>`;
154
+ }
155
+ };
156
+ })();
157
+ export { DuiMapMarkerPopup };
158
+ customElements.define(DuiMapMarkerPopup.tagName, DuiMapMarkerPopup);
@@ -0,0 +1,22 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ import { type MarkerContext } from "./marker-context.js";
3
+ /**
4
+ * `<dui-map-marker-tooltip>` — Hover tooltip on a marker.
5
+ *
6
+ * Shows a popup when the user hovers over the parent marker.
7
+ *
8
+ * @slot - Tooltip content.
9
+ * @csspart tooltip - The tooltip content wrapper.
10
+ */
11
+ export declare class DuiMapMarkerTooltip extends LitElement {
12
+ #private;
13
+ static tagName: "dui-map-marker-tooltip";
14
+ static styles: import("lit").CSSResult[];
15
+ /** Tooltip offset from the marker in pixels. */
16
+ accessor tooltipOffset: number;
17
+ accessor _markerCtx: MarkerContext;
18
+ connectedCallback(): void;
19
+ disconnectedCallback(): void;
20
+ updated(): void;
21
+ render(): TemplateResult;
22
+ }