@mapka/maplibre-gl-sdk 0.16.1 → 0.16.4
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.
- package/README.md +10 -5
- package/lib/.buildInfo.json +1 -1
- package/lib/components/ImageCarousel.d.ts +7 -0
- package/lib/components/ImageCarousel.d.ts.map +1 -0
- package/lib/components/ImageCarousel.js +22 -0
- package/lib/components/PopupContent.d.ts +5 -1
- package/lib/components/PopupContent.d.ts.map +1 -1
- package/lib/components/PopupContent.js +12 -40
- package/lib/components/PopupDataRows.d.ts +7 -0
- package/lib/components/PopupDataRows.d.ts.map +1 -0
- package/lib/components/PopupDataRows.js +22 -0
- package/lib/components/PopupList.d.ts +10 -0
- package/lib/components/PopupList.d.ts.map +1 -0
- package/lib/components/PopupList.js +32 -0
- package/lib/components/icons/ChevronDownIcon.d.ts +2 -0
- package/lib/components/icons/ChevronDownIcon.d.ts.map +1 -0
- package/lib/components/icons/ChevronDownIcon.js +4 -0
- package/lib/components/icons/ChevronLeftIcon.d.ts +2 -0
- package/lib/components/icons/ChevronLeftIcon.d.ts.map +1 -0
- package/lib/components/icons/ChevronLeftIcon.js +4 -0
- package/lib/components/icons/ChevronRightIcon.d.ts +2 -0
- package/lib/components/icons/ChevronRightIcon.d.ts.map +1 -0
- package/lib/components/icons/ChevronRightIcon.js +4 -0
- package/lib/components/icons/ChevronUpIcon.d.ts +2 -0
- package/lib/components/icons/ChevronUpIcon.d.ts.map +1 -0
- package/lib/components/icons/ChevronUpIcon.js +4 -0
- package/lib/components/icons/CircleIcon.d.ts.map +1 -0
- package/lib/components/icons/CloseIcon.d.ts +2 -0
- package/lib/components/icons/CloseIcon.d.ts.map +1 -0
- package/lib/components/icons/CloseIcon.js +4 -0
- package/lib/components/icons/DownloadIcon.d.ts.map +1 -0
- package/lib/components/icons/FreehandIcon.d.ts.map +1 -0
- package/lib/components/icons/HeartIcon.d.ts +4 -0
- package/lib/components/icons/HeartIcon.d.ts.map +1 -0
- package/lib/components/icons/HeartIcon.js +4 -0
- package/lib/components/icons/LineIcon.d.ts.map +1 -0
- package/lib/components/icons/PencilIcon.d.ts.map +1 -0
- package/lib/components/icons/PolygonIcon.d.ts.map +1 -0
- package/lib/components/icons/ProgressDownIcon.d.ts +2 -0
- package/lib/components/icons/ProgressDownIcon.d.ts.map +1 -0
- package/lib/components/icons/RectangleIcon.d.ts.map +1 -0
- package/lib/components/icons/SelectIcon.d.ts.map +1 -0
- package/lib/components/icons/TrashIcon.d.ts.map +1 -0
- package/lib/controls/MapkaDrawControl.js +7 -7
- package/lib/controls/MapkaExportControl.js +2 -2
- package/lib/map.d.ts +8 -7
- package/lib/map.d.ts.map +1 -1
- package/lib/map.js +15 -9
- package/lib/modules/layerPopup.d.ts +2 -1
- package/lib/modules/layerPopup.d.ts.map +1 -1
- package/lib/modules/layerPopup.js +22 -15
- package/lib/modules/markers.d.ts +5 -0
- package/lib/modules/markers.d.ts.map +1 -1
- package/lib/modules/markers.js +21 -16
- package/lib/modules/popup.d.ts +3 -10
- package/lib/modules/popup.d.ts.map +1 -1
- package/lib/modules/popup.js +116 -100
- package/lib/modules/popupGroups.d.ts +14 -0
- package/lib/modules/popupGroups.d.ts.map +1 -0
- package/lib/modules/popupGroups.js +130 -0
- package/lib/styles.css +1 -1
- package/lib/types/popup.d.ts +10 -1
- package/lib/types/popup.d.ts.map +1 -1
- package/package.json +26 -7
- package/src/components/ImageCarousel.css +73 -0
- package/src/components/ImageCarousel.tsx +76 -0
- package/src/components/PopupContent.css +54 -189
- package/src/components/PopupContent.tsx +26 -195
- package/src/components/PopupDataRows.css +41 -0
- package/src/components/PopupDataRows.tsx +39 -0
- package/src/components/PopupList.css +71 -0
- package/src/components/PopupList.tsx +102 -0
- package/src/components/icons/ChevronDownIcon.tsx +20 -0
- package/src/components/icons/ChevronLeftIcon.tsx +20 -0
- package/src/components/icons/ChevronRightIcon.tsx +20 -0
- package/src/components/icons/ChevronUpIcon.tsx +20 -0
- package/src/components/icons/CloseIcon.tsx +13 -0
- package/src/components/icons/HeartIcon.tsx +18 -0
- package/src/components/{ProgressDownIcon.tsx → icons/ProgressDownIcon.tsx} +0 -3
- package/src/controls/MapkaDrawControl.css +1 -3
- package/src/controls/MapkaDrawControl.tsx +7 -7
- package/src/controls/MapkaExportControl.tsx +2 -2
- package/src/map.ts +28 -20
- package/src/modules/layerPopup.ts +32 -21
- package/src/modules/markers.ts +26 -16
- package/src/modules/popup.tsx +129 -112
- package/src/modules/popupGroups.ts +189 -0
- package/src/styles.css +3 -0
- package/src/types/popup.ts +12 -1
- package/lib/components/CircleIcon.d.ts.map +0 -1
- package/lib/components/DownloadIcon.d.ts.map +0 -1
- package/lib/components/FreehandIcon.d.ts.map +0 -1
- package/lib/components/LineIcon.d.ts.map +0 -1
- package/lib/components/PencilIcon.d.ts.map +0 -1
- package/lib/components/PolygonIcon.d.ts.map +0 -1
- package/lib/components/ProgressDownIcon.d.ts +0 -4
- package/lib/components/ProgressDownIcon.d.ts.map +0 -1
- package/lib/components/RectangleIcon.d.ts.map +0 -1
- package/lib/components/SelectIcon.d.ts.map +0 -1
- package/lib/components/TrashIcon.d.ts.map +0 -1
- /package/lib/components/{CircleIcon.d.ts → icons/CircleIcon.d.ts} +0 -0
- /package/lib/components/{CircleIcon.js → icons/CircleIcon.js} +0 -0
- /package/lib/components/{DownloadIcon.d.ts → icons/DownloadIcon.d.ts} +0 -0
- /package/lib/components/{DownloadIcon.js → icons/DownloadIcon.js} +0 -0
- /package/lib/components/{FreehandIcon.d.ts → icons/FreehandIcon.d.ts} +0 -0
- /package/lib/components/{FreehandIcon.js → icons/FreehandIcon.js} +0 -0
- /package/lib/components/{LineIcon.d.ts → icons/LineIcon.d.ts} +0 -0
- /package/lib/components/{LineIcon.js → icons/LineIcon.js} +0 -0
- /package/lib/components/{PencilIcon.d.ts → icons/PencilIcon.d.ts} +0 -0
- /package/lib/components/{PencilIcon.js → icons/PencilIcon.js} +0 -0
- /package/lib/components/{PolygonIcon.d.ts → icons/PolygonIcon.d.ts} +0 -0
- /package/lib/components/{PolygonIcon.js → icons/PolygonIcon.js} +0 -0
- /package/lib/components/{ProgressDownIcon.js → icons/ProgressDownIcon.js} +0 -0
- /package/lib/components/{RectangleIcon.d.ts → icons/RectangleIcon.d.ts} +0 -0
- /package/lib/components/{RectangleIcon.js → icons/RectangleIcon.js} +0 -0
- /package/lib/components/{SelectIcon.d.ts → icons/SelectIcon.d.ts} +0 -0
- /package/lib/components/{SelectIcon.js → icons/SelectIcon.js} +0 -0
- /package/lib/components/{TrashIcon.d.ts → icons/TrashIcon.d.ts} +0 -0
- /package/lib/components/{TrashIcon.js → icons/TrashIcon.js} +0 -0
- /package/src/components/{CircleIcon.tsx → icons/CircleIcon.tsx} +0 -0
- /package/src/components/{DownloadIcon.tsx → icons/DownloadIcon.tsx} +0 -0
- /package/src/components/{FreehandIcon.tsx → icons/FreehandIcon.tsx} +0 -0
- /package/src/components/{LineIcon.tsx → icons/LineIcon.tsx} +0 -0
- /package/src/components/{PencilIcon.tsx → icons/PencilIcon.tsx} +0 -0
- /package/src/components/{PolygonIcon.tsx → icons/PolygonIcon.tsx} +0 -0
- /package/src/components/{RectangleIcon.tsx → icons/RectangleIcon.tsx} +0 -0
- /package/src/components/{SelectIcon.tsx → icons/SelectIcon.tsx} +0 -0
- /package/src/components/{TrashIcon.tsx → icons/TrashIcon.tsx} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useState } from "preact/hooks";
|
|
2
|
+
import type { MapkaPopupOptionsResolved } from "../types/popup.js";
|
|
3
|
+
import { PopupContent } from "./PopupContent.js";
|
|
4
|
+
import { ChevronUpIcon } from "./icons/ChevronUpIcon.js";
|
|
5
|
+
import { ChevronDownIcon } from "./icons/ChevronDownIcon.js";
|
|
6
|
+
import { noop } from "es-toolkit";
|
|
7
|
+
|
|
8
|
+
interface PopupCollectionProps {
|
|
9
|
+
items: MapkaPopupOptionsResolved[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function PopupCustomElement({ popup }: { popup: HTMLElement }) {
|
|
13
|
+
return popup;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface PopupListNavProps {
|
|
17
|
+
index: number;
|
|
18
|
+
total: number;
|
|
19
|
+
onPrev: (e: Event) => void;
|
|
20
|
+
onNext: (e: Event) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function PopupListNav({ index, total, onPrev, onNext }: PopupListNavProps) {
|
|
24
|
+
const isFirst = index === 0;
|
|
25
|
+
const isLast = index === total - 1;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div class="mapka-popup-list-nav">
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
class="mapka-popup-list-nav-btn"
|
|
32
|
+
onClick={onPrev}
|
|
33
|
+
disabled={isFirst}
|
|
34
|
+
aria-label="Previous popup"
|
|
35
|
+
>
|
|
36
|
+
<ChevronUpIcon />
|
|
37
|
+
</button>
|
|
38
|
+
<div class="mapka-popup-list-nav-counter">
|
|
39
|
+
<span>{index + 1}</span>
|
|
40
|
+
<span class="mapka-popup-list-nav-counter-divider" />
|
|
41
|
+
<span>{total}</span>
|
|
42
|
+
</div>
|
|
43
|
+
<button
|
|
44
|
+
type="button"
|
|
45
|
+
class="mapka-popup-list-nav-btn"
|
|
46
|
+
onClick={onNext}
|
|
47
|
+
disabled={isLast}
|
|
48
|
+
aria-label="Next popup"
|
|
49
|
+
>
|
|
50
|
+
<ChevronDownIcon />
|
|
51
|
+
</button>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function PopupList({ items }: PopupCollectionProps) {
|
|
57
|
+
const [index, setIndex] = useState(0);
|
|
58
|
+
const safeIndex = Math.min(index, items.length - 1);
|
|
59
|
+
|
|
60
|
+
const handlePrev = (e: Event) => {
|
|
61
|
+
e.stopPropagation();
|
|
62
|
+
if (safeIndex > 0) {
|
|
63
|
+
setIndex(safeIndex - 1);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleNext = (e: Event) => {
|
|
68
|
+
e.stopPropagation();
|
|
69
|
+
if (safeIndex < items.length - 1) {
|
|
70
|
+
setIndex(safeIndex + 1);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const { id, content } = items[safeIndex];
|
|
74
|
+
return (
|
|
75
|
+
<div class="mapka-popup-list-wrapper">
|
|
76
|
+
<div class="mapka-popup-list">
|
|
77
|
+
{content instanceof HTMLElement ? (
|
|
78
|
+
<PopupCustomElement key={id} popup={content} />
|
|
79
|
+
) : (
|
|
80
|
+
<PopupContent
|
|
81
|
+
key={id}
|
|
82
|
+
title={content.title}
|
|
83
|
+
description={content.description}
|
|
84
|
+
rows={content.rows}
|
|
85
|
+
imageUrls={content.imageUrls}
|
|
86
|
+
primaryAction={content.primaryAction}
|
|
87
|
+
closeButton={false}
|
|
88
|
+
onClose={noop}
|
|
89
|
+
/>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
{items.length > 1 && (
|
|
93
|
+
<PopupListNav
|
|
94
|
+
index={safeIndex}
|
|
95
|
+
total={items.length}
|
|
96
|
+
onPrev={handlePrev}
|
|
97
|
+
onNext={handleNext}
|
|
98
|
+
/>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function ChevronDownIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 16 16"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M3 6 7.3 10.3a1 1 0 0 0 1.4 0L13 6"
|
|
12
|
+
fill="none"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="1.5"
|
|
15
|
+
stroke-linecap="round"
|
|
16
|
+
stroke-linejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function ChevronLeftIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 16 16"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M10 3 5.7 7.3a1 1 0 0 0 0 1.4L10 13"
|
|
12
|
+
fill="none"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="1.5"
|
|
15
|
+
stroke-linecap="round"
|
|
16
|
+
stroke-linejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function ChevronRightIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 16 16"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="m6 3 4.3 4.3a1 1 0 0 1 0 1.4L6 13"
|
|
12
|
+
fill="none"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="1.5"
|
|
15
|
+
stroke-linecap="round"
|
|
16
|
+
stroke-linejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function ChevronUpIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 16 16"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M3 10 7.3 5.7a1 1 0 0 1 1.4 0L13 10"
|
|
12
|
+
fill="none"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="1.5"
|
|
15
|
+
stroke-linecap="round"
|
|
16
|
+
stroke-linejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function CloseIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 32 32"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon"
|
|
9
|
+
>
|
|
10
|
+
<path d="m8 8 16 16M24 8 8 24" fill="none" stroke="currentColor" stroke-width="2" />
|
|
11
|
+
</svg>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function HeartIcon({ filled }: { filled?: boolean }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
viewBox="0 0 32 32"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
focusable="false"
|
|
8
|
+
class="mapka-popup-icon"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M16 28c7-4.73 14-10 14-17a6.98 6.98 0 0 0-7-7c-1.8 0-3.58.68-4.95 2.05L16 8.1l-2.05-2.05a6.98 6.98 0 0 0-9.9 0A6.98 6.98 0 0 0 2 11c0 7 7 12.27 14 17z"
|
|
12
|
+
fill={filled ? "currentColor" : "none"}
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="2"
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
TerraDrawFreehandMode,
|
|
11
11
|
} from "terra-draw";
|
|
12
12
|
import { TerraDrawMapLibreGLAdapter } from "terra-draw-maplibre-gl-adapter";
|
|
13
|
-
import { SelectIcon } from "../components/SelectIcon.js";
|
|
14
|
-
import { PolygonIcon } from "../components/PolygonIcon.js";
|
|
15
|
-
import { RectangleIcon } from "../components/RectangleIcon.js";
|
|
16
|
-
import { CircleIcon } from "../components/CircleIcon.js";
|
|
17
|
-
import { LineIcon } from "../components/LineIcon.js";
|
|
18
|
-
import { TrashIcon } from "../components/TrashIcon.js";
|
|
19
|
-
import { FreehandIcon } from "../components/FreehandIcon.js";
|
|
13
|
+
import { SelectIcon } from "../components/icons/SelectIcon.js";
|
|
14
|
+
import { PolygonIcon } from "../components/icons/PolygonIcon.js";
|
|
15
|
+
import { RectangleIcon } from "../components/icons/RectangleIcon.js";
|
|
16
|
+
import { CircleIcon } from "../components/icons/CircleIcon.js";
|
|
17
|
+
import { LineIcon } from "../components/icons/LineIcon.js";
|
|
18
|
+
import { TrashIcon } from "../components/icons/TrashIcon.js";
|
|
19
|
+
import { FreehandIcon } from "../components/icons/FreehandIcon.js";
|
|
20
20
|
import { isEmpty } from "es-toolkit/compat";
|
|
21
21
|
import type { IControl } from "maplibre-gl";
|
|
22
22
|
import type { GeoJSONStoreFeatures } from "terra-draw";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render } from "preact";
|
|
2
|
-
import { DownloadIcon } from "../components/DownloadIcon.js";
|
|
3
|
-
import { ProgressDownIcon } from "../components/ProgressDownIcon.js";
|
|
2
|
+
import { DownloadIcon } from "../components/icons/DownloadIcon.js";
|
|
3
|
+
import { ProgressDownIcon } from "../components/icons/ProgressDownIcon.js";
|
|
4
4
|
import type { IControl } from "maplibre-gl";
|
|
5
5
|
import type { MapkaMap } from "../map.js";
|
|
6
6
|
import type { MapkaExportOptions } from "../types/export.js";
|
package/src/map.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import * as maplibregl from "maplibre-gl";
|
|
2
2
|
import { loadLayersIcons } from "./modules/icons.js";
|
|
3
3
|
import { exportMap } from "./modules/export.js";
|
|
4
|
-
import {
|
|
5
|
-
closeOnMapClickPopups,
|
|
6
|
-
closePopupsById,
|
|
7
|
-
openPopup,
|
|
8
|
-
removePopups,
|
|
9
|
-
updatePopup,
|
|
10
|
-
} from "./modules/popup.js";
|
|
4
|
+
import { closePopupsByIds, reconciliatePopups, closePopups } from "./modules/popup.js";
|
|
11
5
|
import {
|
|
12
6
|
addMarkers,
|
|
13
7
|
addStyleDiffMarkers,
|
|
@@ -28,9 +22,9 @@ import type {
|
|
|
28
22
|
} from "maplibre-gl";
|
|
29
23
|
import type { MapkaMarkerOptions } from "./types/marker.js";
|
|
30
24
|
import type { MapkaExportOptions } from "./types/export.js";
|
|
31
|
-
import type { MapkaPopupOptions } from "./types/popup.js";
|
|
25
|
+
import type { MapkaPopupOptions, MapkaPopupOptionsResolved } from "./types/popup.js";
|
|
32
26
|
import type { MapkaAddLayerObject } from "./types/layer.js";
|
|
33
|
-
import {
|
|
27
|
+
import { openClickPopups } from "./modules/layerPopup.js";
|
|
34
28
|
|
|
35
29
|
export interface MapkaMapOptions extends MapOptions {
|
|
36
30
|
maxPopups?: number;
|
|
@@ -65,8 +59,8 @@ const noopTransformStyle: TransformStyleFunction = (_, next) => {
|
|
|
65
59
|
};
|
|
66
60
|
|
|
67
61
|
export type MapMapkaPopup = {
|
|
68
|
-
|
|
69
|
-
options:
|
|
62
|
+
ids: string[];
|
|
63
|
+
options: MapkaPopupOptionsResolved[];
|
|
70
64
|
container: HTMLElement;
|
|
71
65
|
popup: Popup;
|
|
72
66
|
};
|
|
@@ -93,21 +87,31 @@ export class MapkaMap extends maplibregl.Map {
|
|
|
93
87
|
public scrollPopups: boolean = true;
|
|
94
88
|
public popups: MapMapkaPopup[] = [];
|
|
95
89
|
|
|
96
|
-
public constructor({
|
|
90
|
+
public constructor({
|
|
91
|
+
transformRequest,
|
|
92
|
+
apiKey,
|
|
93
|
+
maxPopups = 1,
|
|
94
|
+
scrollPopups = true,
|
|
95
|
+
...options
|
|
96
|
+
}: MapkaMapOptions) {
|
|
97
97
|
super({
|
|
98
98
|
...options,
|
|
99
99
|
transformRequest: createTransformRequest(apiKey, transformRequest),
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
this.maxPopups = maxPopups;
|
|
103
|
+
this.scrollPopups = scrollPopups;
|
|
103
104
|
|
|
104
105
|
super.on("styleimagemissing", (event: MapStyleImageMissingEvent) => {
|
|
105
106
|
loadLayersIcons(this, event);
|
|
106
107
|
});
|
|
107
108
|
|
|
108
109
|
super.on("click", (event: maplibregl.MapMouseEvent) => {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
openClickPopups(this, event);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
super.on("zoomend", () => {
|
|
114
|
+
reconciliatePopups(this);
|
|
111
115
|
});
|
|
112
116
|
|
|
113
117
|
super.on("style.load", () => {
|
|
@@ -144,20 +148,24 @@ export class MapkaMap extends maplibregl.Map {
|
|
|
144
148
|
removeMarkers(this);
|
|
145
149
|
}
|
|
146
150
|
|
|
147
|
-
public openPopup(popup: MapkaPopupOptions) {
|
|
148
|
-
return
|
|
151
|
+
public openPopup(popup: MapkaPopupOptions | MapkaPopupOptions[]) {
|
|
152
|
+
return reconciliatePopups(this, Array.isArray(popup) ? popup : [popup]);
|
|
149
153
|
}
|
|
150
154
|
|
|
151
|
-
public closePopup(id: string) {
|
|
152
|
-
|
|
155
|
+
public closePopup(id: string | string[]) {
|
|
156
|
+
closePopupsByIds(this, Array.isArray(id) ? id : [id]);
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
public updatePopup(popup: MapkaPopupOptions) {
|
|
156
|
-
return
|
|
160
|
+
return reconciliatePopups(this, Array.isArray(popup) ? popup : [popup]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public getPopups() {
|
|
164
|
+
return this.popups;
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
public removePopups() {
|
|
160
|
-
|
|
168
|
+
closePopups(this);
|
|
161
169
|
}
|
|
162
170
|
|
|
163
171
|
public async export(options?: MapkaExportOptions) {
|
|
@@ -1,33 +1,16 @@
|
|
|
1
1
|
import { get } from "es-toolkit/compat";
|
|
2
2
|
import { isBoolean, isPlainObject } from "es-toolkit";
|
|
3
|
-
import
|
|
3
|
+
import { closeOnMapClickPopups, getPopupId } from "./popup.js";
|
|
4
|
+
import type { MapMouseEvent, MapGeoJSONFeature, LngLat, Point } from "maplibre-gl";
|
|
4
5
|
import type { MapkaMap } from "../map.js";
|
|
5
6
|
import type { MapkaLayerPopupOptions } from "../types/popup.js";
|
|
6
7
|
import type { MapkaPopupOptions } from "../types/popup.js";
|
|
7
8
|
|
|
8
|
-
export function openOnFeatureClickPopups(map: MapkaMap, { lngLat, point }: MapMouseEvent) {
|
|
9
|
-
const features = map.queryRenderedFeatures(point);
|
|
10
|
-
|
|
11
|
-
if (features.length === 0) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const popups = getFeaturePopups(features, lngLat);
|
|
16
|
-
|
|
17
|
-
if (popups.length === 0) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
for (const popup of popups) {
|
|
22
|
-
map.openPopup(popup);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
9
|
function genericPropertiesToPopup(feature: MapGeoJSONFeature, lngLat: LngLat): MapkaPopupOptions {
|
|
27
10
|
const { id, properties, layer } = feature;
|
|
28
11
|
|
|
29
12
|
return {
|
|
30
|
-
id: id ?? properties.id,
|
|
13
|
+
id: id ?? properties.id ?? getPopupId(layer),
|
|
31
14
|
lngLat: lngLat.toArray(),
|
|
32
15
|
content: {
|
|
33
16
|
title: layer.id,
|
|
@@ -46,7 +29,13 @@ function buildConfigDrivenPopup(
|
|
|
46
29
|
throw new Error("Not implemented", { cause: { config, feature, lngLat } });
|
|
47
30
|
}
|
|
48
31
|
|
|
49
|
-
function getFeaturePopups(
|
|
32
|
+
function getFeaturePopups(
|
|
33
|
+
map: MapkaMap,
|
|
34
|
+
point: Point,
|
|
35
|
+
lngLat: LngLat,
|
|
36
|
+
trigger: "click" | "hover",
|
|
37
|
+
): MapkaPopupOptions[] {
|
|
38
|
+
const features = map.queryRenderedFeatures(point);
|
|
50
39
|
const popups: MapkaPopupOptions[] = [];
|
|
51
40
|
|
|
52
41
|
for (const feature of features) {
|
|
@@ -66,9 +55,31 @@ function getFeaturePopups(features: MapGeoJSONFeature[], lngLat: LngLat): MapkaP
|
|
|
66
55
|
}
|
|
67
56
|
|
|
68
57
|
if (isPlainObject(mapkaPopup)) {
|
|
58
|
+
if (mapkaPopup.trigger && mapkaPopup.trigger !== trigger) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
69
61
|
popups.push(buildConfigDrivenPopup(feature, mapkaPopup, lngLat));
|
|
70
62
|
}
|
|
71
63
|
}
|
|
72
64
|
|
|
73
65
|
return popups;
|
|
74
66
|
}
|
|
67
|
+
|
|
68
|
+
export function openClickPopups(map: MapkaMap, { lngLat, point }: MapMouseEvent) {
|
|
69
|
+
closeOnMapClickPopups(map);
|
|
70
|
+
|
|
71
|
+
const featurePopups = getFeaturePopups(map, point, lngLat, "click");
|
|
72
|
+
if (featurePopups.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
map.openPopup(featurePopups);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function openOnHoverPopups(map: MapkaMap, { lngLat, point }: MapMouseEvent) {
|
|
79
|
+
const featurePopups = getFeaturePopups(map, point, lngLat, "hover");
|
|
80
|
+
|
|
81
|
+
if (featurePopups.length === 0) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
map.openPopup(featurePopups);
|
|
85
|
+
}
|
package/src/modules/markers.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Marker } from "maplibre-gl";
|
|
2
2
|
import { get } from "es-toolkit/compat";
|
|
3
|
-
import { getPopupId } from "./popup.js";
|
|
4
3
|
import { remove } from "es-toolkit";
|
|
5
4
|
import type { Offset, StyleSpecification } from "maplibre-gl";
|
|
6
5
|
import type { MapkaMap } from "../map.js";
|
|
@@ -26,17 +25,27 @@ export function getMarkerId(marker: { id?: string }) {
|
|
|
26
25
|
return marker.id ?? `marker-${crypto.randomUUID()}`;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
export function getMarkerPopupId(marker: { id?: string }, popup: { id?: string }) {
|
|
29
|
+
return popup.id ?? marker.id ?? `marker-popup-${crypto.randomUUID()}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const markerPopupOptions = (
|
|
33
|
+
id: string,
|
|
34
|
+
marker: Marker,
|
|
35
|
+
popupOptions: Omit<MapkaPopupOptions, "lngLat">,
|
|
36
|
+
) => {
|
|
30
37
|
const latLng = marker.getLngLat().toArray();
|
|
31
38
|
|
|
32
39
|
if ("offset" in popupOptions) {
|
|
33
40
|
return {
|
|
34
41
|
...popupOptions,
|
|
42
|
+
id,
|
|
35
43
|
lngLat: latLng,
|
|
36
44
|
};
|
|
37
45
|
} else {
|
|
38
46
|
return {
|
|
39
47
|
...popupOptions,
|
|
48
|
+
id,
|
|
40
49
|
lngLat: latLng,
|
|
41
50
|
offset: DEFAULT_MARKET_OFFSET,
|
|
42
51
|
};
|
|
@@ -49,51 +58,52 @@ function setupMarkerPopupListeners(
|
|
|
49
58
|
popup: MapkaMarkerPopupOptions,
|
|
50
59
|
options: MapkaMarkerOptions,
|
|
51
60
|
) {
|
|
52
|
-
const popupId = getPopupId(popup);
|
|
53
61
|
const markerElement = marker.getElement();
|
|
62
|
+
const popupId = getMarkerPopupId(options, popup);
|
|
63
|
+
const popupOptions = markerPopupOptions(popupId, marker, popup);
|
|
54
64
|
|
|
55
65
|
if (options.draggable) {
|
|
56
66
|
marker.on("dragend", () => {
|
|
57
|
-
if (map.popups.find((p) => p.
|
|
58
|
-
map.updatePopup(
|
|
67
|
+
if (map.popups.find((p) => p.ids.includes(popupId))) {
|
|
68
|
+
map.updatePopup(popupOptions);
|
|
59
69
|
}
|
|
60
70
|
});
|
|
61
71
|
marker.on("drag", () => {
|
|
62
|
-
if (map.popups.find((p) => p.
|
|
63
|
-
map.updatePopup(
|
|
72
|
+
if (map.popups.find((p) => p.ids.includes(popupId))) {
|
|
73
|
+
map.updatePopup(popupOptions);
|
|
64
74
|
}
|
|
65
75
|
});
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
if (popup.trigger === "always") {
|
|
69
|
-
if (!map.popups.find((p) => p.
|
|
70
|
-
map.openPopup(
|
|
79
|
+
if (!map.popups.find((p) => p.ids.includes(popupId))) {
|
|
80
|
+
map.openPopup(popupOptions);
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
markerElement.addEventListener("click", (e) => {
|
|
74
84
|
e.stopPropagation();
|
|
75
|
-
if (!map.popups.find((p) => p.
|
|
76
|
-
map.openPopup(
|
|
85
|
+
if (!map.popups.find((p) => p.ids.includes(popupId))) {
|
|
86
|
+
map.openPopup(popupOptions);
|
|
77
87
|
}
|
|
78
88
|
});
|
|
79
89
|
} else if (popup.trigger === "click") {
|
|
80
90
|
markerElement.style.cursor = "pointer";
|
|
81
91
|
markerElement.addEventListener("click", (e) => {
|
|
82
92
|
e.stopPropagation();
|
|
83
|
-
if (!map.popups.find((p) => p.
|
|
84
|
-
map.openPopup(
|
|
93
|
+
if (!map.popups.find((p) => p.ids.includes(popupId))) {
|
|
94
|
+
map.openPopup(popupOptions);
|
|
85
95
|
}
|
|
86
96
|
});
|
|
87
97
|
} else if (popup.trigger === "hover") {
|
|
88
98
|
markerElement.addEventListener("mouseenter", (e) => {
|
|
89
99
|
e.stopPropagation();
|
|
90
|
-
if (!map.popups.find((p) => p.
|
|
91
|
-
map.openPopup(
|
|
100
|
+
if (!map.popups.find((p) => p.ids.includes(popupId))) {
|
|
101
|
+
map.openPopup(popupOptions);
|
|
92
102
|
}
|
|
93
103
|
});
|
|
94
104
|
markerElement.addEventListener("mouseleave", (e) => {
|
|
95
105
|
e.stopPropagation();
|
|
96
|
-
if (map.popups.find((p) => p.
|
|
106
|
+
if (map.popups.find((p) => p.ids.includes(popupId))) {
|
|
97
107
|
map.closePopup(popupId);
|
|
98
108
|
}
|
|
99
109
|
});
|