mehdi-akbari-map 0.0.3 → 0.0.5
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 +98 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +98 -61
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +98 -61
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +98 -61
- package/dist/react.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/createCustomMarkerElement.d.ts +10 -0
- package/dist/utils/createCustomMarkerElement.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["../../src/components/Map.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["../../src/components/Map.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAyB,MAAM,UAAU,CAAC;AAG3D,QAAA,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAsF3B,CAAC;AAEF,eAAe,GAAG,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,68 @@ module.exports = __toCommonJS(src_exports);
|
|
|
36
36
|
|
|
37
37
|
// src/components/Map.tsx
|
|
38
38
|
var import_react = require("react");
|
|
39
|
+
|
|
40
|
+
// src/utils/createCustomMarkerElement.ts
|
|
41
|
+
function createCustomMarkerElement({
|
|
42
|
+
marker,
|
|
43
|
+
isSelected,
|
|
44
|
+
logoSrc = "",
|
|
45
|
+
showPrice = true
|
|
46
|
+
}) {
|
|
47
|
+
const wrapper = document.createElement("div");
|
|
48
|
+
Object.assign(wrapper.style, {
|
|
49
|
+
display: "flex",
|
|
50
|
+
flexDirection: "column",
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
cursor: "pointer",
|
|
53
|
+
transition: "all 0.3s ease",
|
|
54
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
55
|
+
zIndex: isSelected ? "10" : "1"
|
|
56
|
+
});
|
|
57
|
+
const iconTarget = document.createElement("div");
|
|
58
|
+
Object.assign(iconTarget.style, {
|
|
59
|
+
width: "40px",
|
|
60
|
+
height: "40px",
|
|
61
|
+
borderRadius: "50%",
|
|
62
|
+
backgroundColor: "white",
|
|
63
|
+
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
64
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
|
|
65
|
+
display: "flex",
|
|
66
|
+
alignItems: "center",
|
|
67
|
+
justifyContent: "center",
|
|
68
|
+
overflow: "hidden"
|
|
69
|
+
});
|
|
70
|
+
if (logoSrc) {
|
|
71
|
+
const img = document.createElement("img");
|
|
72
|
+
img.src = logoSrc;
|
|
73
|
+
img.style.width = "80%";
|
|
74
|
+
img.style.height = "80%";
|
|
75
|
+
img.style.objectFit = "contain";
|
|
76
|
+
iconTarget.appendChild(img);
|
|
77
|
+
} else {
|
|
78
|
+
iconTarget.style.backgroundColor = "#ef4444";
|
|
79
|
+
}
|
|
80
|
+
wrapper.appendChild(iconTarget);
|
|
81
|
+
if (showPrice && (marker.name || marker.price)) {
|
|
82
|
+
const label = document.createElement("div");
|
|
83
|
+
Object.assign(label.style, {
|
|
84
|
+
backgroundColor: "white",
|
|
85
|
+
padding: "2px 8px",
|
|
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 || "";
|
|
96
|
+
}
|
|
97
|
+
return wrapper;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/components/Map.tsx
|
|
39
101
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
40
102
|
var Map = ({
|
|
41
103
|
options,
|
|
@@ -43,88 +105,63 @@ var Map = ({
|
|
|
43
105
|
selectedMarkerId = null,
|
|
44
106
|
onMarkerClick,
|
|
45
107
|
onMapLoad,
|
|
46
|
-
children,
|
|
47
108
|
className = "",
|
|
48
109
|
style = { width: "100%", height: "100%" }
|
|
49
110
|
}) => {
|
|
50
111
|
const mapContainerRef = (0, import_react.useRef)(null);
|
|
51
|
-
const
|
|
112
|
+
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
52
113
|
const markersRef = (0, import_react.useRef)([]);
|
|
53
114
|
const [mapLib, setMapLib] = (0, import_react.useState)(null);
|
|
54
|
-
const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
|
|
55
115
|
(0, import_react.useEffect)(() => {
|
|
56
116
|
if (typeof window === "undefined") return;
|
|
57
|
-
let canceled = false;
|
|
58
117
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
setIsLoaded(true);
|
|
62
|
-
}
|
|
63
|
-
}).catch((err) => {
|
|
64
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0644\u0648\u062F \u0646\u0642\u0634\u0647 \u0646\u0634\u0627\u0646:", err);
|
|
118
|
+
setMapLib(mod.default || mod);
|
|
119
|
+
import("@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css");
|
|
65
120
|
});
|
|
66
|
-
return () => {
|
|
67
|
-
canceled = true;
|
|
68
|
-
};
|
|
69
121
|
}, []);
|
|
70
122
|
(0, import_react.useEffect)(() => {
|
|
71
|
-
if (!mapLib || !mapContainerRef.current ||
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
map
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (mapInstanceRef.current) {
|
|
85
|
-
mapInstanceRef.current.remove();
|
|
86
|
-
mapInstanceRef.current = null;
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
} catch (err) {
|
|
90
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0633\u0627\u062E\u062A \u0646\u0642\u0634\u0647:", err);
|
|
91
|
-
}
|
|
92
|
-
}, [mapLib, options, onMapLoad]);
|
|
123
|
+
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
124
|
+
const map = new mapLib.Map({
|
|
125
|
+
container: mapContainerRef.current,
|
|
126
|
+
...options
|
|
127
|
+
});
|
|
128
|
+
map.on("load", () => {
|
|
129
|
+
setMapInstance(map);
|
|
130
|
+
onMapLoad?.(map);
|
|
131
|
+
});
|
|
132
|
+
return () => {
|
|
133
|
+
if (map) map.remove();
|
|
134
|
+
};
|
|
135
|
+
}, [mapLib, options]);
|
|
93
136
|
(0, import_react.useEffect)(() => {
|
|
94
|
-
if (!
|
|
95
|
-
markersRef.current.forEach((m) => m.remove());
|
|
96
|
-
markersRef.current = [];
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
137
|
+
if (!mapInstance || !mapLib) return;
|
|
99
138
|
markersRef.current.forEach((m) => m.remove());
|
|
100
139
|
markersRef.current = [];
|
|
101
140
|
markers.forEach((markerData, index) => {
|
|
102
|
-
const el =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
border-radius: 50%;
|
|
109
|
-
border: 4px solid white;
|
|
110
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
111
|
-
"></div>
|
|
112
|
-
`;
|
|
113
|
-
el.style.cursor = "pointer";
|
|
114
|
-
el.style.transition = "transform 0.3s ease";
|
|
115
|
-
el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
|
|
116
|
-
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
|
|
141
|
+
const el = createCustomMarkerElement({
|
|
142
|
+
marker: markerData,
|
|
143
|
+
isSelected: markerData.id === selectedMarkerId
|
|
144
|
+
// logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید
|
|
145
|
+
});
|
|
146
|
+
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
117
147
|
el.addEventListener("click", (e) => {
|
|
118
148
|
e.stopPropagation();
|
|
119
|
-
onMarkerClick?.(markerData, index,
|
|
149
|
+
onMarkerClick?.(markerData, index, mapInstance);
|
|
120
150
|
});
|
|
121
151
|
markersRef.current.push(marker);
|
|
122
152
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
153
|
+
return () => {
|
|
154
|
+
markersRef.current.forEach((m) => m.remove());
|
|
155
|
+
};
|
|
156
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);
|
|
157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
158
|
+
"div",
|
|
159
|
+
{
|
|
160
|
+
ref: mapContainerRef,
|
|
161
|
+
className,
|
|
162
|
+
style: { position: "relative", ...style }
|
|
163
|
+
}
|
|
164
|
+
);
|
|
128
165
|
};
|
|
129
166
|
var Map_default = Map;
|
|
130
167
|
// 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"],"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';","\
|
|
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 { MapProps, MapboxMap, MarkerData } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\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 // ✅ استفاده از state به جای ref برای instance نقشه\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n\r\n // لود کردن کتابخانه نشان\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n setMapLib(mod.default || mod);\r\n // لود کردن استایلهای پیشفرض نشان\r\n import('@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css');\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); // ✅ اینجا باعث رندر مجدد و فعال شدن useEffect مارکرها میشود\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n if (map) map.remove();\r\n };\r\n }, [mapLib, options]);\r\n\r\n // مدیریت مارکرها\r\n useEffect(() => {\r\n // ✅ حالا mapInstance به عنوان وابستگی درست کار میکند\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 // ✅ استفاده از ابزاری که خودتان نوشتید\r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: markerData.id === selectedMarkerId,\r\n // logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید\r\n });\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\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 // پاکسازی مارکرها در صورت unmount\r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n ref={mapContainerRef} \r\n className={className} \r\n style={{ position: 'relative', ...style }} \r\n />\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 const wrapper = document.createElement('div');\r\n \r\n // استایلهای پایه بصورت Inline برای اطمینان از نمایش\r\n Object.assign(wrapper.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n cursor: 'pointer',\r\n transition: 'all 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n zIndex: isSelected ? '10' : '1'\r\n });\r\n\r\n // بخش تصویر مارکر\r\n const iconTarget = document.createElement('div');\r\n Object.assign(iconTarget.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 6px rgba(0,0,0,0.1)',\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 = '80%';\r\n img.style.height = '80%';\r\n img.style.objectFit = 'contain';\r\n iconTarget.appendChild(img);\r\n } else {\r\n // یک دایره رنگی ساده اگر لوگو نبود\r\n iconTarget.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n wrapper.appendChild(iconTarget);\r\n\r\n // بخش برچسب قیمت\r\n if (showPrice && (marker.name || marker.price)) {\r\n const label = document.createElement('div');\r\n Object.assign(label.style, {\r\n backgroundColor: 'white',\r\n padding: '2px 8px',\r\n borderRadius: '4px',\r\n marginTop: '4px',\r\n fontSize: '11px',\r\n fontWeight: 'bold',\r\n whiteSpace: 'nowrap',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n border: '1px solid #ddd'\r\n });\r\n const labelText = marker.price \r\n ? `${marker.price} ت` \r\n : marker.name;\r\n\r\nlabel.textContent = labelText || '';\r\n }\r\n\r\n return wrapper;\r\n}"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
// src/components/Map.tsx
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
// src/utils/createCustomMarkerElement.ts
|
|
5
|
+
function createCustomMarkerElement({
|
|
6
|
+
marker,
|
|
7
|
+
isSelected,
|
|
8
|
+
logoSrc = "",
|
|
9
|
+
showPrice = true
|
|
10
|
+
}) {
|
|
11
|
+
const wrapper = document.createElement("div");
|
|
12
|
+
Object.assign(wrapper.style, {
|
|
13
|
+
display: "flex",
|
|
14
|
+
flexDirection: "column",
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
cursor: "pointer",
|
|
17
|
+
transition: "all 0.3s ease",
|
|
18
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
19
|
+
zIndex: isSelected ? "10" : "1"
|
|
20
|
+
});
|
|
21
|
+
const iconTarget = document.createElement("div");
|
|
22
|
+
Object.assign(iconTarget.style, {
|
|
23
|
+
width: "40px",
|
|
24
|
+
height: "40px",
|
|
25
|
+
borderRadius: "50%",
|
|
26
|
+
backgroundColor: "white",
|
|
27
|
+
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
28
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
|
|
29
|
+
display: "flex",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
justifyContent: "center",
|
|
32
|
+
overflow: "hidden"
|
|
33
|
+
});
|
|
34
|
+
if (logoSrc) {
|
|
35
|
+
const img = document.createElement("img");
|
|
36
|
+
img.src = logoSrc;
|
|
37
|
+
img.style.width = "80%";
|
|
38
|
+
img.style.height = "80%";
|
|
39
|
+
img.style.objectFit = "contain";
|
|
40
|
+
iconTarget.appendChild(img);
|
|
41
|
+
} else {
|
|
42
|
+
iconTarget.style.backgroundColor = "#ef4444";
|
|
43
|
+
}
|
|
44
|
+
wrapper.appendChild(iconTarget);
|
|
45
|
+
if (showPrice && (marker.name || marker.price)) {
|
|
46
|
+
const label = document.createElement("div");
|
|
47
|
+
Object.assign(label.style, {
|
|
48
|
+
backgroundColor: "white",
|
|
49
|
+
padding: "2px 8px",
|
|
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 || "";
|
|
60
|
+
}
|
|
61
|
+
return wrapper;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/components/Map.tsx
|
|
3
65
|
import { jsx } from "react/jsx-runtime";
|
|
4
66
|
var Map = ({
|
|
5
67
|
options,
|
|
@@ -7,88 +69,63 @@ var Map = ({
|
|
|
7
69
|
selectedMarkerId = null,
|
|
8
70
|
onMarkerClick,
|
|
9
71
|
onMapLoad,
|
|
10
|
-
children,
|
|
11
72
|
className = "",
|
|
12
73
|
style = { width: "100%", height: "100%" }
|
|
13
74
|
}) => {
|
|
14
75
|
const mapContainerRef = useRef(null);
|
|
15
|
-
const
|
|
76
|
+
const [mapInstance, setMapInstance] = useState(null);
|
|
16
77
|
const markersRef = useRef([]);
|
|
17
78
|
const [mapLib, setMapLib] = useState(null);
|
|
18
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
19
79
|
useEffect(() => {
|
|
20
80
|
if (typeof window === "undefined") return;
|
|
21
|
-
let canceled = false;
|
|
22
81
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
setIsLoaded(true);
|
|
26
|
-
}
|
|
27
|
-
}).catch((err) => {
|
|
28
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0644\u0648\u062F \u0646\u0642\u0634\u0647 \u0646\u0634\u0627\u0646:", err);
|
|
82
|
+
setMapLib(mod.default || mod);
|
|
83
|
+
import("@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css");
|
|
29
84
|
});
|
|
30
|
-
return () => {
|
|
31
|
-
canceled = true;
|
|
32
|
-
};
|
|
33
85
|
}, []);
|
|
34
86
|
useEffect(() => {
|
|
35
|
-
if (!mapLib || !mapContainerRef.current ||
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
map
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (mapInstanceRef.current) {
|
|
49
|
-
mapInstanceRef.current.remove();
|
|
50
|
-
mapInstanceRef.current = null;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
} catch (err) {
|
|
54
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0633\u0627\u062E\u062A \u0646\u0642\u0634\u0647:", err);
|
|
55
|
-
}
|
|
56
|
-
}, [mapLib, options, onMapLoad]);
|
|
87
|
+
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
88
|
+
const map = new mapLib.Map({
|
|
89
|
+
container: mapContainerRef.current,
|
|
90
|
+
...options
|
|
91
|
+
});
|
|
92
|
+
map.on("load", () => {
|
|
93
|
+
setMapInstance(map);
|
|
94
|
+
onMapLoad?.(map);
|
|
95
|
+
});
|
|
96
|
+
return () => {
|
|
97
|
+
if (map) map.remove();
|
|
98
|
+
};
|
|
99
|
+
}, [mapLib, options]);
|
|
57
100
|
useEffect(() => {
|
|
58
|
-
if (!
|
|
59
|
-
markersRef.current.forEach((m) => m.remove());
|
|
60
|
-
markersRef.current = [];
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
101
|
+
if (!mapInstance || !mapLib) return;
|
|
63
102
|
markersRef.current.forEach((m) => m.remove());
|
|
64
103
|
markersRef.current = [];
|
|
65
104
|
markers.forEach((markerData, index) => {
|
|
66
|
-
const el =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
border-radius: 50%;
|
|
73
|
-
border: 4px solid white;
|
|
74
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
75
|
-
"></div>
|
|
76
|
-
`;
|
|
77
|
-
el.style.cursor = "pointer";
|
|
78
|
-
el.style.transition = "transform 0.3s ease";
|
|
79
|
-
el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
|
|
80
|
-
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
|
|
105
|
+
const el = createCustomMarkerElement({
|
|
106
|
+
marker: markerData,
|
|
107
|
+
isSelected: markerData.id === selectedMarkerId
|
|
108
|
+
// logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید
|
|
109
|
+
});
|
|
110
|
+
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
81
111
|
el.addEventListener("click", (e) => {
|
|
82
112
|
e.stopPropagation();
|
|
83
|
-
onMarkerClick?.(markerData, index,
|
|
113
|
+
onMarkerClick?.(markerData, index, mapInstance);
|
|
84
114
|
});
|
|
85
115
|
markersRef.current.push(marker);
|
|
86
116
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
return /* @__PURE__ */ jsx(
|
|
117
|
+
return () => {
|
|
118
|
+
markersRef.current.forEach((m) => m.remove());
|
|
119
|
+
};
|
|
120
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);
|
|
121
|
+
return /* @__PURE__ */ jsx(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
ref: mapContainerRef,
|
|
125
|
+
className,
|
|
126
|
+
style: { position: "relative", ...style }
|
|
127
|
+
}
|
|
128
|
+
);
|
|
92
129
|
};
|
|
93
130
|
var Map_default = Map;
|
|
94
131
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Map.tsx"],"sourcesContent":["\
|
|
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 { MapProps, MapboxMap, MarkerData } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\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 // ✅ استفاده از state به جای ref برای instance نقشه\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n\r\n // لود کردن کتابخانه نشان\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n setMapLib(mod.default || mod);\r\n // لود کردن استایلهای پیشفرض نشان\r\n import('@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css');\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); // ✅ اینجا باعث رندر مجدد و فعال شدن useEffect مارکرها میشود\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n if (map) map.remove();\r\n };\r\n }, [mapLib, options]);\r\n\r\n // مدیریت مارکرها\r\n useEffect(() => {\r\n // ✅ حالا mapInstance به عنوان وابستگی درست کار میکند\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 // ✅ استفاده از ابزاری که خودتان نوشتید\r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: markerData.id === selectedMarkerId,\r\n // logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید\r\n });\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\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 // پاکسازی مارکرها در صورت unmount\r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n ref={mapContainerRef} \r\n className={className} \r\n style={{ position: 'relative', ...style }} \r\n />\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 const wrapper = document.createElement('div');\r\n \r\n // استایلهای پایه بصورت Inline برای اطمینان از نمایش\r\n Object.assign(wrapper.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n cursor: 'pointer',\r\n transition: 'all 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n zIndex: isSelected ? '10' : '1'\r\n });\r\n\r\n // بخش تصویر مارکر\r\n const iconTarget = document.createElement('div');\r\n Object.assign(iconTarget.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 6px rgba(0,0,0,0.1)',\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 = '80%';\r\n img.style.height = '80%';\r\n img.style.objectFit = 'contain';\r\n iconTarget.appendChild(img);\r\n } else {\r\n // یک دایره رنگی ساده اگر لوگو نبود\r\n iconTarget.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n wrapper.appendChild(iconTarget);\r\n\r\n // بخش برچسب قیمت\r\n if (showPrice && (marker.name || marker.price)) {\r\n const label = document.createElement('div');\r\n Object.assign(label.style, {\r\n backgroundColor: 'white',\r\n padding: '2px 8px',\r\n borderRadius: '4px',\r\n marginTop: '4px',\r\n fontSize: '11px',\r\n fontWeight: 'bold',\r\n whiteSpace: 'nowrap',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n border: '1px solid #ddd'\r\n });\r\n const labelText = marker.price \r\n ? `${marker.price} ت` \r\n : marker.name;\r\n\r\nlabel.textContent = labelText || '';\r\n }\r\n\r\n return wrapper;\r\n}"],"mappings":";AAEA,SAAgB,WAAW,QAAQ,gBAAgB;;;ACO5C,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,YAAY;AACd,GAAqC;AACnC,QAAM,UAAU,SAAS,cAAc,KAAK;AAG5C,SAAO,OAAO,QAAQ,OAAO;AAAA,IAC3B,SAAS;AAAA,IACT,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW,aAAa,eAAe;AAAA,IACvC,QAAQ,aAAa,OAAO;AAAA,EAC9B,CAAC;AAGD,QAAM,aAAa,SAAS,cAAc,KAAK;AAC/C,SAAO,OAAO,WAAW,OAAO;AAAA,IAC9B,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,QAAQ,aAAa,sBAAsB;AAAA,IAC3C,WAAW;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACZ,CAAC;AAED,MAAI,SAAS;AACX,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM;AACV,QAAI,MAAM,QAAQ;AAClB,QAAI,MAAM,SAAS;AACnB,QAAI,MAAM,YAAY;AACtB,eAAW,YAAY,GAAG;AAAA,EAC5B,OAAO;AAEL,eAAW,MAAM,kBAAkB;AAAA,EACrC;AAEA,UAAQ,YAAY,UAAU;AAG9B,MAAI,cAAc,OAAO,QAAQ,OAAO,QAAQ;AAC9C,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,WAAO,OAAO,MAAM,OAAO;AAAA,MACzB,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,cAAc;AAAA,MACd,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,QAAQ;AAAA,IACV,CAAC;AACF,UAAM,YAAY,OAAO,QACxB,GAAG,OAAO,KAAK,YACf,OAAO;AAEX,UAAM,cAAc,aAAa;AAAA,EAC/B;AAEA,SAAO;AACT;;;ADOI;AAhFJ,IAAM,MAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,UAAU,CAAC;AAAA,EACX,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ,EAAE,OAAO,QAAQ,QAAQ,OAAO;AAC1C,MAAM;AACJ,QAAM,kBAAkB,OAAuB,IAAI;AAEnD,QAAM,CAAC,aAAa,cAAc,IAAI,SAA2B,IAAI;AACrE,QAAM,aAAa,OAAc,CAAC,CAAC;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAc,IAAI;AAG9C,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,gBAAU,IAAI,WAAW,GAAG;AAE5B,aAAO,yDAAyD;AAAA,IAClE,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,YAAa;AAExD,UAAM,MAAM,IAAI,OAAO,IAAI;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,GAAG;AAAA,IACL,CAAC;AAED,QAAI,GAAG,QAAQ,MAAM;AACnB,qBAAe,GAAG;AAClB,kBAAY,GAAG;AAAA,IACjB,CAAC;AAED,WAAO,MAAM;AACX,UAAI,IAAK,KAAI,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AAGpB,YAAU,MAAM;AAEd,QAAI,CAAC,eAAe,CAAC,OAAQ;AAG7B,eAAW,QAAQ,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAC5C,eAAW,UAAU,CAAC;AAEtB,YAAQ,QAAQ,CAAC,YAAwB,UAAkB;AAEzD,YAAM,KAAK,0BAA0B;AAAA,QACnC,QAAQ;AAAA,QACR,YAAY,WAAW,OAAO;AAAA;AAAA,MAEhC,CAAC;AAED,YAAM,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,CAAC,EAC7C,UAAU,CAAC,WAAW,KAAK,WAAW,GAAG,CAAC,EAC1C,MAAM,WAAW;AAEpB,SAAG,iBAAiB,SAAS,CAAC,MAAM;AAClC,UAAE,gBAAgB;AAClB,wBAAgB,YAAY,OAAO,WAAW;AAAA,MAChD,CAAC;AAED,iBAAW,QAAQ,KAAK,MAAM;AAAA,IAChC,CAAC;AAGD,WAAO,MAAM;AACX,iBAAW,QAAQ,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,aAAa,QAAQ,kBAAkB,aAAa,CAAC;AAElE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL;AAAA,MACA,OAAO,EAAE,UAAU,YAAY,GAAG,MAAM;AAAA;AAAA,EAC1C;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
|
package/dist/react.cjs
CHANGED
|
@@ -37,6 +37,68 @@ module.exports = __toCommonJS(react_exports);
|
|
|
37
37
|
|
|
38
38
|
// src/components/Map.tsx
|
|
39
39
|
var import_react = require("react");
|
|
40
|
+
|
|
41
|
+
// src/utils/createCustomMarkerElement.ts
|
|
42
|
+
function createCustomMarkerElement({
|
|
43
|
+
marker,
|
|
44
|
+
isSelected,
|
|
45
|
+
logoSrc = "",
|
|
46
|
+
showPrice = true
|
|
47
|
+
}) {
|
|
48
|
+
const wrapper = document.createElement("div");
|
|
49
|
+
Object.assign(wrapper.style, {
|
|
50
|
+
display: "flex",
|
|
51
|
+
flexDirection: "column",
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
cursor: "pointer",
|
|
54
|
+
transition: "all 0.3s ease",
|
|
55
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
56
|
+
zIndex: isSelected ? "10" : "1"
|
|
57
|
+
});
|
|
58
|
+
const iconTarget = document.createElement("div");
|
|
59
|
+
Object.assign(iconTarget.style, {
|
|
60
|
+
width: "40px",
|
|
61
|
+
height: "40px",
|
|
62
|
+
borderRadius: "50%",
|
|
63
|
+
backgroundColor: "white",
|
|
64
|
+
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
65
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
|
|
66
|
+
display: "flex",
|
|
67
|
+
alignItems: "center",
|
|
68
|
+
justifyContent: "center",
|
|
69
|
+
overflow: "hidden"
|
|
70
|
+
});
|
|
71
|
+
if (logoSrc) {
|
|
72
|
+
const img = document.createElement("img");
|
|
73
|
+
img.src = logoSrc;
|
|
74
|
+
img.style.width = "80%";
|
|
75
|
+
img.style.height = "80%";
|
|
76
|
+
img.style.objectFit = "contain";
|
|
77
|
+
iconTarget.appendChild(img);
|
|
78
|
+
} else {
|
|
79
|
+
iconTarget.style.backgroundColor = "#ef4444";
|
|
80
|
+
}
|
|
81
|
+
wrapper.appendChild(iconTarget);
|
|
82
|
+
if (showPrice && (marker.name || marker.price)) {
|
|
83
|
+
const label = document.createElement("div");
|
|
84
|
+
Object.assign(label.style, {
|
|
85
|
+
backgroundColor: "white",
|
|
86
|
+
padding: "2px 8px",
|
|
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 || "";
|
|
97
|
+
}
|
|
98
|
+
return wrapper;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/components/Map.tsx
|
|
40
102
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
103
|
var Map = ({
|
|
42
104
|
options,
|
|
@@ -44,88 +106,63 @@ var Map = ({
|
|
|
44
106
|
selectedMarkerId = null,
|
|
45
107
|
onMarkerClick,
|
|
46
108
|
onMapLoad,
|
|
47
|
-
children,
|
|
48
109
|
className = "",
|
|
49
110
|
style = { width: "100%", height: "100%" }
|
|
50
111
|
}) => {
|
|
51
112
|
const mapContainerRef = (0, import_react.useRef)(null);
|
|
52
|
-
const
|
|
113
|
+
const [mapInstance, setMapInstance] = (0, import_react.useState)(null);
|
|
53
114
|
const markersRef = (0, import_react.useRef)([]);
|
|
54
115
|
const [mapLib, setMapLib] = (0, import_react.useState)(null);
|
|
55
|
-
const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
|
|
56
116
|
(0, import_react.useEffect)(() => {
|
|
57
117
|
if (typeof window === "undefined") return;
|
|
58
|
-
let canceled = false;
|
|
59
118
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
setIsLoaded(true);
|
|
63
|
-
}
|
|
64
|
-
}).catch((err) => {
|
|
65
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0644\u0648\u062F \u0646\u0642\u0634\u0647 \u0646\u0634\u0627\u0646:", err);
|
|
119
|
+
setMapLib(mod.default || mod);
|
|
120
|
+
import("@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css");
|
|
66
121
|
});
|
|
67
|
-
return () => {
|
|
68
|
-
canceled = true;
|
|
69
|
-
};
|
|
70
122
|
}, []);
|
|
71
123
|
(0, import_react.useEffect)(() => {
|
|
72
|
-
if (!mapLib || !mapContainerRef.current ||
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
map
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (mapInstanceRef.current) {
|
|
86
|
-
mapInstanceRef.current.remove();
|
|
87
|
-
mapInstanceRef.current = null;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
} catch (err) {
|
|
91
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0633\u0627\u062E\u062A \u0646\u0642\u0634\u0647:", err);
|
|
92
|
-
}
|
|
93
|
-
}, [mapLib, options, onMapLoad]);
|
|
124
|
+
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
125
|
+
const map = new mapLib.Map({
|
|
126
|
+
container: mapContainerRef.current,
|
|
127
|
+
...options
|
|
128
|
+
});
|
|
129
|
+
map.on("load", () => {
|
|
130
|
+
setMapInstance(map);
|
|
131
|
+
onMapLoad?.(map);
|
|
132
|
+
});
|
|
133
|
+
return () => {
|
|
134
|
+
if (map) map.remove();
|
|
135
|
+
};
|
|
136
|
+
}, [mapLib, options]);
|
|
94
137
|
(0, import_react.useEffect)(() => {
|
|
95
|
-
if (!
|
|
96
|
-
markersRef.current.forEach((m) => m.remove());
|
|
97
|
-
markersRef.current = [];
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
138
|
+
if (!mapInstance || !mapLib) return;
|
|
100
139
|
markersRef.current.forEach((m) => m.remove());
|
|
101
140
|
markersRef.current = [];
|
|
102
141
|
markers.forEach((markerData, index) => {
|
|
103
|
-
const el =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
border-radius: 50%;
|
|
110
|
-
border: 4px solid white;
|
|
111
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
112
|
-
"></div>
|
|
113
|
-
`;
|
|
114
|
-
el.style.cursor = "pointer";
|
|
115
|
-
el.style.transition = "transform 0.3s ease";
|
|
116
|
-
el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
|
|
117
|
-
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
|
|
142
|
+
const el = createCustomMarkerElement({
|
|
143
|
+
marker: markerData,
|
|
144
|
+
isSelected: markerData.id === selectedMarkerId
|
|
145
|
+
// logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید
|
|
146
|
+
});
|
|
147
|
+
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
118
148
|
el.addEventListener("click", (e) => {
|
|
119
149
|
e.stopPropagation();
|
|
120
|
-
onMarkerClick?.(markerData, index,
|
|
150
|
+
onMarkerClick?.(markerData, index, mapInstance);
|
|
121
151
|
});
|
|
122
152
|
markersRef.current.push(marker);
|
|
123
153
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
154
|
+
return () => {
|
|
155
|
+
markersRef.current.forEach((m) => m.remove());
|
|
156
|
+
};
|
|
157
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);
|
|
158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
159
|
+
"div",
|
|
160
|
+
{
|
|
161
|
+
ref: mapContainerRef,
|
|
162
|
+
className,
|
|
163
|
+
style: { position: "relative", ...style }
|
|
164
|
+
}
|
|
165
|
+
);
|
|
129
166
|
};
|
|
130
167
|
var Map_default = Map;
|
|
131
168
|
// 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"],"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';","\
|
|
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 { MapProps, MapboxMap, MarkerData } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\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 // ✅ استفاده از state به جای ref برای instance نقشه\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n\r\n // لود کردن کتابخانه نشان\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n setMapLib(mod.default || mod);\r\n // لود کردن استایلهای پیشفرض نشان\r\n import('@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css');\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); // ✅ اینجا باعث رندر مجدد و فعال شدن useEffect مارکرها میشود\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n if (map) map.remove();\r\n };\r\n }, [mapLib, options]);\r\n\r\n // مدیریت مارکرها\r\n useEffect(() => {\r\n // ✅ حالا mapInstance به عنوان وابستگی درست کار میکند\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 // ✅ استفاده از ابزاری که خودتان نوشتید\r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: markerData.id === selectedMarkerId,\r\n // logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید\r\n });\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\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 // پاکسازی مارکرها در صورت unmount\r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n ref={mapContainerRef} \r\n className={className} \r\n style={{ position: 'relative', ...style }} \r\n />\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 const wrapper = document.createElement('div');\r\n \r\n // استایلهای پایه بصورت Inline برای اطمینان از نمایش\r\n Object.assign(wrapper.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n cursor: 'pointer',\r\n transition: 'all 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n zIndex: isSelected ? '10' : '1'\r\n });\r\n\r\n // بخش تصویر مارکر\r\n const iconTarget = document.createElement('div');\r\n Object.assign(iconTarget.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 6px rgba(0,0,0,0.1)',\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 = '80%';\r\n img.style.height = '80%';\r\n img.style.objectFit = 'contain';\r\n iconTarget.appendChild(img);\r\n } else {\r\n // یک دایره رنگی ساده اگر لوگو نبود\r\n iconTarget.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n wrapper.appendChild(iconTarget);\r\n\r\n // بخش برچسب قیمت\r\n if (showPrice && (marker.name || marker.price)) {\r\n const label = document.createElement('div');\r\n Object.assign(label.style, {\r\n backgroundColor: 'white',\r\n padding: '2px 8px',\r\n borderRadius: '4px',\r\n marginTop: '4px',\r\n fontSize: '11px',\r\n fontWeight: 'bold',\r\n whiteSpace: 'nowrap',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n border: '1px solid #ddd'\r\n });\r\n const labelText = marker.price \r\n ? `${marker.price} ت` \r\n : marker.name;\r\n\r\nlabel.textContent = labelText || '';\r\n }\r\n\r\n return wrapper;\r\n}"],"mappings":"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","names":[]}
|
package/dist/react.js
CHANGED
|
@@ -2,6 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
// src/components/Map.tsx
|
|
4
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
|
|
6
|
+
// src/utils/createCustomMarkerElement.ts
|
|
7
|
+
function createCustomMarkerElement({
|
|
8
|
+
marker,
|
|
9
|
+
isSelected,
|
|
10
|
+
logoSrc = "",
|
|
11
|
+
showPrice = true
|
|
12
|
+
}) {
|
|
13
|
+
const wrapper = document.createElement("div");
|
|
14
|
+
Object.assign(wrapper.style, {
|
|
15
|
+
display: "flex",
|
|
16
|
+
flexDirection: "column",
|
|
17
|
+
alignItems: "center",
|
|
18
|
+
cursor: "pointer",
|
|
19
|
+
transition: "all 0.3s ease",
|
|
20
|
+
transform: isSelected ? "scale(1.2)" : "scale(1)",
|
|
21
|
+
zIndex: isSelected ? "10" : "1"
|
|
22
|
+
});
|
|
23
|
+
const iconTarget = document.createElement("div");
|
|
24
|
+
Object.assign(iconTarget.style, {
|
|
25
|
+
width: "40px",
|
|
26
|
+
height: "40px",
|
|
27
|
+
borderRadius: "50%",
|
|
28
|
+
backgroundColor: "white",
|
|
29
|
+
border: isSelected ? "3px solid #3b82f6" : "2px solid #ef4444",
|
|
30
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)",
|
|
31
|
+
display: "flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
overflow: "hidden"
|
|
35
|
+
});
|
|
36
|
+
if (logoSrc) {
|
|
37
|
+
const img = document.createElement("img");
|
|
38
|
+
img.src = logoSrc;
|
|
39
|
+
img.style.width = "80%";
|
|
40
|
+
img.style.height = "80%";
|
|
41
|
+
img.style.objectFit = "contain";
|
|
42
|
+
iconTarget.appendChild(img);
|
|
43
|
+
} else {
|
|
44
|
+
iconTarget.style.backgroundColor = "#ef4444";
|
|
45
|
+
}
|
|
46
|
+
wrapper.appendChild(iconTarget);
|
|
47
|
+
if (showPrice && (marker.name || marker.price)) {
|
|
48
|
+
const label = document.createElement("div");
|
|
49
|
+
Object.assign(label.style, {
|
|
50
|
+
backgroundColor: "white",
|
|
51
|
+
padding: "2px 8px",
|
|
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 || "";
|
|
62
|
+
}
|
|
63
|
+
return wrapper;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/components/Map.tsx
|
|
5
67
|
import { jsx } from "react/jsx-runtime";
|
|
6
68
|
var Map = ({
|
|
7
69
|
options,
|
|
@@ -9,88 +71,63 @@ var Map = ({
|
|
|
9
71
|
selectedMarkerId = null,
|
|
10
72
|
onMarkerClick,
|
|
11
73
|
onMapLoad,
|
|
12
|
-
children,
|
|
13
74
|
className = "",
|
|
14
75
|
style = { width: "100%", height: "100%" }
|
|
15
76
|
}) => {
|
|
16
77
|
const mapContainerRef = useRef(null);
|
|
17
|
-
const
|
|
78
|
+
const [mapInstance, setMapInstance] = useState(null);
|
|
18
79
|
const markersRef = useRef([]);
|
|
19
80
|
const [mapLib, setMapLib] = useState(null);
|
|
20
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
21
81
|
useEffect(() => {
|
|
22
82
|
if (typeof window === "undefined") return;
|
|
23
|
-
let canceled = false;
|
|
24
83
|
import("@neshan-maps-platform/mapbox-gl").then((mod) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
setIsLoaded(true);
|
|
28
|
-
}
|
|
29
|
-
}).catch((err) => {
|
|
30
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0644\u0648\u062F \u0646\u0642\u0634\u0647 \u0646\u0634\u0627\u0646:", err);
|
|
84
|
+
setMapLib(mod.default || mod);
|
|
85
|
+
import("@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css");
|
|
31
86
|
});
|
|
32
|
-
return () => {
|
|
33
|
-
canceled = true;
|
|
34
|
-
};
|
|
35
87
|
}, []);
|
|
36
88
|
useEffect(() => {
|
|
37
|
-
if (!mapLib || !mapContainerRef.current ||
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
map
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (mapInstanceRef.current) {
|
|
51
|
-
mapInstanceRef.current.remove();
|
|
52
|
-
mapInstanceRef.current = null;
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
} catch (err) {
|
|
56
|
-
console.error("\u062E\u0637\u0627 \u062F\u0631 \u0633\u0627\u062E\u062A \u0646\u0642\u0634\u0647:", err);
|
|
57
|
-
}
|
|
58
|
-
}, [mapLib, options, onMapLoad]);
|
|
89
|
+
if (!mapLib || !mapContainerRef.current || mapInstance) return;
|
|
90
|
+
const map = new mapLib.Map({
|
|
91
|
+
container: mapContainerRef.current,
|
|
92
|
+
...options
|
|
93
|
+
});
|
|
94
|
+
map.on("load", () => {
|
|
95
|
+
setMapInstance(map);
|
|
96
|
+
onMapLoad?.(map);
|
|
97
|
+
});
|
|
98
|
+
return () => {
|
|
99
|
+
if (map) map.remove();
|
|
100
|
+
};
|
|
101
|
+
}, [mapLib, options]);
|
|
59
102
|
useEffect(() => {
|
|
60
|
-
if (!
|
|
61
|
-
markersRef.current.forEach((m) => m.remove());
|
|
62
|
-
markersRef.current = [];
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
103
|
+
if (!mapInstance || !mapLib) return;
|
|
65
104
|
markersRef.current.forEach((m) => m.remove());
|
|
66
105
|
markersRef.current = [];
|
|
67
106
|
markers.forEach((markerData, index) => {
|
|
68
|
-
const el =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
border-radius: 50%;
|
|
75
|
-
border: 4px solid white;
|
|
76
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
77
|
-
"></div>
|
|
78
|
-
`;
|
|
79
|
-
el.style.cursor = "pointer";
|
|
80
|
-
el.style.transition = "transform 0.3s ease";
|
|
81
|
-
el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
|
|
82
|
-
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
|
|
107
|
+
const el = createCustomMarkerElement({
|
|
108
|
+
marker: markerData,
|
|
109
|
+
isSelected: markerData.id === selectedMarkerId
|
|
110
|
+
// logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید
|
|
111
|
+
});
|
|
112
|
+
const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstance);
|
|
83
113
|
el.addEventListener("click", (e) => {
|
|
84
114
|
e.stopPropagation();
|
|
85
|
-
onMarkerClick?.(markerData, index,
|
|
115
|
+
onMarkerClick?.(markerData, index, mapInstance);
|
|
86
116
|
});
|
|
87
117
|
markersRef.current.push(marker);
|
|
88
118
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
return /* @__PURE__ */ jsx(
|
|
119
|
+
return () => {
|
|
120
|
+
markersRef.current.forEach((m) => m.remove());
|
|
121
|
+
};
|
|
122
|
+
}, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);
|
|
123
|
+
return /* @__PURE__ */ jsx(
|
|
124
|
+
"div",
|
|
125
|
+
{
|
|
126
|
+
ref: mapContainerRef,
|
|
127
|
+
className,
|
|
128
|
+
style: { position: "relative", ...style }
|
|
129
|
+
}
|
|
130
|
+
);
|
|
94
131
|
};
|
|
95
132
|
var Map_default = Map;
|
|
96
133
|
export {
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Map.tsx"],"sourcesContent":["\
|
|
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 { MapProps, MapboxMap, MarkerData } from '../types';\r\nimport { createCustomMarkerElement } from '../utils/createCustomMarkerElement';\r\n\r\nconst Map: React.FC<MapProps> = ({\r\n options,\r\n markers = [],\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 // ✅ استفاده از state به جای ref برای instance نقشه\r\n const [mapInstance, setMapInstance] = useState<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n\r\n // لود کردن کتابخانه نشان\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n setMapLib(mod.default || mod);\r\n // لود کردن استایلهای پیشفرض نشان\r\n import('@neshan-maps-platform/mapbox-gl/dist/NeshanMapboxGl.css');\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); // ✅ اینجا باعث رندر مجدد و فعال شدن useEffect مارکرها میشود\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n if (map) map.remove();\r\n };\r\n }, [mapLib, options]);\r\n\r\n // مدیریت مارکرها\r\n useEffect(() => {\r\n // ✅ حالا mapInstance به عنوان وابستگی درست کار میکند\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 // ✅ استفاده از ابزاری که خودتان نوشتید\r\n const el = createCustomMarkerElement({\r\n marker: markerData,\r\n isSelected: markerData.id === selectedMarkerId,\r\n // logoSrc: markerLogoUrl // میتوانید این را به props اضافه کنید\r\n });\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstance);\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 // پاکسازی مارکرها در صورت unmount\r\n return () => {\r\n markersRef.current.forEach((m) => m.remove());\r\n };\r\n }, [markers, mapInstance, mapLib, selectedMarkerId, onMarkerClick]);\r\n\r\n return (\r\n <div \r\n ref={mapContainerRef} \r\n className={className} \r\n style={{ position: 'relative', ...style }} \r\n />\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 const wrapper = document.createElement('div');\r\n \r\n // استایلهای پایه بصورت Inline برای اطمینان از نمایش\r\n Object.assign(wrapper.style, {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n cursor: 'pointer',\r\n transition: 'all 0.3s ease',\r\n transform: isSelected ? 'scale(1.2)' : 'scale(1)',\r\n zIndex: isSelected ? '10' : '1'\r\n });\r\n\r\n // بخش تصویر مارکر\r\n const iconTarget = document.createElement('div');\r\n Object.assign(iconTarget.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 6px rgba(0,0,0,0.1)',\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 = '80%';\r\n img.style.height = '80%';\r\n img.style.objectFit = 'contain';\r\n iconTarget.appendChild(img);\r\n } else {\r\n // یک دایره رنگی ساده اگر لوگو نبود\r\n iconTarget.style.backgroundColor = '#ef4444';\r\n }\r\n\r\n wrapper.appendChild(iconTarget);\r\n\r\n // بخش برچسب قیمت\r\n if (showPrice && (marker.name || marker.price)) {\r\n const label = document.createElement('div');\r\n Object.assign(label.style, {\r\n backgroundColor: 'white',\r\n padding: '2px 8px',\r\n borderRadius: '4px',\r\n marginTop: '4px',\r\n fontSize: '11px',\r\n fontWeight: 'bold',\r\n whiteSpace: 'nowrap',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)',\r\n border: '1px solid #ddd'\r\n });\r\n const labelText = marker.price \r\n ? `${marker.price} ت` \r\n : marker.name;\r\n\r\nlabel.textContent = labelText || '';\r\n }\r\n\r\n return wrapper;\r\n}"],"mappings":"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","names":[]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export interface MapProps {
|
|
|
28
28
|
children?: React.ReactNode;
|
|
29
29
|
className?: string;
|
|
30
30
|
style?: React.CSSProperties;
|
|
31
|
+
markerLogoUrl?: string;
|
|
32
|
+
flyToOnSelect?: boolean;
|
|
31
33
|
}
|
|
32
34
|
export type { LngLatLike, LngLatBoundsLike, MapboxMap, MapboxMarker, PointLike };
|
|
33
35
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,GAAG,IAAI,SAAS,EAChB,MAAM,IAAI,YAAY,EACtB,SAAS,EACV,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;IACrD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,GAAG,IAAI,SAAS,EAChB,MAAM,IAAI,YAAY,EACtB,SAAS,EACV,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;IACrD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MarkerData } from '../types';
|
|
2
|
+
interface CreateMarkerOptions {
|
|
3
|
+
marker: MarkerData;
|
|
4
|
+
isSelected: boolean;
|
|
5
|
+
logoSrc?: string;
|
|
6
|
+
showPrice?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function createCustomMarkerElement({ marker, isSelected, logoSrc, showPrice, }: CreateMarkerOptions): HTMLElement;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=createCustomMarkerElement.d.ts.map
|
|
@@ -0,0 +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,CAiEnC"}
|