mehdi-akbari-map 0.0.6 → 0.0.8
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/dist/components/Map.d.ts.map +1 -1
- package/dist/index.cjs +63 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +19 -17
- package/dist/index.css.map +1 -1
- package/dist/index.js +63 -36
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +63 -36
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +63 -36
- package/dist/react.js.map +1 -1
- package/dist/styles.css +19 -26
- package/dist/utils/createCustomMarkerElement.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["../../src/components/Map.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["../../src/components/Map.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIhE,OAAO,yDAAyD,CAAC;AAEjE,QAAA,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAgH3B,CAAC;AAEF,eAAe,GAAG,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -44,24 +44,25 @@ function createCustomMarkerElement({
|
|
|
44
44
|
logoSrc = "",
|
|
45
45
|
showPrice = true
|
|
46
46
|
}) {
|
|
47
|
-
const
|
|
48
|
-
|
|
47
|
+
const container = document.createElement("div");
|
|
48
|
+
container.className = "neshan-marker-container";
|
|
49
|
+
const body = document.createElement("div");
|
|
50
|
+
body.className = `neshan-marker-body ${isSelected ? "neshan-marker-selected" : ""}`;
|
|
51
|
+
Object.assign(body.style, {
|
|
49
52
|
display: "flex",
|
|
50
53
|
flexDirection: "column",
|
|
51
54
|
alignItems: "center",
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
55
|
-
zIndex: isSelected ? "10" : "1"
|
|
55
|
+
transition: "transform 0.3s ease",
|
|
56
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)"
|
|
56
57
|
});
|
|
57
|
-
const
|
|
58
|
-
Object.assign(
|
|
58
|
+
const iconBox = document.createElement("div");
|
|
59
|
+
Object.assign(iconBox.style, {
|
|
59
60
|
width: "40px",
|
|
60
61
|
height: "40px",
|
|
61
62
|
borderRadius: "50%",
|
|
62
63
|
backgroundColor: "white",
|
|
63
64
|
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
64
|
-
boxShadow: "0 4px
|
|
65
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)",
|
|
65
66
|
display: "flex",
|
|
66
67
|
alignItems: "center",
|
|
67
68
|
justifyContent: "center",
|
|
@@ -70,31 +71,22 @@ function createCustomMarkerElement({
|
|
|
70
71
|
if (logoSrc) {
|
|
71
72
|
const img = document.createElement("img");
|
|
72
73
|
img.src = logoSrc;
|
|
73
|
-
img.style.width = "
|
|
74
|
-
img.style.height = "
|
|
75
|
-
img.style.objectFit = "
|
|
76
|
-
|
|
74
|
+
img.style.width = "100%";
|
|
75
|
+
img.style.height = "100%";
|
|
76
|
+
img.style.objectFit = "cover";
|
|
77
|
+
iconBox.appendChild(img);
|
|
77
78
|
} else {
|
|
78
|
-
|
|
79
|
+
iconBox.style.backgroundColor = "#ef4444";
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
if (showPrice && (marker.
|
|
81
|
+
body.appendChild(iconBox);
|
|
82
|
+
if (showPrice && (marker.price || marker.name)) {
|
|
82
83
|
const label = document.createElement("div");
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
borderRadius: "4px",
|
|
87
|
-
marginTop: "4px",
|
|
88
|
-
fontSize: "11px",
|
|
89
|
-
fontWeight: "bold",
|
|
90
|
-
whiteSpace: "nowrap",
|
|
91
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
|
|
92
|
-
border: "1px solid #ddd"
|
|
93
|
-
});
|
|
94
|
-
const labelText = marker.price ? `${marker.price} \u062A` : marker.name;
|
|
95
|
-
label.textContent = labelText || "";
|
|
84
|
+
label.className = "neshan-marker-label";
|
|
85
|
+
label.textContent = marker.price ? `${marker.price} \u062A` : marker.name ?? "";
|
|
86
|
+
body.appendChild(label);
|
|
96
87
|
}
|
|
97
|
-
|
|
88
|
+
container.appendChild(body);
|
|
89
|
+
return container;
|
|
98
90
|
}
|
|
99
91
|
|
|
100
92
|
// src/components/Map.tsx
|
|
@@ -103,19 +95,27 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
103
95
|
var Map = ({
|
|
104
96
|
options,
|
|
105
97
|
markers = [],
|
|
98
|
+
markerLogoUrl = "",
|
|
106
99
|
selectedMarkerId = null,
|
|
107
100
|
onMarkerClick,
|
|
101
|
+
onMapLoad,
|
|
108
102
|
className = "",
|
|
109
103
|
style = { width: "100%", height: "100%" }
|
|
110
104
|
}) => {
|
|
111
105
|
const mapContainerRef = (0, import_react.useRef)(null);
|
|
112
106
|
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
113
|
-
const markersRef = (0, import_react.useRef)([]);
|
|
114
107
|
const [mapLib, setMapLib] = (0, import_react.useState)(null);
|
|
108
|
+
const markersRef = (0, import_react.useRef)([]);
|
|
115
109
|
(0, import_react.useEffect)(() => {
|
|
110
|
+
let isMounted = true;
|
|
116
111
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
117
|
-
|
|
112
|
+
if (isMounted) {
|
|
113
|
+
setMapLib(mod.default || mod);
|
|
114
|
+
}
|
|
118
115
|
});
|
|
116
|
+
return () => {
|
|
117
|
+
isMounted = false;
|
|
118
|
+
};
|
|
119
119
|
}, []);
|
|
120
120
|
(0, import_react.useEffect)(() => {
|
|
121
121
|
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
@@ -125,8 +125,13 @@ var Map = ({
|
|
|
125
125
|
});
|
|
126
126
|
map.on("load", () => {
|
|
127
127
|
setMapInstance(map);
|
|
128
|
+
onMapLoad?.(map);
|
|
128
129
|
});
|
|
129
130
|
return () => {
|
|
131
|
+
if (map) {
|
|
132
|
+
map.remove();
|
|
133
|
+
setMapInstance(null);
|
|
134
|
+
}
|
|
130
135
|
};
|
|
131
136
|
}, [mapLib]);
|
|
132
137
|
(0, import_react.useEffect)(() => {
|
|
@@ -137,11 +142,13 @@ var Map = ({
|
|
|
137
142
|
const isSelected = markerData.id === selectedMarkerId;
|
|
138
143
|
const el = createCustomMarkerElement({
|
|
139
144
|
marker: markerData,
|
|
140
|
-
isSelected
|
|
145
|
+
isSelected,
|
|
146
|
+
logoSrc: markerLogoUrl
|
|
141
147
|
});
|
|
142
148
|
const marker = new mapLib.Marker({
|
|
143
149
|
element: el,
|
|
144
|
-
anchor: "bottom"
|
|
150
|
+
anchor: "bottom",
|
|
151
|
+
offset: [0, 0]
|
|
145
152
|
}).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
146
153
|
el.addEventListener("click", (e) => {
|
|
147
154
|
e.stopPropagation();
|
|
@@ -149,8 +156,28 @@ var Map = ({
|
|
|
149
156
|
});
|
|
150
157
|
markersRef.current.push(marker);
|
|
151
158
|
});
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
return () => {
|
|
160
|
+
markersRef.current.forEach((m) => m.remove());
|
|
161
|
+
};
|
|
162
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);
|
|
163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
style: {
|
|
167
|
+
position: "relative",
|
|
168
|
+
overflow: "hidden",
|
|
169
|
+
...style
|
|
170
|
+
},
|
|
171
|
+
className: `neshan-map-wrapper ${className}`,
|
|
172
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
ref: mapContainerRef,
|
|
176
|
+
style: { width: "100%", height: "100%" }
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
);
|
|
154
181
|
};
|
|
155
182
|
var Map_default = Map;
|
|
156
183
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\r\n\r\n\r\nexport { default as NeshanMap } from './components/Map';\r\n\r\n\r\nexport type {\r\n MapProps,\r\n MapOptions,\r\n MarkerData,\r\n MapboxMap,\r\n LngLatLike,\r\n} from './types';\r\n\r\n\r\n\r\n\r\n\r\n\r\nimport './styles.css';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\r\n\r\n\r\nexport { default as NeshanMap } from './components/Map';\r\n\r\n\r\nexport type {\r\n MapProps,\r\n MapOptions,\r\n MarkerData,\r\n MapboxMap,\r\n LngLatLike,\r\n} from './types';\r\n\r\n\r\n\r\n\r\n\r\n\r\nimport './styles.css';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\n\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n markerLogoUrl = '', \r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n onMapLoad,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const markersRef = useRef<any[]>([]);\r\n\r\n \r\n useEffect(() => {\r\n let isMounted = true;\r\n \r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (isMounted) {\r\n setMapLib(mod.default || mod);\r\n }\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstance) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n ...options,\r\n });\r\n\r\n map.on('load', () => {\r\n setMapInstance(map);\r\n onMapLoad?.(map);\r\n });\r\n\r\n \r\n return () => {\r\n if (map) {\r\n map.remove();\r\n setMapInstance(null);\r\n }\r\n };\r\n \r\n \r\n }, [mapLib]); \r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstance || !mapLib) return;\r\n\r\n \r\n markersRef.current.forEach((m) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const isSelected = markerData.id === selectedMarkerId;\r\n \r\n \r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: isSelected,\r\n logoSrc: markerLogoUrl, \r\n });\r\n\r\n \r\n const marker = new mapLib.Marker({ \r\n element: el,\r\n anchor: 'bottom', \r\n offset: [0, 0] \r\n })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\r\n\r\n \r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstance);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n\r\n \r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n style={{ \r\n position: 'relative', \r\n overflow: 'hidden',\r\n ...style \r\n }} \r\n className={`neshan-map-wrapper ${className}`}\r\n >\r\n <div \r\n ref={mapContainerRef} \r\n style={{ width: '100%', height: '100%' }} \r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;","import type { MarkerData } from '../types';\r\n\r\ninterface CreateMarkerOptions {\r\n marker: MarkerData;\r\n isSelected: boolean;\r\n logoSrc?: string;\r\n showPrice?: boolean;\r\n}\r\n\r\nexport function createCustomMarkerElement({\r\n marker,\r\n isSelected,\r\n logoSrc = '',\r\n showPrice = true,\r\n}: CreateMarkerOptions): HTMLElement {\r\n \r\n const container = document.createElement('div');\r\n container.className = 'neshan-marker-container';\r\n\r\n \r\n const body = document.createElement('div');\r\n body.className = `neshan-marker-body ${isSelected ? 'neshan-marker-selected' : ''}`;\r\n \r\n \r\n Object.assign(body.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n transition: 'transform 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n });\r\n\r\n \r\n const iconBox = document.createElement('div');\r\n Object.assign(iconBox.style, {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '50%',\r\n backgroundColor: 'white',\r\n border: isSelected ? '3px solid #3b82f6' : '2px solid #ef4444',\r\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden'\r\n });\r\n\r\n if (logoSrc) {\r\n const img = document.createElement('img');\r\n img.src = logoSrc;\r\n img.style.width = '100%';\r\n img.style.height = '100%';\r\n img.style.objectFit = 'cover';\r\n iconBox.appendChild(img);\r\n } else {\r\n iconBox.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n body.appendChild(iconBox);\r\n\r\n \r\n if (showPrice && (marker.price || marker.name)) {\r\n const label = document.createElement('div');\r\n label.className = 'neshan-marker-label';\r\n label.textContent = marker.price ? `${marker.price} ت` : (marker.name ?? '');\r\n body.appendChild(label);\r\n }\r\n\r\n container.appendChild(body);\r\n return container;\r\n}"],"mappings":"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","names":[]}
|
package/dist/index.css
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
/* src/styles.css */
|
|
2
|
-
.neshan-
|
|
3
|
-
|
|
2
|
+
.neshan-marker-container {
|
|
3
|
+
pointer-events: auto;
|
|
4
|
+
will-change: auto;
|
|
4
5
|
}
|
|
5
|
-
.neshan-marker {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
.neshan-marker-body {
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
transform-origin: bottom center;
|
|
8
9
|
}
|
|
9
|
-
.neshan-marker:hover {
|
|
10
|
+
.neshan-marker-body:hover {
|
|
10
11
|
transform: scale(1.2) !important;
|
|
12
|
+
z-index: 999;
|
|
11
13
|
}
|
|
12
14
|
.neshan-marker-label {
|
|
13
15
|
background: white;
|
|
14
16
|
color: #1f2937;
|
|
15
|
-
font-size:
|
|
17
|
+
font-size: 11px;
|
|
16
18
|
font-weight: bold;
|
|
17
|
-
padding:
|
|
18
|
-
border-radius:
|
|
19
|
+
padding: 3px 8px;
|
|
20
|
+
border-radius: 4px;
|
|
19
21
|
margin-top: 4px;
|
|
20
|
-
box-shadow: 0 2px
|
|
22
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
21
23
|
white-space: nowrap;
|
|
22
|
-
|
|
24
|
+
border: 1px solid #e5e7eb;
|
|
23
25
|
}
|
|
24
|
-
.neshan-marker-selected {
|
|
25
|
-
animation: pulse
|
|
26
|
+
.neshan-marker-selected .neshan-marker-body {
|
|
27
|
+
animation: marker-pulse 1.5s infinite ease-in-out;
|
|
26
28
|
}
|
|
27
|
-
@keyframes pulse {
|
|
29
|
+
@keyframes marker-pulse {
|
|
28
30
|
0% {
|
|
29
|
-
transform: scale(1);
|
|
31
|
+
transform: scale(1.2);
|
|
30
32
|
}
|
|
31
33
|
50% {
|
|
32
|
-
transform: scale(1.
|
|
34
|
+
transform: scale(1.3);
|
|
33
35
|
}
|
|
34
36
|
100% {
|
|
35
|
-
transform: scale(1);
|
|
37
|
+
transform: scale(1.2);
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
/*# sourceMappingURL=index.css.map */
|
package/dist/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles.css"],"sourcesContent":["\r\n
|
|
1
|
+
{"version":3,"sources":["../src/styles.css"],"sourcesContent":["\r\n.neshan-marker-container {\r\n pointer-events: auto;\r\n will-change: auto;\r\n}\r\n\r\n\r\n.neshan-marker-body {\r\n cursor: pointer;\r\n transform-origin: bottom center;\r\n}\r\n\r\n.neshan-marker-body:hover {\r\n transform: scale(1.2) !important;\r\n z-index: 999;\r\n}\r\n\r\n.neshan-marker-label {\r\n background: white;\r\n color: #1f2937;\r\n font-size: 11px;\r\n font-weight: bold;\r\n padding: 3px 8px;\r\n border-radius: 4px;\r\n margin-top: 4px;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\r\n white-space: nowrap;\r\n border: 1px solid #e5e7eb;\r\n}\r\n\r\n\r\n.neshan-marker-selected .neshan-marker-body {\r\n animation: marker-pulse 1.5s infinite ease-in-out;\r\n}\r\n\r\n@keyframes marker-pulse {\r\n 0% { transform: scale(1.2); }\r\n 50% { transform: scale(1.3); }\r\n 100% { transform: scale(1.2); }\r\n}"],"mappings":";AACA,CAAC;AACC,kBAAgB;AAChB,eAAa;AACf;AAGA,CAAC;AACC,UAAQ;AACR,oBAAkB,OAAO;AAC3B;AAEA,CALC,kBAKkB;AACjB,aAAW,MAAM;AACjB,WAAS;AACX;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACP,aAAW;AACX,eAAa;AACb,WAAS,IAAI;AACb,iBAAe;AACf,cAAY;AACZ,cAAY,EAAE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACpC,eAAa;AACb,UAAQ,IAAI,MAAM;AACpB;AAGA,CAAC,uBAAuB,CAxBvB;AAyBC,aAAW,aAAa,KAAK,SAAS;AACxC;AAEA,WAHa;AAIX;AAAK,eAAW,MAAM;AAAM;AAC5B;AAAM,eAAW,MAAM;AAAM;AAC7B;AAAO,eAAW,MAAM;AAAM;AAChC;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -8,24 +8,25 @@ function createCustomMarkerElement({
|
|
|
8
8
|
logoSrc = "",
|
|
9
9
|
showPrice = true
|
|
10
10
|
}) {
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const container = document.createElement("div");
|
|
12
|
+
container.className = "neshan-marker-container";
|
|
13
|
+
const body = document.createElement("div");
|
|
14
|
+
body.className = `neshan-marker-body ${isSelected ? "neshan-marker-selected" : ""}`;
|
|
15
|
+
Object.assign(body.style, {
|
|
13
16
|
display: "flex",
|
|
14
17
|
flexDirection: "column",
|
|
15
18
|
alignItems: "center",
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
19
|
-
zIndex: isSelected ? "10" : "1"
|
|
19
|
+
transition: "transform 0.3s ease",
|
|
20
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)"
|
|
20
21
|
});
|
|
21
|
-
const
|
|
22
|
-
Object.assign(
|
|
22
|
+
const iconBox = document.createElement("div");
|
|
23
|
+
Object.assign(iconBox.style, {
|
|
23
24
|
width: "40px",
|
|
24
25
|
height: "40px",
|
|
25
26
|
borderRadius: "50%",
|
|
26
27
|
backgroundColor: "white",
|
|
27
28
|
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
28
|
-
boxShadow: "0 4px
|
|
29
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)",
|
|
29
30
|
display: "flex",
|
|
30
31
|
alignItems: "center",
|
|
31
32
|
justifyContent: "center",
|
|
@@ -34,31 +35,22 @@ function createCustomMarkerElement({
|
|
|
34
35
|
if (logoSrc) {
|
|
35
36
|
const img = document.createElement("img");
|
|
36
37
|
img.src = logoSrc;
|
|
37
|
-
img.style.width = "
|
|
38
|
-
img.style.height = "
|
|
39
|
-
img.style.objectFit = "
|
|
40
|
-
|
|
38
|
+
img.style.width = "100%";
|
|
39
|
+
img.style.height = "100%";
|
|
40
|
+
img.style.objectFit = "cover";
|
|
41
|
+
iconBox.appendChild(img);
|
|
41
42
|
} else {
|
|
42
|
-
|
|
43
|
+
iconBox.style.backgroundColor = "#ef4444";
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
-
if (showPrice && (marker.
|
|
45
|
+
body.appendChild(iconBox);
|
|
46
|
+
if (showPrice && (marker.price || marker.name)) {
|
|
46
47
|
const label = document.createElement("div");
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
borderRadius: "4px",
|
|
51
|
-
marginTop: "4px",
|
|
52
|
-
fontSize: "11px",
|
|
53
|
-
fontWeight: "bold",
|
|
54
|
-
whiteSpace: "nowrap",
|
|
55
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
|
|
56
|
-
border: "1px solid #ddd"
|
|
57
|
-
});
|
|
58
|
-
const labelText = marker.price ? `${marker.price} \u062A` : marker.name;
|
|
59
|
-
label.textContent = labelText || "";
|
|
48
|
+
label.className = "neshan-marker-label";
|
|
49
|
+
label.textContent = marker.price ? `${marker.price} \u062A` : marker.name ?? "";
|
|
50
|
+
body.appendChild(label);
|
|
60
51
|
}
|
|
61
|
-
|
|
52
|
+
container.appendChild(body);
|
|
53
|
+
return container;
|
|
62
54
|
}
|
|
63
55
|
|
|
64
56
|
// src/components/Map.tsx
|
|
@@ -67,19 +59,27 @@ import { jsx } from "react/jsx-runtime";
|
|
|
67
59
|
var Map = ({
|
|
68
60
|
options,
|
|
69
61
|
markers = [],
|
|
62
|
+
markerLogoUrl = "",
|
|
70
63
|
selectedMarkerId = null,
|
|
71
64
|
onMarkerClick,
|
|
65
|
+
onMapLoad,
|
|
72
66
|
className = "",
|
|
73
67
|
style = { width: "100%", height: "100%" }
|
|
74
68
|
}) => {
|
|
75
69
|
const mapContainerRef = useRef(null);
|
|
76
70
|
const [mapInstance, setMapInstance] = useState(null);
|
|
77
|
-
const markersRef = useRef([]);
|
|
78
71
|
const [mapLib, setMapLib] = useState(null);
|
|
72
|
+
const markersRef = useRef([]);
|
|
79
73
|
useEffect(() => {
|
|
74
|
+
let isMounted = true;
|
|
80
75
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
81
|
-
|
|
76
|
+
if (isMounted) {
|
|
77
|
+
setMapLib(mod.default || mod);
|
|
78
|
+
}
|
|
82
79
|
});
|
|
80
|
+
return () => {
|
|
81
|
+
isMounted = false;
|
|
82
|
+
};
|
|
83
83
|
}, []);
|
|
84
84
|
useEffect(() => {
|
|
85
85
|
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
@@ -89,8 +89,13 @@ var Map = ({
|
|
|
89
89
|
});
|
|
90
90
|
map.on("load", () => {
|
|
91
91
|
setMapInstance(map);
|
|
92
|
+
onMapLoad?.(map);
|
|
92
93
|
});
|
|
93
94
|
return () => {
|
|
95
|
+
if (map) {
|
|
96
|
+
map.remove();
|
|
97
|
+
setMapInstance(null);
|
|
98
|
+
}
|
|
94
99
|
};
|
|
95
100
|
}, [mapLib]);
|
|
96
101
|
useEffect(() => {
|
|
@@ -101,11 +106,13 @@ var Map = ({
|
|
|
101
106
|
const isSelected = markerData.id === selectedMarkerId;
|
|
102
107
|
const el = createCustomMarkerElement({
|
|
103
108
|
marker: markerData,
|
|
104
|
-
isSelected
|
|
109
|
+
isSelected,
|
|
110
|
+
logoSrc: markerLogoUrl
|
|
105
111
|
});
|
|
106
112
|
const marker = new mapLib.Marker({
|
|
107
113
|
element: el,
|
|
108
|
-
anchor: "bottom"
|
|
114
|
+
anchor: "bottom",
|
|
115
|
+
offset: [0, 0]
|
|
109
116
|
}).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
110
117
|
el.addEventListener("click", (e) => {
|
|
111
118
|
e.stopPropagation();
|
|
@@ -113,8 +120,28 @@ var Map = ({
|
|
|
113
120
|
});
|
|
114
121
|
markersRef.current.push(marker);
|
|
115
122
|
});
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
return () => {
|
|
124
|
+
markersRef.current.forEach((m) => m.remove());
|
|
125
|
+
};
|
|
126
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);
|
|
127
|
+
return /* @__PURE__ */ jsx(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
style: {
|
|
131
|
+
position: "relative",
|
|
132
|
+
overflow: "hidden",
|
|
133
|
+
...style
|
|
134
|
+
},
|
|
135
|
+
className: `neshan-map-wrapper ${className}`,
|
|
136
|
+
children: /* @__PURE__ */ jsx(
|
|
137
|
+
"div",
|
|
138
|
+
{
|
|
139
|
+
ref: mapContainerRef,
|
|
140
|
+
style: { width: "100%", height: "100%" }
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
);
|
|
118
145
|
};
|
|
119
146
|
var Map_default = Map;
|
|
120
147
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const
|
|
1
|
+
{"version":3,"sources":["../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\n\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n markerLogoUrl = '', \r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n onMapLoad,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const markersRef = useRef<any[]>([]);\r\n\r\n \r\n useEffect(() => {\r\n let isMounted = true;\r\n \r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (isMounted) {\r\n setMapLib(mod.default || mod);\r\n }\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstance) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n ...options,\r\n });\r\n\r\n map.on('load', () => {\r\n setMapInstance(map);\r\n onMapLoad?.(map);\r\n });\r\n\r\n \r\n return () => {\r\n if (map) {\r\n map.remove();\r\n setMapInstance(null);\r\n }\r\n };\r\n \r\n \r\n }, [mapLib]); \r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstance || !mapLib) return;\r\n\r\n \r\n markersRef.current.forEach((m) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const isSelected = markerData.id === selectedMarkerId;\r\n \r\n \r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: isSelected,\r\n logoSrc: markerLogoUrl, \r\n });\r\n\r\n \r\n const marker = new mapLib.Marker({ \r\n element: el,\r\n anchor: 'bottom', \r\n offset: [0, 0] \r\n })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\r\n\r\n \r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstance);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n\r\n \r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n style={{ \r\n position: 'relative', \r\n overflow: 'hidden',\r\n ...style \r\n }} \r\n className={`neshan-map-wrapper ${className}`}\r\n >\r\n <div \r\n ref={mapContainerRef} \r\n style={{ width: '100%', height: '100%' }} \r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;","import type { MarkerData } from '../types';\r\n\r\ninterface CreateMarkerOptions {\r\n marker: MarkerData;\r\n isSelected: boolean;\r\n logoSrc?: string;\r\n showPrice?: boolean;\r\n}\r\n\r\nexport function createCustomMarkerElement({\r\n marker,\r\n isSelected,\r\n logoSrc = '',\r\n showPrice = true,\r\n}: CreateMarkerOptions): HTMLElement {\r\n \r\n const container = document.createElement('div');\r\n container.className = 'neshan-marker-container';\r\n\r\n \r\n const body = document.createElement('div');\r\n body.className = `neshan-marker-body ${isSelected ? 'neshan-marker-selected' : ''}`;\r\n \r\n \r\n Object.assign(body.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n transition: 'transform 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n });\r\n\r\n \r\n const iconBox = document.createElement('div');\r\n Object.assign(iconBox.style, {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '50%',\r\n backgroundColor: 'white',\r\n border: isSelected ? '3px solid #3b82f6' : '2px solid #ef4444',\r\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden'\r\n });\r\n\r\n if (logoSrc) {\r\n const img = document.createElement('img');\r\n img.src = logoSrc;\r\n img.style.width = '100%';\r\n img.style.height = '100%';\r\n img.style.objectFit = 'cover';\r\n iconBox.appendChild(img);\r\n } else {\r\n iconBox.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n body.appendChild(iconBox);\r\n\r\n \r\n if (showPrice && (marker.price || marker.name)) {\r\n const label = document.createElement('div');\r\n label.className = 'neshan-marker-label';\r\n label.textContent = marker.price ? `${marker.price} ت` : (marker.name ?? '');\r\n body.appendChild(label);\r\n }\r\n\r\n container.appendChild(body);\r\n return container;\r\n}"],"mappings":"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","names":[]}
|
package/dist/react.cjs
CHANGED
|
@@ -45,24 +45,25 @@ function createCustomMarkerElement({
|
|
|
45
45
|
logoSrc = "",
|
|
46
46
|
showPrice = true
|
|
47
47
|
}) {
|
|
48
|
-
const
|
|
49
|
-
|
|
48
|
+
const container = document.createElement("div");
|
|
49
|
+
container.className = "neshan-marker-container";
|
|
50
|
+
const body = document.createElement("div");
|
|
51
|
+
body.className = `neshan-marker-body ${isSelected ? "neshan-marker-selected" : ""}`;
|
|
52
|
+
Object.assign(body.style, {
|
|
50
53
|
display: "flex",
|
|
51
54
|
flexDirection: "column",
|
|
52
55
|
alignItems: "center",
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
56
|
-
zIndex: isSelected ? "10" : "1"
|
|
56
|
+
transition: "transform 0.3s ease",
|
|
57
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)"
|
|
57
58
|
});
|
|
58
|
-
const
|
|
59
|
-
Object.assign(
|
|
59
|
+
const iconBox = document.createElement("div");
|
|
60
|
+
Object.assign(iconBox.style, {
|
|
60
61
|
width: "40px",
|
|
61
62
|
height: "40px",
|
|
62
63
|
borderRadius: "50%",
|
|
63
64
|
backgroundColor: "white",
|
|
64
65
|
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
65
|
-
boxShadow: "0 4px
|
|
66
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)",
|
|
66
67
|
display: "flex",
|
|
67
68
|
alignItems: "center",
|
|
68
69
|
justifyContent: "center",
|
|
@@ -71,31 +72,22 @@ function createCustomMarkerElement({
|
|
|
71
72
|
if (logoSrc) {
|
|
72
73
|
const img = document.createElement("img");
|
|
73
74
|
img.src = logoSrc;
|
|
74
|
-
img.style.width = "
|
|
75
|
-
img.style.height = "
|
|
76
|
-
img.style.objectFit = "
|
|
77
|
-
|
|
75
|
+
img.style.width = "100%";
|
|
76
|
+
img.style.height = "100%";
|
|
77
|
+
img.style.objectFit = "cover";
|
|
78
|
+
iconBox.appendChild(img);
|
|
78
79
|
} else {
|
|
79
|
-
|
|
80
|
+
iconBox.style.backgroundColor = "#ef4444";
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
-
if (showPrice && (marker.
|
|
82
|
+
body.appendChild(iconBox);
|
|
83
|
+
if (showPrice && (marker.price || marker.name)) {
|
|
83
84
|
const label = document.createElement("div");
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
borderRadius: "4px",
|
|
88
|
-
marginTop: "4px",
|
|
89
|
-
fontSize: "11px",
|
|
90
|
-
fontWeight: "bold",
|
|
91
|
-
whiteSpace: "nowrap",
|
|
92
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
|
|
93
|
-
border: "1px solid #ddd"
|
|
94
|
-
});
|
|
95
|
-
const labelText = marker.price ? `${marker.price} \u062A` : marker.name;
|
|
96
|
-
label.textContent = labelText || "";
|
|
85
|
+
label.className = "neshan-marker-label";
|
|
86
|
+
label.textContent = marker.price ? `${marker.price} \u062A` : marker.name ?? "";
|
|
87
|
+
body.appendChild(label);
|
|
97
88
|
}
|
|
98
|
-
|
|
89
|
+
container.appendChild(body);
|
|
90
|
+
return container;
|
|
99
91
|
}
|
|
100
92
|
|
|
101
93
|
// src/components/Map.tsx
|
|
@@ -104,19 +96,27 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
104
96
|
var Map = ({
|
|
105
97
|
options,
|
|
106
98
|
markers = [],
|
|
99
|
+
markerLogoUrl = "",
|
|
107
100
|
selectedMarkerId = null,
|
|
108
101
|
onMarkerClick,
|
|
102
|
+
onMapLoad,
|
|
109
103
|
className = "",
|
|
110
104
|
style = { width: "100%", height: "100%" }
|
|
111
105
|
}) => {
|
|
112
106
|
const mapContainerRef = (0, import_react.useRef)(null);
|
|
113
107
|
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
114
|
-
const markersRef = (0, import_react.useRef)([]);
|
|
115
108
|
const [mapLib, setMapLib] = (0, import_react.useState)(null);
|
|
109
|
+
const markersRef = (0, import_react.useRef)([]);
|
|
116
110
|
(0, import_react.useEffect)(() => {
|
|
111
|
+
let isMounted = true;
|
|
117
112
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
118
|
-
|
|
113
|
+
if (isMounted) {
|
|
114
|
+
setMapLib(mod.default || mod);
|
|
115
|
+
}
|
|
119
116
|
});
|
|
117
|
+
return () => {
|
|
118
|
+
isMounted = false;
|
|
119
|
+
};
|
|
120
120
|
}, []);
|
|
121
121
|
(0, import_react.useEffect)(() => {
|
|
122
122
|
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
@@ -126,8 +126,13 @@ var Map = ({
|
|
|
126
126
|
});
|
|
127
127
|
map.on("load", () => {
|
|
128
128
|
setMapInstance(map);
|
|
129
|
+
onMapLoad?.(map);
|
|
129
130
|
});
|
|
130
131
|
return () => {
|
|
132
|
+
if (map) {
|
|
133
|
+
map.remove();
|
|
134
|
+
setMapInstance(null);
|
|
135
|
+
}
|
|
131
136
|
};
|
|
132
137
|
}, [mapLib]);
|
|
133
138
|
(0, import_react.useEffect)(() => {
|
|
@@ -138,11 +143,13 @@ var Map = ({
|
|
|
138
143
|
const isSelected = markerData.id === selectedMarkerId;
|
|
139
144
|
const el = createCustomMarkerElement({
|
|
140
145
|
marker: markerData,
|
|
141
|
-
isSelected
|
|
146
|
+
isSelected,
|
|
147
|
+
logoSrc: markerLogoUrl
|
|
142
148
|
});
|
|
143
149
|
const marker = new mapLib.Marker({
|
|
144
150
|
element: el,
|
|
145
|
-
anchor: "bottom"
|
|
151
|
+
anchor: "bottom",
|
|
152
|
+
offset: [0, 0]
|
|
146
153
|
}).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
147
154
|
el.addEventListener("click", (e) => {
|
|
148
155
|
e.stopPropagation();
|
|
@@ -150,8 +157,28 @@ var Map = ({
|
|
|
150
157
|
});
|
|
151
158
|
markersRef.current.push(marker);
|
|
152
159
|
});
|
|
153
|
-
|
|
154
|
-
|
|
160
|
+
return () => {
|
|
161
|
+
markersRef.current.forEach((m) => m.remove());
|
|
162
|
+
};
|
|
163
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);
|
|
164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
165
|
+
"div",
|
|
166
|
+
{
|
|
167
|
+
style: {
|
|
168
|
+
position: "relative",
|
|
169
|
+
overflow: "hidden",
|
|
170
|
+
...style
|
|
171
|
+
},
|
|
172
|
+
className: `neshan-map-wrapper ${className}`,
|
|
173
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
ref: mapContainerRef,
|
|
177
|
+
style: { width: "100%", height: "100%" }
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
);
|
|
155
182
|
};
|
|
156
183
|
var Map_default = Map;
|
|
157
184
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts","../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["// src/react.ts\r\n\r\n\"use client\";\r\n\r\nexport { default as NeshanMap } from './components/Map';\r\nexport type {\r\n MapProps,\r\n MapOptions,\r\n MarkerData,\r\n} from './types';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const
|
|
1
|
+
{"version":3,"sources":["../src/react.ts","../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["// src/react.ts\r\n\r\n\"use client\";\r\n\r\nexport { default as NeshanMap } from './components/Map';\r\nexport type {\r\n MapProps,\r\n MapOptions,\r\n MarkerData,\r\n} from './types';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\n\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n markerLogoUrl = '', \r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n onMapLoad,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const markersRef = useRef<any[]>([]);\r\n\r\n \r\n useEffect(() => {\r\n let isMounted = true;\r\n \r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (isMounted) {\r\n setMapLib(mod.default || mod);\r\n }\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstance) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n ...options,\r\n });\r\n\r\n map.on('load', () => {\r\n setMapInstance(map);\r\n onMapLoad?.(map);\r\n });\r\n\r\n \r\n return () => {\r\n if (map) {\r\n map.remove();\r\n setMapInstance(null);\r\n }\r\n };\r\n \r\n \r\n }, [mapLib]); \r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstance || !mapLib) return;\r\n\r\n \r\n markersRef.current.forEach((m) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const isSelected = markerData.id === selectedMarkerId;\r\n \r\n \r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: isSelected,\r\n logoSrc: markerLogoUrl, \r\n });\r\n\r\n \r\n const marker = new mapLib.Marker({ \r\n element: el,\r\n anchor: 'bottom', \r\n offset: [0, 0] \r\n })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\r\n\r\n \r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstance);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n\r\n \r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n style={{ \r\n position: 'relative', \r\n overflow: 'hidden',\r\n ...style \r\n }} \r\n className={`neshan-map-wrapper ${className}`}\r\n >\r\n <div \r\n ref={mapContainerRef} \r\n style={{ width: '100%', height: '100%' }} \r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;","import type { MarkerData } from '../types';\r\n\r\ninterface CreateMarkerOptions {\r\n marker: MarkerData;\r\n isSelected: boolean;\r\n logoSrc?: string;\r\n showPrice?: boolean;\r\n}\r\n\r\nexport function createCustomMarkerElement({\r\n marker,\r\n isSelected,\r\n logoSrc = '',\r\n showPrice = true,\r\n}: CreateMarkerOptions): HTMLElement {\r\n \r\n const container = document.createElement('div');\r\n container.className = 'neshan-marker-container';\r\n\r\n \r\n const body = document.createElement('div');\r\n body.className = `neshan-marker-body ${isSelected ? 'neshan-marker-selected' : ''}`;\r\n \r\n \r\n Object.assign(body.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n transition: 'transform 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n });\r\n\r\n \r\n const iconBox = document.createElement('div');\r\n Object.assign(iconBox.style, {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '50%',\r\n backgroundColor: 'white',\r\n border: isSelected ? '3px solid #3b82f6' : '2px solid #ef4444',\r\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden'\r\n });\r\n\r\n if (logoSrc) {\r\n const img = document.createElement('img');\r\n img.src = logoSrc;\r\n img.style.width = '100%';\r\n img.style.height = '100%';\r\n img.style.objectFit = 'cover';\r\n iconBox.appendChild(img);\r\n } else {\r\n iconBox.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n body.appendChild(iconBox);\r\n\r\n \r\n if (showPrice && (marker.price || marker.name)) {\r\n const label = document.createElement('div');\r\n label.className = 'neshan-marker-label';\r\n label.textContent = marker.price ? `${marker.price} ت` : (marker.name ?? '');\r\n body.appendChild(label);\r\n }\r\n\r\n container.appendChild(body);\r\n return container;\r\n}"],"mappings":"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","names":[]}
|
package/dist/react.js
CHANGED
|
@@ -10,24 +10,25 @@ function createCustomMarkerElement({
|
|
|
10
10
|
logoSrc = "",
|
|
11
11
|
showPrice = true
|
|
12
12
|
}) {
|
|
13
|
-
const
|
|
14
|
-
|
|
13
|
+
const container = document.createElement("div");
|
|
14
|
+
container.className = "neshan-marker-container";
|
|
15
|
+
const body = document.createElement("div");
|
|
16
|
+
body.className = `neshan-marker-body ${isSelected ? "neshan-marker-selected" : ""}`;
|
|
17
|
+
Object.assign(body.style, {
|
|
15
18
|
display: "flex",
|
|
16
19
|
flexDirection: "column",
|
|
17
20
|
alignItems: "center",
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
21
|
-
zIndex: isSelected ? "10" : "1"
|
|
21
|
+
transition: "transform 0.3s ease",
|
|
22
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)"
|
|
22
23
|
});
|
|
23
|
-
const
|
|
24
|
-
Object.assign(
|
|
24
|
+
const iconBox = document.createElement("div");
|
|
25
|
+
Object.assign(iconBox.style, {
|
|
25
26
|
width: "40px",
|
|
26
27
|
height: "40px",
|
|
27
28
|
borderRadius: "50%",
|
|
28
29
|
backgroundColor: "white",
|
|
29
30
|
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
30
|
-
boxShadow: "0 4px
|
|
31
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)",
|
|
31
32
|
display: "flex",
|
|
32
33
|
alignItems: "center",
|
|
33
34
|
justifyContent: "center",
|
|
@@ -36,31 +37,22 @@ function createCustomMarkerElement({
|
|
|
36
37
|
if (logoSrc) {
|
|
37
38
|
const img = document.createElement("img");
|
|
38
39
|
img.src = logoSrc;
|
|
39
|
-
img.style.width = "
|
|
40
|
-
img.style.height = "
|
|
41
|
-
img.style.objectFit = "
|
|
42
|
-
|
|
40
|
+
img.style.width = "100%";
|
|
41
|
+
img.style.height = "100%";
|
|
42
|
+
img.style.objectFit = "cover";
|
|
43
|
+
iconBox.appendChild(img);
|
|
43
44
|
} else {
|
|
44
|
-
|
|
45
|
+
iconBox.style.backgroundColor = "#ef4444";
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
if (showPrice && (marker.
|
|
47
|
+
body.appendChild(iconBox);
|
|
48
|
+
if (showPrice && (marker.price || marker.name)) {
|
|
48
49
|
const label = document.createElement("div");
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
borderRadius: "4px",
|
|
53
|
-
marginTop: "4px",
|
|
54
|
-
fontSize: "11px",
|
|
55
|
-
fontWeight: "bold",
|
|
56
|
-
whiteSpace: "nowrap",
|
|
57
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
|
|
58
|
-
border: "1px solid #ddd"
|
|
59
|
-
});
|
|
60
|
-
const labelText = marker.price ? `${marker.price} \u062A` : marker.name;
|
|
61
|
-
label.textContent = labelText || "";
|
|
50
|
+
label.className = "neshan-marker-label";
|
|
51
|
+
label.textContent = marker.price ? `${marker.price} \u062A` : marker.name ?? "";
|
|
52
|
+
body.appendChild(label);
|
|
62
53
|
}
|
|
63
|
-
|
|
54
|
+
container.appendChild(body);
|
|
55
|
+
return container;
|
|
64
56
|
}
|
|
65
57
|
|
|
66
58
|
// src/components/Map.tsx
|
|
@@ -69,19 +61,27 @@ import { jsx } from "react/jsx-runtime";
|
|
|
69
61
|
var Map = ({
|
|
70
62
|
options,
|
|
71
63
|
markers = [],
|
|
64
|
+
markerLogoUrl = "",
|
|
72
65
|
selectedMarkerId = null,
|
|
73
66
|
onMarkerClick,
|
|
67
|
+
onMapLoad,
|
|
74
68
|
className = "",
|
|
75
69
|
style = { width: "100%", height: "100%" }
|
|
76
70
|
}) => {
|
|
77
71
|
const mapContainerRef = useRef(null);
|
|
78
72
|
const [mapInstance, setMapInstance] = useState(null);
|
|
79
|
-
const markersRef = useRef([]);
|
|
80
73
|
const [mapLib, setMapLib] = useState(null);
|
|
74
|
+
const markersRef = useRef([]);
|
|
81
75
|
useEffect(() => {
|
|
76
|
+
let isMounted = true;
|
|
82
77
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
83
|
-
|
|
78
|
+
if (isMounted) {
|
|
79
|
+
setMapLib(mod.default || mod);
|
|
80
|
+
}
|
|
84
81
|
});
|
|
82
|
+
return () => {
|
|
83
|
+
isMounted = false;
|
|
84
|
+
};
|
|
85
85
|
}, []);
|
|
86
86
|
useEffect(() => {
|
|
87
87
|
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
@@ -91,8 +91,13 @@ var Map = ({
|
|
|
91
91
|
});
|
|
92
92
|
map.on("load", () => {
|
|
93
93
|
setMapInstance(map);
|
|
94
|
+
onMapLoad?.(map);
|
|
94
95
|
});
|
|
95
96
|
return () => {
|
|
97
|
+
if (map) {
|
|
98
|
+
map.remove();
|
|
99
|
+
setMapInstance(null);
|
|
100
|
+
}
|
|
96
101
|
};
|
|
97
102
|
}, [mapLib]);
|
|
98
103
|
useEffect(() => {
|
|
@@ -103,11 +108,13 @@ var Map = ({
|
|
|
103
108
|
const isSelected = markerData.id === selectedMarkerId;
|
|
104
109
|
const el = createCustomMarkerElement({
|
|
105
110
|
marker: markerData,
|
|
106
|
-
isSelected
|
|
111
|
+
isSelected,
|
|
112
|
+
logoSrc: markerLogoUrl
|
|
107
113
|
});
|
|
108
114
|
const marker = new mapLib.Marker({
|
|
109
115
|
element: el,
|
|
110
|
-
anchor: "bottom"
|
|
116
|
+
anchor: "bottom",
|
|
117
|
+
offset: [0, 0]
|
|
111
118
|
}).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
112
119
|
el.addEventListener("click", (e) => {
|
|
113
120
|
e.stopPropagation();
|
|
@@ -115,8 +122,28 @@ var Map = ({
|
|
|
115
122
|
});
|
|
116
123
|
markersRef.current.push(marker);
|
|
117
124
|
});
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
return () => {
|
|
126
|
+
markersRef.current.forEach((m) => m.remove());
|
|
127
|
+
};
|
|
128
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);
|
|
129
|
+
return /* @__PURE__ */ jsx(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: {
|
|
133
|
+
position: "relative",
|
|
134
|
+
overflow: "hidden",
|
|
135
|
+
...style
|
|
136
|
+
},
|
|
137
|
+
className: `neshan-map-wrapper ${className}`,
|
|
138
|
+
children: /* @__PURE__ */ jsx(
|
|
139
|
+
"div",
|
|
140
|
+
{
|
|
141
|
+
ref: mapContainerRef,
|
|
142
|
+
style: { width: "100%", height: "100%" }
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
);
|
|
120
147
|
};
|
|
121
148
|
var Map_default = Map;
|
|
122
149
|
export {
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const
|
|
1
|
+
{"version":3,"sources":["../src/components/Map.tsx","../src/utils/createCustomMarkerElement.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport type { MapboxMap, MarkerData, MapProps } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\n\r\nimport '@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\r\n markerLogoUrl = '', \r\n selectedMarkerId = null,\r\n onMarkerClick,\r\n onMapLoad,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const markersRef = useRef<any[]>([]);\r\n\r\n \r\n useEffect(() => {\r\n let isMounted = true;\r\n \r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (isMounted) {\r\n setMapLib(mod.default || mod);\r\n }\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstance) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n ...options,\r\n });\r\n\r\n map.on('load', () => {\r\n setMapInstance(map);\r\n onMapLoad?.(map);\r\n });\r\n\r\n \r\n return () => {\r\n if (map) {\r\n map.remove();\r\n setMapInstance(null);\r\n }\r\n };\r\n \r\n \r\n }, [mapLib]); \r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstance || !mapLib) return;\r\n\r\n \r\n markersRef.current.forEach((m) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const isSelected = markerData.id === selectedMarkerId;\r\n \r\n \r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: isSelected,\r\n logoSrc: markerLogoUrl, \r\n });\r\n\r\n \r\n const marker = new mapLib.Marker({ \r\n element: el,\r\n anchor: 'bottom', \r\n offset: [0, 0] \r\n })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\r\n\r\n \r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstance);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n\r\n \r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, markerLogoUrl, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n style={{ \r\n position: 'relative', \r\n overflow: 'hidden',\r\n ...style \r\n }} \r\n className={`neshan-map-wrapper ${className}`}\r\n >\r\n <div \r\n ref={mapContainerRef} \r\n style={{ width: '100%', height: '100%' }} \r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;","import type { MarkerData } from '../types';\r\n\r\ninterface CreateMarkerOptions {\r\n marker: MarkerData;\r\n isSelected: boolean;\r\n logoSrc?: string;\r\n showPrice?: boolean;\r\n}\r\n\r\nexport function createCustomMarkerElement({\r\n marker,\r\n isSelected,\r\n logoSrc = '',\r\n showPrice = true,\r\n}: CreateMarkerOptions): HTMLElement {\r\n \r\n const container = document.createElement('div');\r\n container.className = 'neshan-marker-container';\r\n\r\n \r\n const body = document.createElement('div');\r\n body.className = `neshan-marker-body ${isSelected ? 'neshan-marker-selected' : ''}`;\r\n \r\n \r\n Object.assign(body.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n transition: 'transform 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n });\r\n\r\n \r\n const iconBox = document.createElement('div');\r\n Object.assign(iconBox.style, {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '50%',\r\n backgroundColor: 'white',\r\n border: isSelected ? '3px solid #3b82f6' : '2px solid #ef4444',\r\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n overflow: 'hidden'\r\n });\r\n\r\n if (logoSrc) {\r\n const img = document.createElement('img');\r\n img.src = logoSrc;\r\n img.style.width = '100%';\r\n img.style.height = '100%';\r\n img.style.objectFit = 'cover';\r\n iconBox.appendChild(img);\r\n } else {\r\n iconBox.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n body.appendChild(iconBox);\r\n\r\n \r\n if (showPrice && (marker.price || marker.name)) {\r\n const label = document.createElement('div');\r\n label.className = 'neshan-marker-label';\r\n label.textContent = marker.price ? `${marker.price} ت` : (marker.name ?? '');\r\n body.appendChild(label);\r\n }\r\n\r\n container.appendChild(body);\r\n return container;\r\n}"],"mappings":"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","names":[]}
|
package/dist/styles.css
CHANGED
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
box-sizing: border-box;
|
|
2
|
+
.neshan-marker-container {
|
|
3
|
+
pointer-events: auto;
|
|
4
|
+
will-change: auto;
|
|
6
5
|
}
|
|
7
6
|
|
|
8
7
|
|
|
9
|
-
.neshan-marker {
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
.neshan-marker-body {
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
transform-origin: bottom center;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
.neshan-marker:hover {
|
|
13
|
+
.neshan-marker-body:hover {
|
|
15
14
|
transform: scale(1.2) !important;
|
|
15
|
+
z-index: 999;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
.neshan-marker-label {
|
|
20
19
|
background: white;
|
|
21
20
|
color: #1f2937;
|
|
22
|
-
font-size:
|
|
21
|
+
font-size: 11px;
|
|
23
22
|
font-weight: bold;
|
|
24
|
-
padding:
|
|
25
|
-
border-radius:
|
|
23
|
+
padding: 3px 8px;
|
|
24
|
+
border-radius: 4px;
|
|
26
25
|
margin-top: 4px;
|
|
27
|
-
box-shadow: 0 2px
|
|
26
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
28
27
|
white-space: nowrap;
|
|
29
|
-
|
|
28
|
+
border: 1px solid #e5e7eb;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
.neshan-marker-selected {
|
|
34
|
-
animation: pulse
|
|
32
|
+
.neshan-marker-selected .neshan-marker-body {
|
|
33
|
+
animation: marker-pulse 1.5s infinite ease-in-out;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
@keyframes pulse {
|
|
38
|
-
0% {
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
50% {
|
|
42
|
-
transform: scale(1.15);
|
|
43
|
-
}
|
|
44
|
-
100% {
|
|
45
|
-
transform: scale(1);
|
|
46
|
-
}
|
|
36
|
+
@keyframes marker-pulse {
|
|
37
|
+
0% { transform: scale(1.2); }
|
|
38
|
+
50% { transform: scale(1.3); }
|
|
39
|
+
100% { transform: scale(1.2); }
|
|
47
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCustomMarkerElement.d.ts","sourceRoot":"","sources":["../../src/utils/createCustomMarkerElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,UAAU,EACV,OAAY,EACZ,SAAgB,GACjB,EAAE,mBAAmB,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"createCustomMarkerElement.d.ts","sourceRoot":"","sources":["../../src/utils/createCustomMarkerElement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,UAAU,EACV,OAAY,EACZ,SAAgB,GACjB,EAAE,mBAAmB,GAAG,WAAW,CAwDnC"}
|