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.
@@ -1 +1 @@
1
- {"version":3,"file":"Map.d.ts","sourceRoot":"","sources":["../../src/components/Map.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAyB,MAAM,UAAU,CAAC;AAE3D,QAAA,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAwH3B,CAAC;AAEF,eAAe,GAAG,CAAC"}
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 mapInstanceRef = (0, import_react.useRef)(null);
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
- if (!canceled) {
60
- setMapLib(mod.default || mod);
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 || mapInstanceRef.current) return;
72
- try {
73
- const map = new mapLib.Map({
74
- container: mapContainerRef.current,
75
- ...options
76
- });
77
- map.on("load", () => {
78
- mapInstanceRef.current = map;
79
- onMapLoad?.(map);
80
- });
81
- return () => {
82
- markersRef.current.forEach((m) => m.remove());
83
- markersRef.current = [];
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 (!mapInstanceRef.current || !mapLib || markers.length === 0) {
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 = document.createElement("div");
103
- el.innerHTML = `
104
- <div style="
105
- background: #ef4444;
106
- width: 32px;
107
- height: 32px;
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, mapInstanceRef.current);
149
+ onMarkerClick?.(markerData, index, mapInstance);
120
150
  });
121
151
  markersRef.current.push(marker);
122
152
  });
123
- }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);
124
- if (!isLoaded) {
125
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", background: "#f3f4f6" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u0642\u0634\u0647..." }) });
126
- }
127
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: mapContainerRef, className, style, children });
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:
@@ -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';","\r\n\r\n\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types';\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 children,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const mapInstanceRef = useRef<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const [isLoaded, setIsLoaded] = useState(false); \r\n\r\n \r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n let canceled = false;\r\n\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (!canceled) {\r\n setMapLib(mod.default || mod);\r\n setIsLoaded(true);\r\n }\r\n }).catch((err) => {\r\n console.error(\"خطا در لود نقشه نشان:\", err);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n try {\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 mapInstanceRef.current = map;\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n if (mapInstanceRef.current) {\r\n mapInstanceRef.current.remove();\r\n mapInstanceRef.current = null;\r\n }\r\n };\r\n } catch (err) {\r\n console.error(\"خطا در ساخت نقشه:\", err);\r\n }\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib || markers.length === 0) {\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n return;\r\n }\r\n\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const el = document.createElement('div');\r\n el.innerHTML = `\r\n <div style=\"\r\n background: #ef4444;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n border: 4px solid white;\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transition = 'transform 0.3s ease';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstanceRef.current!);\r\n\r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstanceRef.current!);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);\r\n\r\n \r\n if (!isLoaded) {\r\n return (\r\n <div style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f3f4f6' }}>\r\n <p>در حال بارگذاری نقشه...</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={mapContainerRef} className={className} style={style}>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIA,mBAAmD;AAiH3C;AA9GR,IAAM,MAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,UAAU,CAAC;AAAA,EACX,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ,EAAE,OAAO,QAAQ,QAAQ,OAAO;AAC1C,MAAM;AACJ,QAAM,sBAAkB,qBAAuB,IAAI;AACnD,QAAM,qBAAiB,qBAAyB,IAAI;AACpD,QAAM,iBAAa,qBAAc,CAAC,CAAC;AACnC,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAc,IAAI;AAC9C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAG9C,8BAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,UAAU;AACb,kBAAU,IAAI,WAAW,GAAG;AAC5B,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,cAAQ,MAAM,yGAAyB,GAAG;AAAA,IAC5C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,QAAI;AACF,YAAM,MAAM,IAAI,OAAO,IAAI;AAAA,QACzB,WAAW,gBAAgB;AAAA,QAC3B,GAAG;AAAA,MACL,CAAC;AAED,UAAI,GAAG,QAAQ,MAAM;AACnB,uBAAe,UAAU;AACzB,oBAAY,GAAG;AAAA,MACjB,CAAC;AAED,aAAO,MAAM;AACX,mBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,mBAAW,UAAU,CAAC;AACtB,YAAI,eAAe,SAAS;AAC1B,yBAAe,QAAQ,OAAO;AAC9B,yBAAe,UAAU;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,sFAAqB,GAAG;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAG/B,8BAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,UAAU,QAAQ,WAAW,GAAG;AAE9D,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB;AAAA,IACF;AAGA,eAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,eAAW,UAAU,CAAC;AAEtB,YAAQ,QAAQ,CAAC,YAAwB,UAAkB;AACzD,YAAM,KAAK,SAAS,cAAc,KAAK;AACvC,SAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUf,SAAG,MAAM,SAAS;AAClB,SAAG,MAAM,aAAa;AACtB,SAAG,MAAM,YAAY,WAAW,OAAO,mBAAmB,eAAe;AAEzE,YAAM,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,CAAC,EAC7C,UAAU,CAAC,WAAW,KAAK,WAAW,GAAG,CAAC,EAC1C,MAAM,eAAe,OAAQ;AAEhC,SAAG,iBAAiB,SAAS,CAAC,MAAM;AAClC,UAAE,gBAAgB;AAClB,wBAAgB,YAAY,OAAO,eAAe,OAAQ;AAAA,MAC5D,CAAC;AAED,iBAAW,QAAQ,KAAK,MAAM;AAAA,IAChC,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,QAAQ,eAAe,SAAS,eAAe,gBAAgB,CAAC;AAG7E,MAAI,CAAC,UAAU;AACb,WACE,4CAAC,SAAI,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,YAAY,UAAU,GAC7G,sDAAC,OAAE,0HAAuB,GAC5B;AAAA,EAEJ;AAEA,SACE,4CAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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 mapInstanceRef = useRef(null);
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
- if (!canceled) {
24
- setMapLib(mod.default || mod);
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 || mapInstanceRef.current) return;
36
- try {
37
- const map = new mapLib.Map({
38
- container: mapContainerRef.current,
39
- ...options
40
- });
41
- map.on("load", () => {
42
- mapInstanceRef.current = map;
43
- onMapLoad?.(map);
44
- });
45
- return () => {
46
- markersRef.current.forEach((m) => m.remove());
47
- markersRef.current = [];
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 (!mapInstanceRef.current || !mapLib || markers.length === 0) {
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 = document.createElement("div");
67
- el.innerHTML = `
68
- <div style="
69
- background: #ef4444;
70
- width: 32px;
71
- height: 32px;
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, mapInstanceRef.current);
113
+ onMarkerClick?.(markerData, index, mapInstance);
84
114
  });
85
115
  markersRef.current.push(marker);
86
116
  });
87
- }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);
88
- if (!isLoaded) {
89
- return /* @__PURE__ */ jsx("div", { style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", background: "#f3f4f6" }, children: /* @__PURE__ */ jsx("p", { children: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u0642\u0634\u0647..." }) });
90
- }
91
- return /* @__PURE__ */ jsx("div", { ref: mapContainerRef, className, style, children });
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":["\r\n\r\n\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types';\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 children,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const mapInstanceRef = useRef<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const [isLoaded, setIsLoaded] = useState(false); \r\n\r\n \r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n let canceled = false;\r\n\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (!canceled) {\r\n setMapLib(mod.default || mod);\r\n setIsLoaded(true);\r\n }\r\n }).catch((err) => {\r\n console.error(\"خطا در لود نقشه نشان:\", err);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n try {\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 mapInstanceRef.current = map;\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n if (mapInstanceRef.current) {\r\n mapInstanceRef.current.remove();\r\n mapInstanceRef.current = null;\r\n }\r\n };\r\n } catch (err) {\r\n console.error(\"خطا در ساخت نقشه:\", err);\r\n }\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib || markers.length === 0) {\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n return;\r\n }\r\n\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const el = document.createElement('div');\r\n el.innerHTML = `\r\n <div style=\"\r\n background: #ef4444;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n border: 4px solid white;\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transition = 'transform 0.3s ease';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstanceRef.current!);\r\n\r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstanceRef.current!);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);\r\n\r\n \r\n if (!isLoaded) {\r\n return (\r\n <div style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f3f4f6' }}>\r\n <p>در حال بارگذاری نقشه...</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={mapContainerRef} className={className} style={style}>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;"],"mappings":";AAIA,SAAgB,WAAW,QAAQ,gBAAgB;AAiH3C;AA9GR,IAAM,MAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,UAAU,CAAC;AAAA,EACX,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ,EAAE,OAAO,QAAQ,QAAQ,OAAO;AAC1C,MAAM;AACJ,QAAM,kBAAkB,OAAuB,IAAI;AACnD,QAAM,iBAAiB,OAAyB,IAAI;AACpD,QAAM,aAAa,OAAc,CAAC,CAAC;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAc,IAAI;AAC9C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAG9C,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,UAAU;AACb,kBAAU,IAAI,WAAW,GAAG;AAC5B,oBAAY,IAAI;AAAA,MAClB;AAAA,IACF,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,cAAQ,MAAM,yGAAyB,GAAG;AAAA,IAC5C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,QAAI;AACF,YAAM,MAAM,IAAI,OAAO,IAAI;AAAA,QACzB,WAAW,gBAAgB;AAAA,QAC3B,GAAG;AAAA,MACL,CAAC;AAED,UAAI,GAAG,QAAQ,MAAM;AACnB,uBAAe,UAAU;AACzB,oBAAY,GAAG;AAAA,MACjB,CAAC;AAED,aAAO,MAAM;AACX,mBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,mBAAW,UAAU,CAAC;AACtB,YAAI,eAAe,SAAS;AAC1B,yBAAe,QAAQ,OAAO;AAC9B,yBAAe,UAAU;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,sFAAqB,GAAG;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAG/B,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,UAAU,QAAQ,WAAW,GAAG;AAE9D,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB;AAAA,IACF;AAGA,eAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,eAAW,UAAU,CAAC;AAEtB,YAAQ,QAAQ,CAAC,YAAwB,UAAkB;AACzD,YAAM,KAAK,SAAS,cAAc,KAAK;AACvC,SAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUf,SAAG,MAAM,SAAS;AAClB,SAAG,MAAM,aAAa;AACtB,SAAG,MAAM,YAAY,WAAW,OAAO,mBAAmB,eAAe;AAEzE,YAAM,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,CAAC,EAC7C,UAAU,CAAC,WAAW,KAAK,WAAW,GAAG,CAAC,EAC1C,MAAM,eAAe,OAAQ;AAEhC,SAAG,iBAAiB,SAAS,CAAC,MAAM;AAClC,UAAE,gBAAgB;AAClB,wBAAgB,YAAY,OAAO,eAAe,OAAQ;AAAA,MAC5D,CAAC;AAED,iBAAW,QAAQ,KAAK,MAAM;AAAA,IAChC,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,QAAQ,eAAe,SAAS,eAAe,gBAAgB,CAAC;AAG7E,MAAI,CAAC,UAAU;AACb,WACE,oBAAC,SAAI,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,YAAY,UAAU,GAC7G,8BAAC,OAAE,0HAAuB,GAC5B;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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/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 mapInstanceRef = (0, import_react.useRef)(null);
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
- if (!canceled) {
61
- setMapLib(mod.default || mod);
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 || mapInstanceRef.current) return;
73
- try {
74
- const map = new mapLib.Map({
75
- container: mapContainerRef.current,
76
- ...options
77
- });
78
- map.on("load", () => {
79
- mapInstanceRef.current = map;
80
- onMapLoad?.(map);
81
- });
82
- return () => {
83
- markersRef.current.forEach((m) => m.remove());
84
- markersRef.current = [];
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 (!mapInstanceRef.current || !mapLib || markers.length === 0) {
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 = document.createElement("div");
104
- el.innerHTML = `
105
- <div style="
106
- background: #ef4444;
107
- width: 32px;
108
- height: 32px;
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, mapInstanceRef.current);
150
+ onMarkerClick?.(markerData, index, mapInstance);
121
151
  });
122
152
  markersRef.current.push(marker);
123
153
  });
124
- }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);
125
- if (!isLoaded) {
126
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", background: "#f3f4f6" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u0642\u0634\u0647..." }) });
127
- }
128
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: mapContainerRef, className, style, children });
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:
@@ -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';","\r\n\r\n\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types';\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 children,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const mapInstanceRef = useRef<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const [isLoaded, setIsLoaded] = useState(false); \r\n\r\n \r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n let canceled = false;\r\n\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (!canceled) {\r\n setMapLib(mod.default || mod);\r\n setIsLoaded(true);\r\n }\r\n }).catch((err) => {\r\n console.error(\"خطا در لود نقشه نشان:\", err);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n try {\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 mapInstanceRef.current = map;\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n if (mapInstanceRef.current) {\r\n mapInstanceRef.current.remove();\r\n mapInstanceRef.current = null;\r\n }\r\n };\r\n } catch (err) {\r\n console.error(\"خطا در ساخت نقشه:\", err);\r\n }\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib || markers.length === 0) {\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n return;\r\n }\r\n\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const el = document.createElement('div');\r\n el.innerHTML = `\r\n <div style=\"\r\n background: #ef4444;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n border: 4px solid white;\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transition = 'transform 0.3s ease';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstanceRef.current!);\r\n\r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstanceRef.current!);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);\r\n\r\n \r\n if (!isLoaded) {\r\n return (\r\n <div style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f3f4f6' }}>\r\n <p>در حال بارگذاری نقشه...</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={mapContainerRef} className={className} style={style}>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;"],"mappings":"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","names":[]}
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAAmD;;;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,sBAAkB,qBAAuB,IAAI;AAEnD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAA2B,IAAI;AACrE,QAAM,iBAAa,qBAAc,CAAC,CAAC;AACnC,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAc,IAAI;AAG9C,8BAAU,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,8BAAU,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,8BAAU,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.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 mapInstanceRef = useRef(null);
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
- if (!canceled) {
26
- setMapLib(mod.default || mod);
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 || mapInstanceRef.current) return;
38
- try {
39
- const map = new mapLib.Map({
40
- container: mapContainerRef.current,
41
- ...options
42
- });
43
- map.on("load", () => {
44
- mapInstanceRef.current = map;
45
- onMapLoad?.(map);
46
- });
47
- return () => {
48
- markersRef.current.forEach((m) => m.remove());
49
- markersRef.current = [];
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 (!mapInstanceRef.current || !mapLib || markers.length === 0) {
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 = document.createElement("div");
69
- el.innerHTML = `
70
- <div style="
71
- background: #ef4444;
72
- width: 32px;
73
- height: 32px;
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, mapInstanceRef.current);
115
+ onMarkerClick?.(markerData, index, mapInstance);
86
116
  });
87
117
  markersRef.current.push(marker);
88
118
  });
89
- }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);
90
- if (!isLoaded) {
91
- return /* @__PURE__ */ jsx("div", { style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", background: "#f3f4f6" }, children: /* @__PURE__ */ jsx("p", { children: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u0642\u0634\u0647..." }) });
92
- }
93
- return /* @__PURE__ */ jsx("div", { ref: mapContainerRef, className, style, children });
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":["\r\n\r\n\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types';\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 children,\r\n className = '',\r\n style = { width: '100%', height: '100%' },\r\n}) => {\r\n const mapContainerRef = useRef<HTMLDivElement>(null);\r\n const mapInstanceRef = useRef<MapboxMap | null>(null);\r\n const markersRef = useRef<any[]>([]);\r\n const [mapLib, setMapLib] = useState<any>(null);\r\n const [isLoaded, setIsLoaded] = useState(false); \r\n\r\n \r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n let canceled = false;\r\n\r\n import('@neshan-maps-platform/mapbox-gl').then((mod) => {\r\n if (!canceled) {\r\n setMapLib(mod.default || mod);\r\n setIsLoaded(true);\r\n }\r\n }).catch((err) => {\r\n console.error(\"خطا در لود نقشه نشان:\", err);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n try {\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 mapInstanceRef.current = map;\r\n onMapLoad?.(map);\r\n });\r\n\r\n return () => {\r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n if (mapInstanceRef.current) {\r\n mapInstanceRef.current.remove();\r\n mapInstanceRef.current = null;\r\n }\r\n };\r\n } catch (err) {\r\n console.error(\"خطا در ساخت نقشه:\", err);\r\n }\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n \r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib || markers.length === 0) {\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n return;\r\n }\r\n\r\n \r\n markersRef.current.forEach((m: any) => m.remove());\r\n markersRef.current = [];\r\n\r\n markers.forEach((markerData: MarkerData, index: number) => {\r\n const el = document.createElement('div');\r\n el.innerHTML = `\r\n <div style=\"\r\n background: #ef4444;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n border: 4px solid white;\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transition = 'transform 0.3s ease';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n\r\n const marker = new mapLib.Marker({ element: el })\r\n .setLngLat([markerData.lng, markerData.lat])\r\n .addTo(mapInstanceRef.current!);\r\n\r\n el.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n onMarkerClick?.(markerData, index, mapInstanceRef.current!);\r\n });\r\n\r\n markersRef.current.push(marker);\r\n });\r\n }, [markers, mapLib, mapInstanceRef.current, onMarkerClick, selectedMarkerId]);\r\n\r\n \r\n if (!isLoaded) {\r\n return (\r\n <div style={{ ...style, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f3f4f6' }}>\r\n <p>در حال بارگذاری نقشه...</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={mapContainerRef} className={className} style={style}>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\nexport default Map;"],"mappings":"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","names":[]}
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":[]}
@@ -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;CAC7B;AAED,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mehdi-akbari-map",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A professional Map",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",