@mapka/maplibre-gl-sdk 0.16.1 → 0.16.3
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 +8 -0
- package/lib/components/PopupListItem.d.ts +13 -0
- package/lib/components/PopupListItem.d.ts.map +1 -0
- package/lib/components/PopupListItem.js +11 -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/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 +52 -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 +24 -0
- package/src/components/PopupList.tsx +27 -0
- package/src/components/PopupListItem.css +61 -0
- package/src/components/PopupListItem.tsx +40 -0
- package/src/components/icons/ChevronLeftIcon.tsx +20 -0
- package/src/components/icons/ChevronRightIcon.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.tsx +7 -7
- package/src/controls/MapkaExportControl.tsx +2 -2
- package/src/map.ts +22 -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 +190 -0
- package/src/styles.css +4 -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,61 @@
|
|
|
1
|
+
.mapka-popup-list-item {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
background: #fff;
|
|
6
|
+
border-radius: 8px;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.mapka-popup-list-item + .mapka-popup-list-item {
|
|
12
|
+
border-top: 1px solid #dcdfe3;
|
|
13
|
+
padding-top: 8px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.mapka-popup-list-item-header {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: row;
|
|
19
|
+
height: 90px;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
border-radius: 8px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.mapka-popup-list-item-image {
|
|
25
|
+
width: 90px;
|
|
26
|
+
height: 90px;
|
|
27
|
+
border-radius: 8px;
|
|
28
|
+
object-fit: cover;
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
background: #ccd1d6;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.mapka-popup-list-item-info {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: 4px;
|
|
37
|
+
flex: 1;
|
|
38
|
+
padding: 4px 4px 4px 8px;
|
|
39
|
+
min-width: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.mapka-popup-list-item-title {
|
|
43
|
+
margin: 0;
|
|
44
|
+
font-weight: 700;
|
|
45
|
+
font-size: 16px;
|
|
46
|
+
line-height: 20px;
|
|
47
|
+
color: #4f4f4f;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.mapka-popup-list-item-description {
|
|
51
|
+
margin: 0;
|
|
52
|
+
font-weight: 400;
|
|
53
|
+
font-size: 12px;
|
|
54
|
+
line-height: 16px;
|
|
55
|
+
color: #4f4f4f;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
display: -webkit-box;
|
|
58
|
+
-webkit-line-clamp: 3;
|
|
59
|
+
line-clamp: 3;
|
|
60
|
+
-webkit-box-orient: vertical;
|
|
61
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PopupDataRows } from "./PopupDataRows.js";
|
|
2
|
+
import type { MapkaPopupContent } from "../types/popup.js";
|
|
3
|
+
|
|
4
|
+
interface PopupHeaderProps {
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
imageUrls: string[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function PopupHeader({ title, description, imageUrls: [firstImage] }: PopupHeaderProps) {
|
|
11
|
+
return (
|
|
12
|
+
<div class="mapka-popup-list-item-header">
|
|
13
|
+
{firstImage && <img src={firstImage} alt={title} class="mapka-popup-list-item-image" />}
|
|
14
|
+
|
|
15
|
+
<div class="mapka-popup-list-item-info">
|
|
16
|
+
{title && <span class="mapka-popup-list-item-title">{title}</span>}
|
|
17
|
+
{description && <span class="mapka-popup-list-item-description">{description}</span>}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface PopupCollectionItemProps {
|
|
24
|
+
popup: MapkaPopupContent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function PopupListItem({
|
|
28
|
+
popup: { title, description, rows = [], imageUrls = [] },
|
|
29
|
+
}: PopupCollectionItemProps) {
|
|
30
|
+
const hasImages = Boolean(imageUrls.length);
|
|
31
|
+
const hasHeader = Boolean(title || description || hasImages);
|
|
32
|
+
const hasDataRows = Boolean(rows.length);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div class="mapka-popup-list-item">
|
|
36
|
+
{hasHeader && <PopupHeader title={title} description={description} imageUrls={imageUrls} />}
|
|
37
|
+
{hasDataRows && <PopupDataRows rows={rows} />}
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -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,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,25 @@ export class MapkaMap extends maplibregl.Map {
|
|
|
93
87
|
public scrollPopups: boolean = true;
|
|
94
88
|
public popups: MapMapkaPopup[] = [];
|
|
95
89
|
|
|
96
|
-
public constructor({ transformRequest, apiKey, maxPopups = 1, ...options }: MapkaMapOptions) {
|
|
90
|
+
public constructor({ transformRequest, apiKey, maxPopups = 1, scrollPopups = true, ...options }: MapkaMapOptions) {
|
|
97
91
|
super({
|
|
98
92
|
...options,
|
|
99
93
|
transformRequest: createTransformRequest(apiKey, transformRequest),
|
|
100
94
|
});
|
|
101
95
|
|
|
102
96
|
this.maxPopups = maxPopups;
|
|
97
|
+
this.scrollPopups = scrollPopups;
|
|
103
98
|
|
|
104
99
|
super.on("styleimagemissing", (event: MapStyleImageMissingEvent) => {
|
|
105
100
|
loadLayersIcons(this, event);
|
|
106
101
|
});
|
|
107
102
|
|
|
108
103
|
super.on("click", (event: maplibregl.MapMouseEvent) => {
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
openClickPopups(this, event);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
super.on("zoomend", () => {
|
|
108
|
+
reconciliatePopups(this);
|
|
111
109
|
});
|
|
112
110
|
|
|
113
111
|
super.on("style.load", () => {
|
|
@@ -144,20 +142,24 @@ export class MapkaMap extends maplibregl.Map {
|
|
|
144
142
|
removeMarkers(this);
|
|
145
143
|
}
|
|
146
144
|
|
|
147
|
-
public openPopup(popup: MapkaPopupOptions) {
|
|
148
|
-
return
|
|
145
|
+
public openPopup(popup: MapkaPopupOptions | MapkaPopupOptions[]) {
|
|
146
|
+
return reconciliatePopups(this, Array.isArray(popup) ? popup : [popup]);
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
public closePopup(id: string) {
|
|
152
|
-
|
|
149
|
+
public closePopup(id: string | string[]) {
|
|
150
|
+
closePopupsByIds(this, Array.isArray(id) ? id : [id]);
|
|
153
151
|
}
|
|
154
152
|
|
|
155
153
|
public updatePopup(popup: MapkaPopupOptions) {
|
|
156
|
-
return
|
|
154
|
+
return reconciliatePopups(this, Array.isArray(popup) ? popup : [popup]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public getPopups() {
|
|
158
|
+
return this.popups;
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
public removePopups() {
|
|
160
|
-
|
|
162
|
+
closePopups(this);
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
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
|
});
|