@mapka/maplibre-gl-sdk 0.16.0 → 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 +15 -37
- 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 -0
- 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 +64 -174
- package/src/components/PopupContent.tsx +32 -202
- 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
|
@@ -1,212 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.mapka-popup-icon {
|
|
11
|
-
display: block;
|
|
12
|
-
fill: none;
|
|
13
|
-
height: 16px;
|
|
14
|
-
width: 16px;
|
|
15
|
-
stroke: currentColor;
|
|
16
|
-
overflow: visible;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.mapka-popup-icon-sm {
|
|
20
|
-
height: 12px;
|
|
21
|
-
width: 12px;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.mapka-popup-icon-star {
|
|
25
|
-
height: 12px;
|
|
26
|
-
width: 12px;
|
|
27
|
-
fill: currentColor;
|
|
28
|
-
stroke: none;
|
|
1
|
+
/* Mapka Popup Styles */
|
|
2
|
+
.mapka-popup-container {
|
|
3
|
+
margin-top: -15px;
|
|
4
|
+
margin-bottom: -15px;
|
|
5
|
+
margin-left: -10px;
|
|
6
|
+
margin-right: -10px;
|
|
29
7
|
}
|
|
30
8
|
|
|
31
|
-
|
|
32
|
-
.mapka-popup-carousel {
|
|
9
|
+
.mapka-popup {
|
|
33
10
|
position: relative;
|
|
34
|
-
width: 100%;
|
|
35
|
-
height: 200px;
|
|
36
|
-
overflow: hidden;
|
|
37
|
-
border-radius: 12px 12px 0 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.mapka-popup-carousel-track {
|
|
41
11
|
display: flex;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.mapka-popup-carousel-image {
|
|
47
|
-
min-width: 100%;
|
|
48
|
-
height: 100%;
|
|
49
|
-
object-fit: cover;
|
|
50
|
-
flex-shrink: 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.mapka-popup-carousel-actions {
|
|
54
|
-
position: absolute;
|
|
55
|
-
top: 12px;
|
|
56
|
-
right: 12px;
|
|
57
|
-
display: flex;
|
|
58
|
-
gap: 8px;
|
|
59
|
-
z-index: 3;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.mapka-popup-action-btn {
|
|
63
|
-
background: rgba(255, 255, 255, 0.95);
|
|
64
|
-
border: none;
|
|
65
|
-
border-radius: 50%;
|
|
66
|
-
width: 32px;
|
|
67
|
-
height: 32px;
|
|
68
|
-
cursor: pointer;
|
|
69
|
-
display: flex;
|
|
70
|
-
align-items: center;
|
|
71
|
-
justify-content: center;
|
|
72
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18);
|
|
73
|
-
transition: background 0.2s ease, transform 0.2s ease;
|
|
74
|
-
color: #222;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.mapka-popup-action-btn:hover {
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
align-items: flex-start;
|
|
78
14
|
background: #fff;
|
|
79
|
-
|
|
15
|
+
border: 1px solid #dcdfe3;
|
|
16
|
+
border-radius: 12px;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
box-shadow:
|
|
19
|
+
0px 4px 32px -4px rgba(69, 72, 76, 0.12),
|
|
20
|
+
0px 3px 12px -2px rgba(173, 181, 189, 0.06);
|
|
80
21
|
}
|
|
81
22
|
|
|
82
|
-
.mapka-popup-
|
|
23
|
+
.mapka-popup-close-btn {
|
|
83
24
|
position: absolute;
|
|
84
|
-
top:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
border: none;
|
|
88
|
-
border-radius: 50%;
|
|
89
|
-
width: 28px;
|
|
90
|
-
height: 28px;
|
|
91
|
-
cursor: pointer;
|
|
25
|
+
top: 10px;
|
|
26
|
+
right: 10px;
|
|
27
|
+
z-index: 2;
|
|
92
28
|
display: flex;
|
|
93
29
|
align-items: center;
|
|
94
30
|
justify-content: center;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
color: #222;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.mapka-popup-carousel-btn:hover {
|
|
102
|
-
background: #fff;
|
|
103
|
-
transform: translateY(-50%) scale(1.05);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.mapka-popup-carousel-prev {
|
|
107
|
-
left: 12px;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.mapka-popup-carousel-next {
|
|
111
|
-
right: 12px;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.mapka-popup-dots {
|
|
115
|
-
position: absolute;
|
|
116
|
-
bottom: 12px;
|
|
117
|
-
left: 50%;
|
|
118
|
-
transform: translateX(-50%);
|
|
119
|
-
display: flex;
|
|
120
|
-
gap: 6px;
|
|
121
|
-
z-index: 2;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.mapka-popup-dot {
|
|
125
|
-
width: 6px;
|
|
126
|
-
height: 6px;
|
|
127
|
-
border-radius: 50%;
|
|
128
|
-
background: rgba(255, 255, 255, 0.6);
|
|
31
|
+
width: 24px;
|
|
32
|
+
height: 24px;
|
|
33
|
+
border-radius: 6px;
|
|
129
34
|
border: none;
|
|
35
|
+
background: rgba(255, 255, 255, 0.8);
|
|
130
36
|
cursor: pointer;
|
|
131
37
|
padding: 0;
|
|
132
|
-
|
|
38
|
+
color: #4f4f4f;
|
|
133
39
|
}
|
|
134
40
|
|
|
135
|
-
.mapka-popup-
|
|
136
|
-
|
|
137
|
-
|
|
41
|
+
.mapka-popup-close-btn .mapka-popup-icon {
|
|
42
|
+
width: 16px;
|
|
43
|
+
height: 16px;
|
|
138
44
|
}
|
|
139
45
|
|
|
140
|
-
.mapka-popup-
|
|
141
|
-
background:
|
|
46
|
+
.mapka-popup-close-btn:hover {
|
|
47
|
+
background: rgba(255, 255, 255, 0.95);
|
|
142
48
|
}
|
|
143
49
|
|
|
144
|
-
/* Content */
|
|
145
50
|
.mapka-popup-content {
|
|
146
|
-
padding: 12px 16px 16px;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.mapka-popup-header {
|
|
150
51
|
display: flex;
|
|
151
|
-
|
|
52
|
+
flex-direction: column;
|
|
152
53
|
align-items: flex-start;
|
|
153
|
-
gap:
|
|
154
|
-
|
|
54
|
+
gap: 12px;
|
|
55
|
+
padding: 16px;
|
|
56
|
+
width: 100%;
|
|
57
|
+
box-sizing: border-box;
|
|
155
58
|
}
|
|
156
59
|
|
|
157
60
|
.mapka-popup-title {
|
|
158
61
|
margin: 0;
|
|
159
|
-
font-
|
|
160
|
-
font-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
flex: 1;
|
|
62
|
+
font-weight: 700;
|
|
63
|
+
font-size: 20px;
|
|
64
|
+
line-height: 28px;
|
|
65
|
+
color: #4f4f4f;
|
|
164
66
|
}
|
|
165
67
|
|
|
166
|
-
|
|
167
68
|
.mapka-popup-description {
|
|
168
|
-
margin: 0
|
|
69
|
+
margin: 0;
|
|
70
|
+
font-weight: 400;
|
|
169
71
|
font-size: 14px;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
overflow: hidden;
|
|
173
|
-
text-overflow: ellipsis;
|
|
174
|
-
display: -webkit-box;
|
|
175
|
-
-webkit-line-clamp: 2;
|
|
176
|
-
-webkit-box-orient: vertical;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/* Rows */
|
|
180
|
-
.mapka-popup-rows {
|
|
181
|
-
margin: 12px 0 0 0;
|
|
182
|
-
padding: 12px 0 0 0;
|
|
183
|
-
border-top: 1px solid #ebebeb;
|
|
184
|
-
display: grid;
|
|
185
|
-
grid-template-columns: 1fr 1fr;
|
|
186
|
-
gap: 8px 16px;
|
|
72
|
+
line-height: 18px;
|
|
73
|
+
color: #4f4f4f;
|
|
187
74
|
}
|
|
188
75
|
|
|
189
|
-
.mapka-popup-
|
|
190
|
-
display:
|
|
76
|
+
.mapka-popup-actions {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 8px;
|
|
79
|
+
align-items: flex-start;
|
|
80
|
+
width: 100%;
|
|
191
81
|
}
|
|
192
82
|
|
|
193
|
-
.mapka-popup-
|
|
194
|
-
|
|
83
|
+
.mapka-popup-button-primary {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
gap: 8px;
|
|
88
|
+
flex: 1;
|
|
89
|
+
padding: 10px 16px;
|
|
90
|
+
background: #4f4f4f;
|
|
91
|
+
border: none;
|
|
92
|
+
border-radius: 6px;
|
|
93
|
+
cursor: pointer;
|
|
195
94
|
font-weight: 500;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
overflow: hidden;
|
|
200
|
-
text-overflow: ellipsis;
|
|
95
|
+
font-size: 14px;
|
|
96
|
+
line-height: 18px;
|
|
97
|
+
color: #fff;
|
|
201
98
|
}
|
|
202
99
|
|
|
203
|
-
.mapka-popup-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
color: #222;
|
|
207
|
-
margin: 0;
|
|
208
|
-
text-align: right;
|
|
209
|
-
white-space: nowrap;
|
|
210
|
-
overflow: hidden;
|
|
211
|
-
text-overflow: ellipsis;
|
|
212
|
-
}
|
|
100
|
+
.mapka-popup-button-primary:hover {
|
|
101
|
+
background: #3a3a3a;
|
|
102
|
+
}
|
|
@@ -1,197 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useState } from "preact/hooks";
|
|
1
|
+
import type { MouseEventHandler } from "preact";
|
|
3
2
|
import type { MapkaPopupContent } from "../types/popup.js";
|
|
3
|
+
import { CloseIcon } from "./icons/CloseIcon.js";
|
|
4
|
+
import { PopupDataRows } from "./PopupDataRows.js";
|
|
5
|
+
import { ImageCarousel } from "./ImageCarousel.js";
|
|
4
6
|
|
|
5
7
|
interface PopupProps extends MapkaPopupContent {
|
|
6
8
|
onClose?: () => void;
|
|
7
9
|
closeButton?: boolean;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
aria-hidden="true"
|
|
16
|
-
focusable="false"
|
|
17
|
-
class="mapka-popup-icon"
|
|
18
|
-
>
|
|
19
|
-
<path
|
|
20
|
-
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"
|
|
21
|
-
fill={filled ? "currentColor" : "none"}
|
|
22
|
-
stroke="currentColor"
|
|
23
|
-
stroke-width="2"
|
|
24
|
-
/>
|
|
25
|
-
</svg>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function CloseIcon() {
|
|
30
|
-
return (
|
|
31
|
-
<svg
|
|
32
|
-
viewBox="0 0 32 32"
|
|
33
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
34
|
-
aria-hidden="true"
|
|
35
|
-
focusable="false"
|
|
36
|
-
class="mapka-popup-icon"
|
|
37
|
-
>
|
|
38
|
-
<path d="m6 6 20 20M26 6 6 26" fill="none" stroke="currentColor" stroke-width="3" />
|
|
39
|
-
</svg>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
12
|
+
function PrimaryButton({ label, onClick }: { label: string; onClick?: () => void }) {
|
|
13
|
+
const handleClick = (e: Event) => {
|
|
14
|
+
e.stopPropagation();
|
|
15
|
+
onClick?.();
|
|
16
|
+
};
|
|
42
17
|
|
|
43
|
-
function ChevronLeftIcon() {
|
|
44
18
|
return (
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
aria-hidden="true"
|
|
49
|
-
focusable="false"
|
|
50
|
-
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
51
|
-
>
|
|
52
|
-
<path
|
|
53
|
-
d="M20 28 8.7 16.7a1 1 0 0 1 0-1.4L20 4"
|
|
54
|
-
fill="none"
|
|
55
|
-
stroke="currentColor"
|
|
56
|
-
stroke-width="4"
|
|
57
|
-
/>
|
|
58
|
-
</svg>
|
|
19
|
+
<button type="button" class="mapka-popup-button-primary" onClick={handleClick}>
|
|
20
|
+
{label}
|
|
21
|
+
</button>
|
|
59
22
|
);
|
|
60
23
|
}
|
|
61
24
|
|
|
62
|
-
function
|
|
25
|
+
export function CloseButton({ onClose }: { onClose?: MouseEventHandler<HTMLButtonElement> }) {
|
|
63
26
|
return (
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
aria-hidden="true"
|
|
68
|
-
focusable="false"
|
|
69
|
-
class="mapka-popup-icon mapka-popup-icon-sm"
|
|
70
|
-
>
|
|
71
|
-
<path
|
|
72
|
-
d="m12 4 11.3 11.3a1 1 0 0 1 0 1.4L12 28"
|
|
73
|
-
fill="none"
|
|
74
|
-
stroke="currentColor"
|
|
75
|
-
stroke-width="4"
|
|
76
|
-
/>
|
|
77
|
-
</svg>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function ImageCarousel({
|
|
82
|
-
imageUrls,
|
|
83
|
-
title,
|
|
84
|
-
onFavorite,
|
|
85
|
-
id,
|
|
86
|
-
closeButton,
|
|
87
|
-
onClose,
|
|
88
|
-
}: {
|
|
89
|
-
imageUrls: string[];
|
|
90
|
-
title?: string;
|
|
91
|
-
closeButton?: boolean;
|
|
92
|
-
onFavorite?: (id: string) => void;
|
|
93
|
-
id?: string;
|
|
94
|
-
onClose?: () => void;
|
|
95
|
-
}) {
|
|
96
|
-
const [currentIndex, setCurrentIndex] = useState(0);
|
|
97
|
-
|
|
98
|
-
const handlePrev = (e: Event) => {
|
|
99
|
-
e.stopPropagation();
|
|
100
|
-
setCurrentIndex((prev) => (prev === 0 ? imageUrls.length - 1 : prev - 1));
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const handleNext = (e: Event) => {
|
|
104
|
-
e.stopPropagation();
|
|
105
|
-
setCurrentIndex((prev) => (prev + 1) % imageUrls.length);
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const handleFavoriteClick = (e: Event) => {
|
|
109
|
-
e.stopPropagation();
|
|
110
|
-
if (onFavorite && id) {
|
|
111
|
-
onFavorite(id);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const handleCloseClick = (e: Event) => {
|
|
116
|
-
e.stopPropagation();
|
|
117
|
-
onClose?.();
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<div class="mapka-popup-carousel">
|
|
122
|
-
<div
|
|
123
|
-
class="mapka-popup-carousel-track"
|
|
124
|
-
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
|
|
125
|
-
>
|
|
126
|
-
{imageUrls.map((url, index) => (
|
|
127
|
-
<img
|
|
128
|
-
key={index}
|
|
129
|
-
src={url}
|
|
130
|
-
alt={title || `Image ${index + 1}`}
|
|
131
|
-
class="mapka-popup-carousel-image"
|
|
132
|
-
/>
|
|
133
|
-
))}
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div class="mapka-popup-carousel-actions">
|
|
137
|
-
{onFavorite && (
|
|
138
|
-
<button
|
|
139
|
-
type="button"
|
|
140
|
-
class="mapka-popup-action-btn"
|
|
141
|
-
onClick={handleFavoriteClick}
|
|
142
|
-
aria-label="Add to favorites"
|
|
143
|
-
>
|
|
144
|
-
<HeartIcon />
|
|
145
|
-
</button>
|
|
146
|
-
)}
|
|
147
|
-
{closeButton && (
|
|
148
|
-
<button
|
|
149
|
-
type="button"
|
|
150
|
-
class="mapka-popup-action-btn"
|
|
151
|
-
onClick={handleCloseClick}
|
|
152
|
-
aria-label="Close"
|
|
153
|
-
>
|
|
154
|
-
<CloseIcon />
|
|
155
|
-
</button>
|
|
156
|
-
)}
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
{imageUrls.length > 1 && (
|
|
160
|
-
<Fragment>
|
|
161
|
-
<button
|
|
162
|
-
type="button"
|
|
163
|
-
class="mapka-popup-carousel-btn mapka-popup-carousel-prev"
|
|
164
|
-
onClick={handlePrev}
|
|
165
|
-
aria-label="Previous image"
|
|
166
|
-
>
|
|
167
|
-
<ChevronLeftIcon />
|
|
168
|
-
</button>
|
|
169
|
-
<button
|
|
170
|
-
type="button"
|
|
171
|
-
class="mapka-popup-carousel-btn mapka-popup-carousel-next"
|
|
172
|
-
onClick={handleNext}
|
|
173
|
-
aria-label="Next image"
|
|
174
|
-
>
|
|
175
|
-
<ChevronRightIcon />
|
|
176
|
-
</button>
|
|
177
|
-
|
|
178
|
-
<div class="mapka-popup-dots">
|
|
179
|
-
{imageUrls.map((_, index) => (
|
|
180
|
-
<button
|
|
181
|
-
key={index}
|
|
182
|
-
type="button"
|
|
183
|
-
class={`mapka-popup-dot ${index === currentIndex ? "mapka-popup-dot-active" : ""}`}
|
|
184
|
-
onClick={(e) => {
|
|
185
|
-
e.stopPropagation();
|
|
186
|
-
setCurrentIndex(index);
|
|
187
|
-
}}
|
|
188
|
-
aria-label={`Go to image ${index + 1}`}
|
|
189
|
-
/>
|
|
190
|
-
))}
|
|
191
|
-
</div>
|
|
192
|
-
</Fragment>
|
|
193
|
-
)}
|
|
194
|
-
</div>
|
|
27
|
+
<button type="button" class="mapka-popup-close-btn" onClick={onClose} aria-label="Close">
|
|
28
|
+
<CloseIcon />
|
|
29
|
+
</button>
|
|
195
30
|
);
|
|
196
31
|
}
|
|
197
32
|
|
|
@@ -200,38 +35,33 @@ export function PopupContent({
|
|
|
200
35
|
description,
|
|
201
36
|
rows,
|
|
202
37
|
closeButton,
|
|
203
|
-
imageUrls,
|
|
204
|
-
|
|
38
|
+
imageUrls = [],
|
|
39
|
+
primaryAction,
|
|
205
40
|
onClose,
|
|
206
41
|
}: PopupProps) {
|
|
207
42
|
const hasImages = imageUrls && imageUrls.length > 0;
|
|
208
43
|
const hasRows = rows && rows.length > 0;
|
|
209
44
|
|
|
45
|
+
const handleCloseClick = (e: Event) => {
|
|
46
|
+
e.stopPropagation();
|
|
47
|
+
onClose?.();
|
|
48
|
+
};
|
|
49
|
+
|
|
210
50
|
return (
|
|
211
|
-
<div class="mapka-
|
|
212
|
-
{
|
|
213
|
-
|
|
214
|
-
imageUrls={imageUrls}
|
|
215
|
-
title={title}
|
|
216
|
-
closeButton={closeButton}
|
|
217
|
-
onFavorite={onFavorite}
|
|
218
|
-
onClose={onClose}
|
|
219
|
-
/>
|
|
220
|
-
)}
|
|
51
|
+
<div class="mapka-popup">
|
|
52
|
+
{closeButton && <CloseButton onClose={handleCloseClick} />}
|
|
53
|
+
{hasImages && <ImageCarousel imageUrls={imageUrls} title={title} />}
|
|
221
54
|
|
|
222
55
|
<div class="mapka-popup-content">
|
|
223
56
|
{title && <h3 class="mapka-popup-title">{title}</h3>}
|
|
224
57
|
{description && <p class="mapka-popup-description">{description}</p>}
|
|
225
58
|
|
|
226
|
-
{hasRows &&
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
</div>
|
|
233
|
-
))}
|
|
234
|
-
</dl>
|
|
59
|
+
{hasRows && <PopupDataRows rows={rows} />}
|
|
60
|
+
|
|
61
|
+
{primaryAction && (
|
|
62
|
+
<div class="mapka-popup-actions">
|
|
63
|
+
<PrimaryButton label={primaryAction.label} onClick={primaryAction.onClick} />
|
|
64
|
+
</div>
|
|
235
65
|
)}
|
|
236
66
|
</div>
|
|
237
67
|
</div>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
.mapka-popup-rows {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 2px;
|
|
5
|
+
margin: 0;
|
|
6
|
+
width: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.mapka-popup-row {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: row;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: 16px;
|
|
14
|
+
height: 30px;
|
|
15
|
+
padding: 0 8px;
|
|
16
|
+
border-radius: 6px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.mapka-popup-row-label {
|
|
20
|
+
flex: 1;
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-weight: 400;
|
|
23
|
+
font-size: 12px;
|
|
24
|
+
line-height: 16px;
|
|
25
|
+
color: #4f4f4f;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.mapka-popup-row-value {
|
|
29
|
+
flex: 1;
|
|
30
|
+
margin: 0;
|
|
31
|
+
font-weight: 400;
|
|
32
|
+
font-size: 12px;
|
|
33
|
+
line-height: 16px;
|
|
34
|
+
color: #4f4f4f;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.mapka-popup-row-divider {
|
|
38
|
+
height: 0;
|
|
39
|
+
border-bottom: 1px solid #e0e0e0;
|
|
40
|
+
width: 100%;
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { MapkaPopupRow } from "../types/popup.js";
|
|
2
|
+
|
|
3
|
+
export function displayRowValue(value: unknown) {
|
|
4
|
+
if (value == null) {
|
|
5
|
+
return "-";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (typeof value === "number") {
|
|
9
|
+
return value.toLocaleString();
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "boolean") {
|
|
12
|
+
return value ? "true" : "false";
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === "object") {
|
|
15
|
+
return JSON.stringify(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function displayRowName(name: string) {
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function PopupDataRows({ rows }: { rows: MapkaPopupRow[] }) {
|
|
26
|
+
return (
|
|
27
|
+
<dl class="mapka-popup-rows">
|
|
28
|
+
{rows.map((row, index) => (
|
|
29
|
+
<>
|
|
30
|
+
{index > 0 && <div class="mapka-popup-row-divider" />}
|
|
31
|
+
<div key={index} class="mapka-popup-row">
|
|
32
|
+
<dt class="mapka-popup-row-label">{displayRowName(row.name)}</dt>
|
|
33
|
+
<dd class="mapka-popup-row-value">{displayRowValue(row.value)}</dd>
|
|
34
|
+
</div>
|
|
35
|
+
</>
|
|
36
|
+
))}
|
|
37
|
+
</dl>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.mapka-popup-list-wrapper {
|
|
2
|
+
width: 100%;
|
|
3
|
+
overflow-y: auto;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.mapka-popup-list {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: 8px;
|
|
10
|
+
overflow-y: auto;
|
|
11
|
+
max-height: 265px;
|
|
12
|
+
padding: 8px 8px 24px;
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.mapka-popup-list-gradient {
|
|
17
|
+
position: absolute;
|
|
18
|
+
bottom: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
right: 0;
|
|
21
|
+
height: 54px;
|
|
22
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #fff 100%);
|
|
23
|
+
pointer-events: none;
|
|
24
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MapkaPopupOptionsResolved } from "../types/popup.js";
|
|
2
|
+
import { PopupListItem } from "./PopupListItem.js";
|
|
3
|
+
|
|
4
|
+
interface PopupCollectionProps {
|
|
5
|
+
items: MapkaPopupOptionsResolved[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function PopupCustomElement({ popup }: { popup: HTMLElement }) {
|
|
9
|
+
return popup;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function PopupList({ items }: PopupCollectionProps) {
|
|
13
|
+
return (
|
|
14
|
+
<div class="mapka-popup-list-wrapper">
|
|
15
|
+
<div class="mapka-popup-list">
|
|
16
|
+
{items.map(({ content, id }) =>
|
|
17
|
+
content instanceof HTMLElement ? (
|
|
18
|
+
<PopupCustomElement key={id} popup={content} />
|
|
19
|
+
) : (
|
|
20
|
+
<PopupListItem key={id} popup={content} />
|
|
21
|
+
),
|
|
22
|
+
)}
|
|
23
|
+
</div>
|
|
24
|
+
<div class="mapka-popup-list-gradient" />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|