mehdi-akbari-map 0.0.2 → 0.0.4

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":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAyB,MAAM,UAAU,CAAC;AAE3D,QAAA,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CA2F3B,CAAC;AAEF,eAAe,GAAG,CAAC"}
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"}
package/dist/index.cjs CHANGED
@@ -51,11 +51,17 @@ var Map = ({
51
51
  const mapInstanceRef = (0, import_react.useRef)(null);
52
52
  const markersRef = (0, import_react.useRef)([]);
53
53
  const [mapLib, setMapLib] = (0, import_react.useState)(null);
54
+ const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
54
55
  (0, import_react.useEffect)(() => {
55
56
  if (typeof window === "undefined") return;
56
57
  let canceled = false;
57
58
  import("@neshan-maps-platform/mapbox-gl").then((mod) => {
58
- if (!canceled) setMapLib(mod.default || 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);
59
65
  });
60
66
  return () => {
61
67
  canceled = true;
@@ -63,42 +69,50 @@ var Map = ({
63
69
  }, []);
64
70
  (0, import_react.useEffect)(() => {
65
71
  if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;
66
- const map = new mapLib.Map({
67
- container: mapContainerRef.current,
68
- style: "neshan://vector",
69
- // یا بر اساس mapType
70
- ...options
71
- });
72
- map.on("load", () => {
73
- mapInstanceRef.current = map;
74
- onMapLoad?.(map);
75
- });
76
- return () => {
77
- markersRef.current.forEach((m) => m.remove());
78
- markersRef.current = [];
79
- map.remove();
80
- mapInstanceRef.current = null;
81
- };
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
+ }
82
92
  }, [mapLib, options, onMapLoad]);
83
93
  (0, import_react.useEffect)(() => {
84
- if (!mapInstanceRef.current || !mapLib) return;
94
+ if (!mapInstanceRef.current || !mapLib || markers.length === 0) {
95
+ markersRef.current.forEach((m) => m.remove());
96
+ markersRef.current = [];
97
+ return;
98
+ }
85
99
  markersRef.current.forEach((m) => m.remove());
86
100
  markersRef.current = [];
87
101
  markers.forEach((markerData, index) => {
88
102
  const el = document.createElement("div");
89
103
  el.innerHTML = `
90
104
  <div style="
91
- background: red;
92
- width: 30px;
93
- height: 30px;
105
+ background: #ef4444;
106
+ width: 32px;
107
+ height: 32px;
94
108
  border-radius: 50%;
95
- border: 3px solid white;
96
- box-shadow: 0 2px 10px rgba(0,0,0,0.4);
109
+ border: 4px solid white;
110
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
97
111
  "></div>
98
112
  `;
99
113
  el.style.cursor = "pointer";
100
- el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
101
114
  el.style.transition = "transform 0.3s ease";
115
+ el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
102
116
  const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
103
117
  el.addEventListener("click", (e) => {
104
118
  e.stopPropagation();
@@ -106,7 +120,10 @@ var Map = ({
106
120
  });
107
121
  markersRef.current.push(marker);
108
122
  });
109
- }, [markers, mapLib, onMarkerClick, selectedMarkerId]);
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
+ }
110
127
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: mapContainerRef, className, style, children });
111
128
  };
112
129
  var Map_default = Map;
@@ -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';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types'; // یا '@/types' اگر alias تنظیم کردی\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[]>([]); // mapboxgl.Marker[]\r\n const [mapLib, setMapLib] = useState<any>(null);\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) setMapLib(mod.default || mod);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n style: 'neshan://vector', // یا بر اساس mapType\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 map.remove();\r\n mapInstanceRef.current = null;\r\n };\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib) return;\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: red;\r\n width: 30px;\r\n height: 30px;\r\n border-radius: 50%;\r\n border: 3px solid white;\r\n box-shadow: 0 2px 10px rgba(0,0,0,0.4);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n el.style.transition = 'transform 0.3s ease';\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, onMarkerClick, selectedMarkerId]);\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;;;ACEA,mBAAmD;AA0F/C;AAvFJ,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;AAE9C,8BAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,SAAU,WAAU,IAAI,WAAW,GAAG;AAAA,IAC7C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,UAAM,MAAM,IAAI,OAAO,IAAI;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,OAAO;AAAA;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAED,QAAI,GAAG,QAAQ,MAAM;AACnB,qBAAe,UAAU;AACzB,kBAAY,GAAG;AAAA,IACjB,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB,UAAI,OAAO;AACX,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAE/B,8BAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,OAAQ;AAExC,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,YAAY,WAAW,OAAO,mBAAmB,eAAe;AACzE,SAAG,MAAM,aAAa;AAEtB,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,gBAAgB,CAAC;AAErD,SACE,4CAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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":[]}
package/dist/index.js CHANGED
@@ -15,11 +15,17 @@ var Map = ({
15
15
  const mapInstanceRef = useRef(null);
16
16
  const markersRef = useRef([]);
17
17
  const [mapLib, setMapLib] = useState(null);
18
+ const [isLoaded, setIsLoaded] = useState(false);
18
19
  useEffect(() => {
19
20
  if (typeof window === "undefined") return;
20
21
  let canceled = false;
21
22
  import("@neshan-maps-platform/mapbox-gl").then((mod) => {
22
- if (!canceled) setMapLib(mod.default || 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);
23
29
  });
24
30
  return () => {
25
31
  canceled = true;
@@ -27,42 +33,50 @@ var Map = ({
27
33
  }, []);
28
34
  useEffect(() => {
29
35
  if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;
30
- const map = new mapLib.Map({
31
- container: mapContainerRef.current,
32
- style: "neshan://vector",
33
- // یا بر اساس mapType
34
- ...options
35
- });
36
- map.on("load", () => {
37
- mapInstanceRef.current = map;
38
- onMapLoad?.(map);
39
- });
40
- return () => {
41
- markersRef.current.forEach((m) => m.remove());
42
- markersRef.current = [];
43
- map.remove();
44
- mapInstanceRef.current = null;
45
- };
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
+ }
46
56
  }, [mapLib, options, onMapLoad]);
47
57
  useEffect(() => {
48
- if (!mapInstanceRef.current || !mapLib) return;
58
+ if (!mapInstanceRef.current || !mapLib || markers.length === 0) {
59
+ markersRef.current.forEach((m) => m.remove());
60
+ markersRef.current = [];
61
+ return;
62
+ }
49
63
  markersRef.current.forEach((m) => m.remove());
50
64
  markersRef.current = [];
51
65
  markers.forEach((markerData, index) => {
52
66
  const el = document.createElement("div");
53
67
  el.innerHTML = `
54
68
  <div style="
55
- background: red;
56
- width: 30px;
57
- height: 30px;
69
+ background: #ef4444;
70
+ width: 32px;
71
+ height: 32px;
58
72
  border-radius: 50%;
59
- border: 3px solid white;
60
- box-shadow: 0 2px 10px rgba(0,0,0,0.4);
73
+ border: 4px solid white;
74
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
61
75
  "></div>
62
76
  `;
63
77
  el.style.cursor = "pointer";
64
- el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
65
78
  el.style.transition = "transform 0.3s ease";
79
+ el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
66
80
  const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
67
81
  el.addEventListener("click", (e) => {
68
82
  e.stopPropagation();
@@ -70,7 +84,10 @@ var Map = ({
70
84
  });
71
85
  markersRef.current.push(marker);
72
86
  });
73
- }, [markers, mapLib, onMarkerClick, selectedMarkerId]);
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
+ }
74
91
  return /* @__PURE__ */ jsx("div", { ref: mapContainerRef, className, style, children });
75
92
  };
76
93
  var Map_default = Map;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Map.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types'; // یا '@/types' اگر alias تنظیم کردی\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[]>([]); // mapboxgl.Marker[]\r\n const [mapLib, setMapLib] = useState<any>(null);\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) setMapLib(mod.default || mod);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n style: 'neshan://vector', // یا بر اساس mapType\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 map.remove();\r\n mapInstanceRef.current = null;\r\n };\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib) return;\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: red;\r\n width: 30px;\r\n height: 30px;\r\n border-radius: 50%;\r\n border: 3px solid white;\r\n box-shadow: 0 2px 10px rgba(0,0,0,0.4);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n el.style.transition = 'transform 0.3s ease';\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, onMarkerClick, selectedMarkerId]);\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":";AAEA,SAAgB,WAAW,QAAQ,gBAAgB;AA0F/C;AAvFJ,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;AAE9C,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,SAAU,WAAU,IAAI,WAAW,GAAG;AAAA,IAC7C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,UAAM,MAAM,IAAI,OAAO,IAAI;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,OAAO;AAAA;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAED,QAAI,GAAG,QAAQ,MAAM;AACnB,qBAAe,UAAU;AACzB,kBAAY,GAAG;AAAA,IACjB,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB,UAAI,OAAO;AACX,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,OAAQ;AAExC,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,YAAY,WAAW,OAAO,mBAAmB,eAAe;AACzE,SAAG,MAAM,aAAa;AAEtB,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,gBAAgB,CAAC;AAErD,SACE,oBAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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":[]}
package/dist/react.cjs CHANGED
@@ -52,11 +52,17 @@ var Map = ({
52
52
  const mapInstanceRef = (0, import_react.useRef)(null);
53
53
  const markersRef = (0, import_react.useRef)([]);
54
54
  const [mapLib, setMapLib] = (0, import_react.useState)(null);
55
+ const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
55
56
  (0, import_react.useEffect)(() => {
56
57
  if (typeof window === "undefined") return;
57
58
  let canceled = false;
58
59
  import("@neshan-maps-platform/mapbox-gl").then((mod) => {
59
- if (!canceled) setMapLib(mod.default || 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);
60
66
  });
61
67
  return () => {
62
68
  canceled = true;
@@ -64,42 +70,50 @@ var Map = ({
64
70
  }, []);
65
71
  (0, import_react.useEffect)(() => {
66
72
  if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;
67
- const map = new mapLib.Map({
68
- container: mapContainerRef.current,
69
- style: "neshan://vector",
70
- // یا بر اساس mapType
71
- ...options
72
- });
73
- map.on("load", () => {
74
- mapInstanceRef.current = map;
75
- onMapLoad?.(map);
76
- });
77
- return () => {
78
- markersRef.current.forEach((m) => m.remove());
79
- markersRef.current = [];
80
- map.remove();
81
- mapInstanceRef.current = null;
82
- };
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
+ }
83
93
  }, [mapLib, options, onMapLoad]);
84
94
  (0, import_react.useEffect)(() => {
85
- if (!mapInstanceRef.current || !mapLib) return;
95
+ if (!mapInstanceRef.current || !mapLib || markers.length === 0) {
96
+ markersRef.current.forEach((m) => m.remove());
97
+ markersRef.current = [];
98
+ return;
99
+ }
86
100
  markersRef.current.forEach((m) => m.remove());
87
101
  markersRef.current = [];
88
102
  markers.forEach((markerData, index) => {
89
103
  const el = document.createElement("div");
90
104
  el.innerHTML = `
91
105
  <div style="
92
- background: red;
93
- width: 30px;
94
- height: 30px;
106
+ background: #ef4444;
107
+ width: 32px;
108
+ height: 32px;
95
109
  border-radius: 50%;
96
- border: 3px solid white;
97
- box-shadow: 0 2px 10px rgba(0,0,0,0.4);
110
+ border: 4px solid white;
111
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
98
112
  "></div>
99
113
  `;
100
114
  el.style.cursor = "pointer";
101
- el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
102
115
  el.style.transition = "transform 0.3s ease";
116
+ el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
103
117
  const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
104
118
  el.addEventListener("click", (e) => {
105
119
  e.stopPropagation();
@@ -107,7 +121,10 @@ var Map = ({
107
121
  });
108
122
  markersRef.current.push(marker);
109
123
  });
110
- }, [markers, mapLib, onMarkerClick, selectedMarkerId]);
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
+ }
111
128
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: mapContainerRef, className, style, children });
112
129
  };
113
130
  var Map_default = Map;
@@ -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';","\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types'; // یا '@/types' اگر alias تنظیم کردی\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[]>([]); // mapboxgl.Marker[]\r\n const [mapLib, setMapLib] = useState<any>(null);\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) setMapLib(mod.default || mod);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n style: 'neshan://vector', // یا بر اساس mapType\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 map.remove();\r\n mapInstanceRef.current = null;\r\n };\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib) return;\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: red;\r\n width: 30px;\r\n height: 30px;\r\n border-radius: 50%;\r\n border: 3px solid white;\r\n box-shadow: 0 2px 10px rgba(0,0,0,0.4);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n el.style.transition = 'transform 0.3s ease';\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, onMarkerClick, selectedMarkerId]);\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;;;ACEA,mBAAmD;AA0F/C;AAvFJ,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;AAE9C,8BAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,SAAU,WAAU,IAAI,WAAW,GAAG;AAAA,IAC7C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,UAAM,MAAM,IAAI,OAAO,IAAI;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,OAAO;AAAA;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAED,QAAI,GAAG,QAAQ,MAAM;AACnB,qBAAe,UAAU;AACzB,kBAAY,GAAG;AAAA,IACjB,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB,UAAI,OAAO;AACX,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAE/B,8BAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,OAAQ;AAExC,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,YAAY,WAAW,OAAO,mBAAmB,eAAe;AACzE,SAAG,MAAM,aAAa;AAEtB,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,gBAAgB,CAAC;AAErD,SACE,4CAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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":[]}
package/dist/react.js CHANGED
@@ -17,11 +17,17 @@ var Map = ({
17
17
  const mapInstanceRef = useRef(null);
18
18
  const markersRef = useRef([]);
19
19
  const [mapLib, setMapLib] = useState(null);
20
+ const [isLoaded, setIsLoaded] = useState(false);
20
21
  useEffect(() => {
21
22
  if (typeof window === "undefined") return;
22
23
  let canceled = false;
23
24
  import("@neshan-maps-platform/mapbox-gl").then((mod) => {
24
- if (!canceled) setMapLib(mod.default || 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);
25
31
  });
26
32
  return () => {
27
33
  canceled = true;
@@ -29,42 +35,50 @@ var Map = ({
29
35
  }, []);
30
36
  useEffect(() => {
31
37
  if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;
32
- const map = new mapLib.Map({
33
- container: mapContainerRef.current,
34
- style: "neshan://vector",
35
- // یا بر اساس mapType
36
- ...options
37
- });
38
- map.on("load", () => {
39
- mapInstanceRef.current = map;
40
- onMapLoad?.(map);
41
- });
42
- return () => {
43
- markersRef.current.forEach((m) => m.remove());
44
- markersRef.current = [];
45
- map.remove();
46
- mapInstanceRef.current = null;
47
- };
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
+ }
48
58
  }, [mapLib, options, onMapLoad]);
49
59
  useEffect(() => {
50
- if (!mapInstanceRef.current || !mapLib) return;
60
+ if (!mapInstanceRef.current || !mapLib || markers.length === 0) {
61
+ markersRef.current.forEach((m) => m.remove());
62
+ markersRef.current = [];
63
+ return;
64
+ }
51
65
  markersRef.current.forEach((m) => m.remove());
52
66
  markersRef.current = [];
53
67
  markers.forEach((markerData, index) => {
54
68
  const el = document.createElement("div");
55
69
  el.innerHTML = `
56
70
  <div style="
57
- background: red;
58
- width: 30px;
59
- height: 30px;
71
+ background: #ef4444;
72
+ width: 32px;
73
+ height: 32px;
60
74
  border-radius: 50%;
61
- border: 3px solid white;
62
- box-shadow: 0 2px 10px rgba(0,0,0,0.4);
75
+ border: 4px solid white;
76
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
63
77
  "></div>
64
78
  `;
65
79
  el.style.cursor = "pointer";
66
- el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
67
80
  el.style.transition = "transform 0.3s ease";
81
+ el.style.transform = markerData.id === selectedMarkerId ? "scale(1.4)" : "scale(1)";
68
82
  const marker = new mapLib.Marker({ element: el }).setLngLat([markerData.lng, markerData.lat]).addTo(mapInstanceRef.current);
69
83
  el.addEventListener("click", (e) => {
70
84
  e.stopPropagation();
@@ -72,7 +86,10 @@ var Map = ({
72
86
  });
73
87
  markersRef.current.push(marker);
74
88
  });
75
- }, [markers, mapLib, onMarkerClick, selectedMarkerId]);
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
+ }
76
93
  return /* @__PURE__ */ jsx("div", { ref: mapContainerRef, className, style, children });
77
94
  };
78
95
  var Map_default = Map;
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Map.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport React, { useEffect, useRef, useState } from 'react';\r\nimport { MapProps, MapboxMap, MarkerData } from '../types'; // یا '@/types' اگر alias تنظیم کردی\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[]>([]); // mapboxgl.Marker[]\r\n const [mapLib, setMapLib] = useState<any>(null);\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) setMapLib(mod.default || mod);\r\n });\r\n\r\n return () => {\r\n canceled = true;\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!mapLib || !mapContainerRef.current || mapInstanceRef.current) return;\r\n\r\n const map = new mapLib.Map({\r\n container: mapContainerRef.current,\r\n style: 'neshan://vector', // یا بر اساس mapType\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 map.remove();\r\n mapInstanceRef.current = null;\r\n };\r\n }, [mapLib, options, onMapLoad]);\r\n\r\n useEffect(() => {\r\n if (!mapInstanceRef.current || !mapLib) return;\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: red;\r\n width: 30px;\r\n height: 30px;\r\n border-radius: 50%;\r\n border: 3px solid white;\r\n box-shadow: 0 2px 10px rgba(0,0,0,0.4);\r\n \"></div>\r\n `;\r\n el.style.cursor = 'pointer';\r\n el.style.transform = markerData.id === selectedMarkerId ? 'scale(1.4)' : 'scale(1)';\r\n el.style.transition = 'transform 0.3s ease';\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, onMarkerClick, selectedMarkerId]);\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":";;;AAEA,SAAgB,WAAW,QAAQ,gBAAgB;AA0F/C;AAvFJ,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;AAE9C,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,WAAW;AAEf,WAAO,iCAAiC,EAAE,KAAK,CAAC,QAAQ;AACtD,UAAI,CAAC,SAAU,WAAU,IAAI,WAAW,GAAG;AAAA,IAC7C,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,gBAAgB,WAAW,eAAe,QAAS;AAEnE,UAAM,MAAM,IAAI,OAAO,IAAI;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,OAAO;AAAA;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAED,QAAI,GAAG,QAAQ,MAAM;AACnB,qBAAe,UAAU;AACzB,kBAAY,GAAG;AAAA,IACjB,CAAC;AAED,WAAO,MAAM;AACX,iBAAW,QAAQ,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC;AACjD,iBAAW,UAAU,CAAC;AACtB,UAAI,OAAO;AACX,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,eAAe,WAAW,CAAC,OAAQ;AAExC,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,YAAY,WAAW,OAAO,mBAAmB,eAAe;AACzE,SAAG,MAAM,aAAa;AAEtB,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,gBAAgB,CAAC;AAErD,SACE,oBAAC,SAAI,KAAK,iBAAiB,WAAsB,OAC9C,UACH;AAEJ;AAEA,IAAO,cAAQ;","names":[]}
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":[]}
@@ -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":"AAEA,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,CAiCnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mehdi-akbari-map",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A professional Map",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",