react-naver-maps-kit 1.2.0 → 1.3.0

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.
Files changed (47) hide show
  1. package/dist/core/loader/loadNaverMapsScript.d.ts.map +1 -1
  2. package/dist/index.cjs +833 -33
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +14 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +794 -35
  7. package/dist/index.js.map +1 -1
  8. package/dist/naver-maps-extensions.d.ts +53 -0
  9. package/dist/overlays/circle/Circle.d.ts.map +1 -1
  10. package/dist/overlays/data/GeoJson.d.ts.map +1 -1
  11. package/dist/overlays/data/Gpx.d.ts.map +1 -1
  12. package/dist/overlays/data/Kmz.d.ts.map +1 -1
  13. package/dist/overlays/ellipse/Ellipse.d.ts.map +1 -1
  14. package/dist/overlays/ground-overlay/GroundOverlay.d.ts +1 -0
  15. package/dist/overlays/ground-overlay/GroundOverlay.d.ts.map +1 -1
  16. package/dist/overlays/infowindow/InfoWindow.d.ts.map +1 -1
  17. package/dist/overlays/marker/Marker.d.ts.map +1 -1
  18. package/dist/overlays/marker-clusterer/MarkerClusterer.d.ts.map +1 -1
  19. package/dist/overlays/polygon/Polygon.d.ts.map +1 -1
  20. package/dist/overlays/polyline/Polyline.d.ts.map +1 -1
  21. package/dist/overlays/rectangle/Rectangle.d.ts.map +1 -1
  22. package/dist/react/components/NaverMap.d.ts.map +1 -1
  23. package/dist/react/context/MapInstanceContext.d.ts +11 -0
  24. package/dist/react/context/MapInstanceContext.d.ts.map +1 -0
  25. package/dist/react/provider/NaverMapProvider.d.ts +6 -2
  26. package/dist/react/provider/NaverMapProvider.d.ts.map +1 -1
  27. package/dist/submodules/drawing/DrawingManager.d.ts +43 -0
  28. package/dist/submodules/drawing/DrawingManager.d.ts.map +1 -0
  29. package/dist/submodules/drawing/index.d.ts +3 -0
  30. package/dist/submodules/drawing/index.d.ts.map +1 -0
  31. package/dist/submodules/panorama/AroundControl.d.ts +21 -0
  32. package/dist/submodules/panorama/AroundControl.d.ts.map +1 -0
  33. package/dist/submodules/panorama/FlightSpot.d.ts +17 -0
  34. package/dist/submodules/panorama/FlightSpot.d.ts.map +1 -0
  35. package/dist/submodules/panorama/Panorama.d.ts +75 -0
  36. package/dist/submodules/panorama/Panorama.d.ts.map +1 -0
  37. package/dist/submodules/panorama/PanoramaContext.d.ts +10 -0
  38. package/dist/submodules/panorama/PanoramaContext.d.ts.map +1 -0
  39. package/dist/submodules/panorama/index.d.ts +9 -0
  40. package/dist/submodules/panorama/index.d.ts.map +1 -0
  41. package/dist/submodules/visualization/DotMap.d.ts +25 -0
  42. package/dist/submodules/visualization/DotMap.d.ts.map +1 -0
  43. package/dist/submodules/visualization/HeatMap.d.ts +23 -0
  44. package/dist/submodules/visualization/HeatMap.d.ts.map +1 -0
  45. package/dist/submodules/visualization/index.d.ts +5 -0
  46. package/dist/submodules/visualization/index.d.ts.map +1 -0
  47. package/package.json +14 -12
package/dist/index.cjs CHANGED
@@ -1,5 +1,33 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) {
14
+ __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ }
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
26
+ }) : target, mod));
27
+
28
+ //#endregion
2
29
  let react = require("react");
30
+ react = __toESM(react);
3
31
  let react_jsx_runtime = require("react/jsx-runtime");
4
32
  let react_dom = require("react-dom");
5
33
  let module$1 = require("module");
@@ -33,27 +61,36 @@ function getClientKey(options) {
33
61
  };
34
62
  throw new Error("loadNaverMapsScript requires ncpKeyId. For backward compatibility, ncpClientId, govClientId, or finClientId can be provided.");
35
63
  }
36
- function isNaverMapsReady() {
64
+ function isNaverMapsReady(submodules) {
37
65
  if (typeof window === "undefined") return false;
38
- const browserWindow = window;
39
- return Boolean(browserWindow.naver?.maps);
66
+ const maps = window.naver?.maps;
67
+ if (!maps) return false;
68
+ if (submodules && submodules.length > 0) {
69
+ const submoduleMap = {
70
+ panorama: "Panorama",
71
+ geocoder: "Service",
72
+ drawing: "drawing",
73
+ visualization: "visualization"
74
+ };
75
+ for (const submodule of submodules) if (!maps[submoduleMap[submodule]]) return false;
76
+ }
77
+ return true;
40
78
  }
41
79
  function createScriptUrl(options) {
42
80
  const clientKey = getClientKey(options);
43
- const params = new URLSearchParams();
44
- params.set(clientKey.param, clientKey.value);
45
- if (options.submodules && options.submodules.length > 0) params.set("submodules", options.submodules.join(","));
46
- return `${NAVER_MAPS_SCRIPT_BASE_URL}?${params.toString()}`;
81
+ const queryParts = [`${clientKey.param}=${encodeURIComponent(clientKey.value)}`];
82
+ if (options.submodules && options.submodules.length > 0) queryParts.push(`submodules=${options.submodules.join(",")}`);
83
+ return `${NAVER_MAPS_SCRIPT_BASE_URL}?${queryParts.join("&")}`;
47
84
  }
48
- function waitForNaverMapsReady(timeoutMs) {
85
+ function waitForNaverMapsReady(timeoutMs, submodules) {
49
86
  return new Promise((resolve, reject) => {
50
- if (isNaverMapsReady()) {
87
+ if (isNaverMapsReady(submodules)) {
51
88
  resolve();
52
89
  return;
53
90
  }
54
91
  const startedAt = Date.now();
55
92
  const intervalId = setInterval(() => {
56
- if (isNaverMapsReady()) {
93
+ if (isNaverMapsReady(submodules)) {
57
94
  clearInterval(intervalId);
58
95
  resolve();
59
96
  return;
@@ -78,7 +115,7 @@ function attachAuthFailureHandler(reject) {
78
115
  }
79
116
  function loadNaverMapsScript(options) {
80
117
  if (typeof window === "undefined" || typeof document === "undefined") return Promise.reject(/* @__PURE__ */ new Error("loadNaverMapsScript can only run in a browser environment."));
81
- if (isNaverMapsReady()) return Promise.resolve();
118
+ if (isNaverMapsReady(options.submodules)) return Promise.resolve();
82
119
  const scriptUrl = createScriptUrl(options);
83
120
  if (inFlightLoad && inFlightScriptUrl === scriptUrl) return inFlightLoad;
84
121
  const existingScript = document.querySelector(`script[src="${scriptUrl}"]`);
@@ -96,7 +133,7 @@ function loadNaverMapsScript(options) {
96
133
  restoreAuthFailure();
97
134
  };
98
135
  const handleReady = () => {
99
- waitForNaverMapsReady(timeoutMs).then(() => {
136
+ waitForNaverMapsReady(timeoutMs, options.submodules).then(() => {
100
137
  cleanup();
101
138
  resolve();
102
139
  }).catch((error) => {
@@ -146,7 +183,7 @@ function loadNaverMapsScript(options) {
146
183
  };
147
184
  const onLoad = () => {
148
185
  script.dataset.reactNaverMapsKitLoaded = "true";
149
- waitForNaverMapsReady(timeoutMs).then(() => {
186
+ waitForNaverMapsReady(timeoutMs, options.submodules).then(() => {
150
187
  cleanup();
151
188
  resolve();
152
189
  }).catch((error) => {
@@ -269,13 +306,15 @@ function NaverMapProvider({ children, autoLoad = true, onReady, onError, ncpKeyI
269
306
  setMap,
270
307
  reloadSdk,
271
308
  retrySdk: reloadSdk,
272
- clearSdkError
309
+ clearSdkError,
310
+ submodules: submodules ?? []
273
311
  }), [
274
312
  clearSdkError,
275
313
  map,
276
314
  reloadSdk,
277
315
  sdkError,
278
- sdkStatus
316
+ sdkStatus,
317
+ submodules
279
318
  ]);
280
319
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NaverMapContext.Provider, {
281
320
  value,
@@ -283,6 +322,28 @@ function NaverMapProvider({ children, autoLoad = true, onReady, onError, ncpKeyI
283
322
  });
284
323
  }
285
324
 
325
+ //#endregion
326
+ //#region src/react/context/MapInstanceContext.tsx
327
+ const MapInstanceContext = (0, react.createContext)(null);
328
+ function useMapInstance() {
329
+ return (0, react.useContext)(MapInstanceContext);
330
+ }
331
+ function useMapInstanceRequired() {
332
+ const context = (0, react.useContext)(MapInstanceContext);
333
+ if (!context) throw new Error("This component must be used inside NaverMap or Panorama. Make sure it is a child of <NaverMap> or <Panorama>.");
334
+ return context;
335
+ }
336
+ function useMap() {
337
+ const context = (0, react.useContext)(MapInstanceContext);
338
+ if (!context || context.type !== "map") return null;
339
+ return context.instance;
340
+ }
341
+ function usePanoramaInstance() {
342
+ const context = (0, react.useContext)(MapInstanceContext);
343
+ if (!context || context.type !== "panorama") return null;
344
+ return context.instance;
345
+ }
346
+
286
347
  //#endregion
287
348
  //#region src/react/components/NaverMap.tsx
288
349
  const MAP_OPTION_KEYS = [
@@ -647,6 +708,7 @@ const NaverMapBase = (0, react.forwardRef)(function NaverMapInner(props, ref) {
647
708
  if (!context) throw new Error("NaverMap must be used inside NaverMapProvider.");
648
709
  const { sdkStatus, setMap, reloadSdk } = context;
649
710
  const [mapReady, setMapReady] = (0, react.useState)(false);
711
+ const [localMapInstance, setLocalMapInstance] = (0, react.useState)(null);
650
712
  const propsRef = (0, react.useRef)(props);
651
713
  (0, react.useEffect)(() => {
652
714
  propsRef.current = props;
@@ -791,6 +853,7 @@ const NaverMapBase = (0, react.forwardRef)(function NaverMapInner(props, ref) {
791
853
  mapRef.current = mapInstance;
792
854
  appliedOptionsRef.current = initOptions;
793
855
  setMap(mapInstance);
856
+ setLocalMapInstance(mapInstance);
794
857
  setMapReady(true);
795
858
  propsRef.current.onMapReady?.(mapInstance);
796
859
  const listeners = MAP_EVENT_BINDINGS.map((binding) => naver.maps.Event.addListener(mapInstance, binding.eventName, (event) => {
@@ -812,6 +875,7 @@ const NaverMapBase = (0, react.forwardRef)(function NaverMapInner(props, ref) {
812
875
  mapRef.current = null;
813
876
  appliedOptionsRef.current = {};
814
877
  setMap(null);
878
+ setLocalMapInstance(null);
815
879
  setMapReady(false);
816
880
  propsRef.current.onMapDestroy?.();
817
881
  };
@@ -843,15 +907,23 @@ const NaverMapBase = (0, react.forwardRef)(function NaverMapInner(props, ref) {
843
907
  isControlledCenter,
844
908
  isControlledZoom
845
909
  ]);
910
+ const mapInstanceContextValue = (0, react.useMemo)(() => ({
911
+ instance: localMapInstance,
912
+ setInstance: setLocalMapInstance,
913
+ type: "map"
914
+ }), [localMapInstance]);
846
915
  if (sdkStatus === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.fallback ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
847
916
  ...divProps,
848
917
  children: "지도를 불러올 수 없습니다."
849
918
  }) });
850
919
  if (sdkStatus === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.fallback ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ...divProps }) });
851
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
852
- ref: containerRef,
853
- ...divProps,
854
- children: mapReady ? props.children : null
920
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MapInstanceContext.Provider, {
921
+ value: mapInstanceContextValue,
922
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
923
+ ref: containerRef,
924
+ ...divProps,
925
+ children: mapReady ? props.children : null
926
+ })
855
927
  });
856
928
  });
857
929
  NaverMapBase.displayName = "NaverMap";
@@ -1042,7 +1114,8 @@ function toLatLngLiteral(position) {
1042
1114
  return null;
1043
1115
  }
1044
1116
  const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
1045
- const { map: contextMap, sdkStatus } = useNaverMap();
1117
+ const { sdkStatus } = useNaverMap();
1118
+ const contextMap = useMapInstance()?.instance;
1046
1119
  const clustererRegistry = (0, react.useContext)(ClustererContext);
1047
1120
  const visibleIds = (0, react.useContext)(ClustererVisibilityContext);
1048
1121
  const isInsideClusterer = clustererRegistry !== null && clustererRegistry.enabled;
@@ -2262,7 +2335,8 @@ function padBounds(bounds, padding) {
2262
2335
  */
2263
2336
  function MarkerClusterer(props) {
2264
2337
  const { algorithm: algorithmProp, clusterIcon, onClusterClick, behavior, clusterData, enabled = true, children } = props;
2265
- const { map, sdkStatus } = useNaverMap();
2338
+ const { sdkStatus } = useNaverMap();
2339
+ const map = useMapInstance()?.instance;
2266
2340
  const registryRef = (0, react.useRef)(/* @__PURE__ */ new Map());
2267
2341
  const [registryVersion, setRegistryVersion] = (0, react.useState)(0);
2268
2342
  const registry = (0, react.useMemo)(() => ({
@@ -2512,7 +2586,8 @@ function setInfoWindowOptionByKey(infoWindow, key, value) {
2512
2586
  infoWindow.setOptions(key, value);
2513
2587
  }
2514
2588
  const InfoWindow = (0, react.forwardRef)(function InfoWindowInner(props, ref) {
2515
- const { map, sdkStatus } = useNaverMap();
2589
+ const { sdkStatus } = useNaverMap();
2590
+ const map = useMapInstance()?.instance;
2516
2591
  const infoWindowRef = (0, react.useRef)(null);
2517
2592
  const infoWindowEventListenersRef = (0, react.useRef)([]);
2518
2593
  const onInfoWindowDestroyRef = (0, react.useRef)(props.onInfoWindowDestroy);
@@ -2786,7 +2861,8 @@ function buildCircleEventBindings(props) {
2786
2861
  ];
2787
2862
  }
2788
2863
  const Circle = (0, react.forwardRef)(function CircleInner(props, ref) {
2789
- const { map: contextMap, sdkStatus } = useNaverMap();
2864
+ const { sdkStatus } = useNaverMap();
2865
+ const contextMap = useMapInstance()?.instance;
2790
2866
  const circleRef = (0, react.useRef)(null);
2791
2867
  const circleEventListenersRef = (0, react.useRef)([]);
2792
2868
  const onCircleDestroyRef = (0, react.useRef)(props.onCircleDestroy);
@@ -2998,7 +3074,8 @@ function buildEllipseEventBindings(props) {
2998
3074
  ];
2999
3075
  }
3000
3076
  const Ellipse = (0, react.forwardRef)(function EllipseInner(props, ref) {
3001
- const { map: contextMap, sdkStatus } = useNaverMap();
3077
+ const { sdkStatus } = useNaverMap();
3078
+ const contextMap = useMapInstance()?.instance;
3002
3079
  const ellipseRef = (0, react.useRef)(null);
3003
3080
  const ellipseEventListenersRef = (0, react.useRef)([]);
3004
3081
  const onEllipseDestroyRef = (0, react.useRef)(props.onEllipseDestroy);
@@ -3162,7 +3239,8 @@ function buildGroundOverlayEventBindings(props) {
3162
3239
  ];
3163
3240
  }
3164
3241
  const GroundOverlay = (0, react.forwardRef)(function GroundOverlayInner(props, ref) {
3165
- const { map: contextMap, sdkStatus } = useNaverMap();
3242
+ const { sdkStatus } = useNaverMap();
3243
+ const contextMap = useMapInstance()?.instance;
3166
3244
  const groundOverlayRef = (0, react.useRef)(null);
3167
3245
  const groundOverlayEventListenersRef = (0, react.useRef)([]);
3168
3246
  const onGroundOverlayDestroyRef = (0, react.useRef)(props.onGroundOverlayDestroy);
@@ -3200,7 +3278,12 @@ const GroundOverlay = (0, react.forwardRef)(function GroundOverlayInner(props, r
3200
3278
  getProjection: (...args) => invokeGroundOverlayMethod("getProjection", ...args),
3201
3279
  getUrl: (...args) => invokeGroundOverlayMethod("getUrl", ...args),
3202
3280
  setMap: (...args) => invokeGroundOverlayMethod("setMap", ...args),
3203
- setOpacity: (...args) => invokeGroundOverlayMethod("setOpacity", ...args)
3281
+ setOpacity: (...args) => invokeGroundOverlayMethod("setOpacity", ...args),
3282
+ setUrl: (url) => {
3283
+ const groundOverlay = groundOverlayRef.current;
3284
+ if (!groundOverlay) return void 0;
3285
+ groundOverlay.setUrl?.(url);
3286
+ }
3204
3287
  }), [invokeGroundOverlayMethod]);
3205
3288
  (0, react.useEffect)(() => {
3206
3289
  if (sdkStatus !== "ready" || !targetMap || groundOverlayRef.current) return;
@@ -3366,7 +3449,8 @@ function buildPolygonEventBindings(props) {
3366
3449
  ];
3367
3450
  }
3368
3451
  const Polygon = (0, react.forwardRef)(function PolygonInner(props, ref) {
3369
- const { map: contextMap, sdkStatus } = useNaverMap();
3452
+ const { sdkStatus } = useNaverMap();
3453
+ const contextMap = useMapInstance()?.instance;
3370
3454
  const polygonRef = (0, react.useRef)(null);
3371
3455
  const polygonEventListenersRef = (0, react.useRef)([]);
3372
3456
  const onPolygonDestroyRef = (0, react.useRef)(props.onPolygonDestroy);
@@ -3588,7 +3672,8 @@ function buildPolylineEventBindings(props) {
3588
3672
  ];
3589
3673
  }
3590
3674
  const Polyline = (0, react.forwardRef)(function PolylineInner(props, ref) {
3591
- const { map: contextMap, sdkStatus } = useNaverMap();
3675
+ const { sdkStatus } = useNaverMap();
3676
+ const contextMap = useMapInstance()?.instance;
3592
3677
  const polylineRef = (0, react.useRef)(null);
3593
3678
  const polylineEventListenersRef = (0, react.useRef)([]);
3594
3679
  const onPolylineDestroyRef = (0, react.useRef)(props.onPolylineDestroy);
@@ -3798,7 +3883,8 @@ function buildRectangleEventBindings(props) {
3798
3883
  ];
3799
3884
  }
3800
3885
  const Rectangle = (0, react.forwardRef)(function RectangleInner(props, ref) {
3801
- const { map: contextMap, sdkStatus } = useNaverMap();
3886
+ const { sdkStatus } = useNaverMap();
3887
+ const contextMap = useMapInstance()?.instance;
3802
3888
  const rectangleRef = (0, react.useRef)(null);
3803
3889
  const rectangleEventListenersRef = (0, react.useRef)([]);
3804
3890
  const onRectangleDestroyRef = (0, react.useRef)(props.onRectangleDestroy);
@@ -3935,7 +4021,8 @@ function buildGeoJsonEventBindings(props) {
3935
4021
  ];
3936
4022
  }
3937
4023
  const GeoJson = (0, react.forwardRef)(function GeoJsonInner(props, ref) {
3938
- const { map: contextMap, sdkStatus } = useNaverMap();
4024
+ const { sdkStatus } = useNaverMap();
4025
+ const contextMap = useMapInstance()?.instance;
3939
4026
  const dataRef = (0, react.useRef)(null);
3940
4027
  const dataEventListenersRef = (0, react.useRef)([]);
3941
4028
  const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
@@ -4083,7 +4170,8 @@ function parseXml(xmlString) {
4083
4170
  return doc;
4084
4171
  }
4085
4172
  const Gpx = (0, react.forwardRef)(function GpxInner(props, ref) {
4086
- const { map: contextMap, sdkStatus } = useNaverMap();
4173
+ const { sdkStatus } = useNaverMap();
4174
+ const contextMap = useMapInstance()?.instance;
4087
4175
  const dataRef = (0, react.useRef)(null);
4088
4176
  const dataEventListenersRef = (0, react.useRef)([]);
4089
4177
  const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
@@ -4685,7 +4773,8 @@ function extractKmlFromKmz(arrayBuffer) {
4685
4773
  return doc;
4686
4774
  }
4687
4775
  const Kmz = (0, react.forwardRef)(function KmzInner(props, ref) {
4688
- const { map: contextMap, sdkStatus } = useNaverMap();
4776
+ const { sdkStatus } = useNaverMap();
4777
+ const contextMap = useMapInstance()?.instance;
4689
4778
  const dataRef = (0, react.useRef)(null);
4690
4779
  const dataEventListenersRef = (0, react.useRef)([]);
4691
4780
  const onDataDestroyRef = (0, react.useRef)(props.onDataDestroy);
@@ -4797,29 +4886,740 @@ const Kmz = (0, react.forwardRef)(function KmzInner(props, ref) {
4797
4886
  });
4798
4887
  Kmz.displayName = "Kmz";
4799
4888
 
4889
+ //#endregion
4890
+ //#region src/submodules/panorama/PanoramaContext.ts
4891
+ const PanoramaContext = (0, react.createContext)(null);
4892
+ function usePanorama() {
4893
+ const value = (0, react.useContext)(PanoramaContext);
4894
+ if (!value) throw new Error("usePanorama must be used within a Panorama component. Make sure you wrap your panorama-dependent components with <Panorama>.");
4895
+ return value;
4896
+ }
4897
+
4898
+ //#endregion
4899
+ //#region src/submodules/panorama/Panorama.tsx
4900
+ function toLatLng(position) {
4901
+ if (!position) return position;
4902
+ const pos = position;
4903
+ if (typeof pos.lat === "number" && typeof pos.lng === "number") return new naver.maps.LatLng(pos.lat, pos.lng);
4904
+ return position;
4905
+ }
4906
+ function toPanoramaOptions(props, convertLatLng = false, excludeControlled = false) {
4907
+ const options = {};
4908
+ if (props.size !== void 0) options.size = props.size;
4909
+ if (props.panoId !== void 0) options.panoId = props.panoId;
4910
+ if (!excludeControlled && props.position !== void 0) options.position = convertLatLng ? toLatLng(props.position) : props.position;
4911
+ if (!excludeControlled && props.pov !== void 0) options.pov = props.pov;
4912
+ if (props.visible !== void 0) options.visible = props.visible;
4913
+ if (props.minScale !== void 0) options.minScale = props.minScale;
4914
+ if (props.maxScale !== void 0) options.maxScale = props.maxScale;
4915
+ if (props.minZoom !== void 0) options.minZoom = props.minZoom;
4916
+ if (props.maxZoom !== void 0) options.maxZoom = props.maxZoom;
4917
+ if (props.flightSpot !== void 0) options.flightSpot = props.flightSpot;
4918
+ if (props.logoControl !== void 0) options.logoControl = props.logoControl;
4919
+ if (props.logoControlOptions !== void 0) options.logoControlOptions = props.logoControlOptions;
4920
+ if (props.zoomControl !== void 0) options.zoomControl = props.zoomControl;
4921
+ if (props.zoomControlOptions !== void 0) options.zoomControlOptions = props.zoomControlOptions;
4922
+ if (props.aroundControl !== void 0) options.aroundControl = props.aroundControl;
4923
+ if (props.aroundControlOptions !== void 0) options.aroundControlOptions = props.aroundControlOptions;
4924
+ return options;
4925
+ }
4926
+ function buildPanoramaEventBindings(props) {
4927
+ return [
4928
+ {
4929
+ eventName: "init",
4930
+ invoke: props.onInit ? () => props.onInit?.() : void 0
4931
+ },
4932
+ {
4933
+ eventName: "pano_changed",
4934
+ invoke: props.onPanoChanged ? () => props.onPanoChanged?.() : void 0
4935
+ },
4936
+ {
4937
+ eventName: "pano_status",
4938
+ invoke: props.onPanoStatus ? (event) => props.onPanoStatus?.(event) : void 0
4939
+ },
4940
+ {
4941
+ eventName: "pov_changed",
4942
+ invoke: props.onPovChanged ? () => props.onPovChanged?.() : void 0
4943
+ }
4944
+ ];
4945
+ }
4946
+ function bindPanoramaEventListeners(panorama, listenersRef, bindings) {
4947
+ if (listenersRef.current.length > 0) {
4948
+ naver.maps.Event.removeListener(listenersRef.current);
4949
+ listenersRef.current = [];
4950
+ }
4951
+ listenersRef.current = bindings.filter((binding) => typeof binding.invoke === "function").map((binding) => naver.maps.Event.addListener(panorama, binding.eventName, (event) => {
4952
+ binding.invoke?.(event);
4953
+ }));
4954
+ }
4955
+ const Panorama = (0, react.forwardRef)(function PanoramaInner(props, ref) {
4956
+ const naverMapContext = NaverMapContext;
4957
+ const context = react.default.useContext(naverMapContext);
4958
+ if (!context) throw new Error("Panorama must be used inside NaverMapProvider.");
4959
+ const { sdkStatus, submodules } = context;
4960
+ if (sdkStatus === "ready" && !submodules.includes("panorama")) throw new Error("Panorama component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
4961
+ const containerRef = (0, react.useRef)(null);
4962
+ const panoramaRef = (0, react.useRef)(null);
4963
+ const eventListenersRef = (0, react.useRef)([]);
4964
+ const onPanoramaDestroyRef = (0, react.useRef)(props.onPanoramaDestroy);
4965
+ const [panoramaInstance, setPanoramaInstance] = (0, react.useState)(null);
4966
+ const [panoramaReady, setPanoramaReady] = (0, react.useState)(false);
4967
+ const propsRef = (0, react.useRef)(props);
4968
+ (0, react.useEffect)(() => {
4969
+ propsRef.current = props;
4970
+ });
4971
+ (0, react.useEffect)(() => {
4972
+ onPanoramaDestroyRef.current = props.onPanoramaDestroy;
4973
+ }, [props.onPanoramaDestroy]);
4974
+ const initialPositionRef = (0, react.useRef)(props.position ?? props.defaultPosition);
4975
+ const initialPovRef = (0, react.useRef)(props.pov ?? props.defaultPov);
4976
+ const isControlledPosition = props.position !== void 0;
4977
+ const isControlledPov = props.pov !== void 0;
4978
+ const optionsSnapshot = (0, react.useMemo)(() => toPanoramaOptions(props, false, true), [
4979
+ props.size,
4980
+ props.panoId,
4981
+ props.visible,
4982
+ props.minScale,
4983
+ props.maxScale,
4984
+ props.minZoom,
4985
+ props.maxZoom,
4986
+ props.flightSpot,
4987
+ props.logoControl,
4988
+ props.logoControlOptions,
4989
+ props.zoomControl,
4990
+ props.zoomControlOptions,
4991
+ props.aroundControl,
4992
+ props.aroundControlOptions
4993
+ ]);
4994
+ const invokePanoramaMethod = (0, react.useCallback)((methodName, ...args) => {
4995
+ const panorama = panoramaRef.current;
4996
+ if (!panorama) return void 0;
4997
+ const method = panorama[methodName];
4998
+ if (typeof method !== "function") return void 0;
4999
+ return method.apply(panorama, args);
5000
+ }, []);
5001
+ (0, react.useImperativeHandle)(ref, () => ({
5002
+ getInstance: () => panoramaRef.current,
5003
+ getElement: (...args) => invokePanoramaMethod("getElement", ...args),
5004
+ getLocation: (...args) => invokePanoramaMethod("getLocation", ...args),
5005
+ getMaxScale: (...args) => invokePanoramaMethod("getMaxScale", ...args),
5006
+ getMaxZoom: (...args) => invokePanoramaMethod("getMaxZoom", ...args),
5007
+ getMinScale: (...args) => invokePanoramaMethod("getMinScale", ...args),
5008
+ getMinZoom: (...args) => invokePanoramaMethod("getMinZoom", ...args),
5009
+ getOptions: (...args) => invokePanoramaMethod("getOptions", ...args),
5010
+ getPanoId: (...args) => invokePanoramaMethod("getPanoId", ...args),
5011
+ getPosition: (...args) => invokePanoramaMethod("getPosition", ...args),
5012
+ getPov: (...args) => invokePanoramaMethod("getPov", ...args),
5013
+ getProjection: (...args) => invokePanoramaMethod("getProjection", ...args),
5014
+ getScale: (...args) => invokePanoramaMethod("getScale", ...args),
5015
+ getSize: (...args) => invokePanoramaMethod("getSize", ...args),
5016
+ getVisible: (...args) => invokePanoramaMethod("getVisible", ...args),
5017
+ getZoom: (...args) => invokePanoramaMethod("getZoom", ...args),
5018
+ setOptions: (...args) => invokePanoramaMethod("setOptions", ...args),
5019
+ setPanoId: (...args) => invokePanoramaMethod("setPanoId", ...args),
5020
+ setPanoIdWithPov: (...args) => invokePanoramaMethod("setPanoIdWithPov", ...args),
5021
+ setPosition: (...args) => invokePanoramaMethod("setPosition", ...args),
5022
+ setPov: (...args) => invokePanoramaMethod("setPov", ...args),
5023
+ setScale: (...args) => invokePanoramaMethod("setScale", ...args),
5024
+ setSize: (...args) => invokePanoramaMethod("setSize", ...args),
5025
+ setVisible: (...args) => invokePanoramaMethod("setVisible", ...args),
5026
+ setZoom: (...args) => invokePanoramaMethod("setZoom", ...args),
5027
+ zoomIn: (...args) => invokePanoramaMethod("zoomIn", ...args),
5028
+ zoomOut: (...args) => invokePanoramaMethod("zoomOut", ...args)
5029
+ }), [invokePanoramaMethod]);
5030
+ (0, react.useEffect)(() => {
5031
+ if (sdkStatus !== "ready" || !containerRef.current || panoramaRef.current) return;
5032
+ const container = containerRef.current;
5033
+ try {
5034
+ const initOpts = toPanoramaOptions(propsRef.current, true, true);
5035
+ if (initialPositionRef.current !== void 0) initOpts.position = toLatLng(initialPositionRef.current);
5036
+ if (initialPovRef.current !== void 0) initOpts.pov = initialPovRef.current;
5037
+ const panorama = new naver.maps.Panorama(container, initOpts);
5038
+ panoramaRef.current = panorama;
5039
+ setPanoramaInstance(panorama);
5040
+ setPanoramaReady(true);
5041
+ bindPanoramaEventListeners(panorama, eventListenersRef, buildPanoramaEventBindings(propsRef.current));
5042
+ propsRef.current.onPanoramaReady?.(panorama);
5043
+ } catch (error) {
5044
+ console.error("[Panorama] Failed to create panorama:", error);
5045
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Panorama instance.");
5046
+ propsRef.current.onPanoramaError?.(normalizedError);
5047
+ }
5048
+ }, [sdkStatus]);
5049
+ (0, react.useEffect)(() => {
5050
+ return () => {
5051
+ const container = containerRef.current;
5052
+ try {
5053
+ if (eventListenersRef.current.length > 0) {
5054
+ naver.maps.Event.removeListener(eventListenersRef.current);
5055
+ eventListenersRef.current = [];
5056
+ }
5057
+ if (panoramaRef.current) naver.maps.Event.clearInstanceListeners(panoramaRef.current);
5058
+ } catch (error) {
5059
+ console.error("[react-naver-maps-kit] failed to clear panorama listeners", error);
5060
+ }
5061
+ if (container) container.innerHTML = "";
5062
+ panoramaRef.current = null;
5063
+ setPanoramaInstance(null);
5064
+ setPanoramaReady(false);
5065
+ onPanoramaDestroyRef.current?.();
5066
+ };
5067
+ }, []);
5068
+ (0, react.useEffect)(() => {
5069
+ const panorama = panoramaRef.current;
5070
+ if (!panorama) return;
5071
+ if (Object.keys(optionsSnapshot).length > 0) panorama.setOptions(optionsSnapshot);
5072
+ }, [optionsSnapshot]);
5073
+ (0, react.useEffect)(() => {
5074
+ const panorama = panoramaRef.current;
5075
+ if (!panorama || !isControlledPosition || props.position === void 0) return;
5076
+ panorama.setPosition(toLatLng(props.position));
5077
+ }, [isControlledPosition, props.position]);
5078
+ (0, react.useEffect)(() => {
5079
+ const panorama = panoramaRef.current;
5080
+ if (!panorama || !isControlledPov || props.pov === void 0) return;
5081
+ panorama.setPov(props.pov);
5082
+ }, [isControlledPov, props.pov]);
5083
+ const panoramaContextValue = (0, react.useMemo)(() => ({
5084
+ panorama: panoramaInstance,
5085
+ setPanorama: setPanoramaInstance,
5086
+ sdkStatus,
5087
+ submodules
5088
+ }), [
5089
+ panoramaInstance,
5090
+ sdkStatus,
5091
+ submodules
5092
+ ]);
5093
+ const mapInstanceContextValue = (0, react.useMemo)(() => ({
5094
+ instance: panoramaInstance,
5095
+ setInstance: setPanoramaInstance,
5096
+ type: "panorama"
5097
+ }), [panoramaInstance]);
5098
+ const naverMapContextValue = (0, react.useMemo)(() => ({
5099
+ ...context,
5100
+ map: panoramaInstance,
5101
+ setMap: setPanoramaInstance
5102
+ }), [context, panoramaInstance]);
5103
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NaverMapContext.Provider, {
5104
+ value: naverMapContextValue,
5105
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MapInstanceContext.Provider, {
5106
+ value: mapInstanceContextValue,
5107
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanoramaContext.Provider, {
5108
+ value: panoramaContextValue,
5109
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5110
+ ref: containerRef,
5111
+ style: props.style,
5112
+ className: props.className,
5113
+ children: panoramaReady ? props.children : null
5114
+ })
5115
+ })
5116
+ })
5117
+ });
5118
+ });
5119
+ Panorama.displayName = "Panorama";
5120
+
5121
+ //#endregion
5122
+ //#region src/submodules/panorama/FlightSpot.tsx
5123
+ const FlightSpot = (0, react.forwardRef)(function FlightSpotInner(props, ref) {
5124
+ const { sdkStatus, submodules } = useNaverMap();
5125
+ const contextMap = useMapInstance()?.instance;
5126
+ let panoramaContext = null;
5127
+ try {
5128
+ panoramaContext = usePanorama();
5129
+ } catch {}
5130
+ const flightSpotRef = (0, react.useRef)(null);
5131
+ const eventListenersRef = (0, react.useRef)([]);
5132
+ const onFlightSpotDestroyRef = (0, react.useRef)(props.onFlightSpotDestroy);
5133
+ const targetMap = props.map ?? panoramaContext?.panorama ?? contextMap;
5134
+ const isInPanorama = panoramaContext !== null;
5135
+ const effectiveSubmodules = panoramaContext?.submodules ?? submodules;
5136
+ if (sdkStatus === "ready" && effectiveSubmodules && !effectiveSubmodules.includes("panorama")) throw new Error("FlightSpot component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
5137
+ const propsRef = (0, react.useRef)(props);
5138
+ (0, react.useEffect)(() => {
5139
+ propsRef.current = props;
5140
+ });
5141
+ (0, react.useEffect)(() => {
5142
+ onFlightSpotDestroyRef.current = props.onFlightSpotDestroy;
5143
+ }, [props.onFlightSpotDestroy]);
5144
+ const invokeFlightSpotMethod = (0, react.useCallback)((methodName, ...args) => {
5145
+ const flightSpot = flightSpotRef.current;
5146
+ if (!flightSpot) return void 0;
5147
+ const method = flightSpot[methodName];
5148
+ if (typeof method !== "function") return void 0;
5149
+ return method.apply(flightSpot, args);
5150
+ }, []);
5151
+ const teardownFlightSpot = (0, react.useCallback)(() => {
5152
+ const flightSpot = flightSpotRef.current;
5153
+ if (!flightSpot) return;
5154
+ try {
5155
+ if (eventListenersRef.current.length > 0) {
5156
+ naver.maps.Event.removeListener(eventListenersRef.current);
5157
+ eventListenersRef.current = [];
5158
+ }
5159
+ naver.maps.Event.clearInstanceListeners(flightSpot);
5160
+ } catch (error) {
5161
+ console.error("[react-naver-maps-kit] failed to clear flightSpot listeners", error);
5162
+ }
5163
+ flightSpot.setMap(null);
5164
+ flightSpotRef.current = null;
5165
+ onFlightSpotDestroyRef.current?.();
5166
+ }, []);
5167
+ (0, react.useImperativeHandle)(ref, () => ({
5168
+ getInstance: () => flightSpotRef.current,
5169
+ getMap: (...args) => invokeFlightSpotMethod("getMap", ...args),
5170
+ setMap: (...args) => invokeFlightSpotMethod("setMap", ...args)
5171
+ }), [invokeFlightSpotMethod]);
5172
+ (0, react.useEffect)(() => {
5173
+ if (sdkStatus !== "ready" || flightSpotRef.current) return;
5174
+ if (isInPanorama && !panoramaContext?.panorama) return;
5175
+ try {
5176
+ const flightSpot = new naver.maps.FlightSpot();
5177
+ flightSpotRef.current = flightSpot;
5178
+ if (propsRef.current.onPoiClicked) {
5179
+ const listener = naver.maps.Event.addListener(flightSpot, "poi_clicked", (panoId) => {
5180
+ propsRef.current.onPoiClicked?.(panoId);
5181
+ });
5182
+ eventListenersRef.current.push(listener);
5183
+ }
5184
+ if (propsRef.current.visible !== false && targetMap) flightSpot.setMap(targetMap);
5185
+ propsRef.current.onFlightSpotReady?.(flightSpot);
5186
+ } catch (error) {
5187
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.FlightSpot instance.");
5188
+ propsRef.current.onFlightSpotError?.(normalizedError);
5189
+ }
5190
+ }, [
5191
+ sdkStatus,
5192
+ isInPanorama,
5193
+ panoramaContext?.panorama,
5194
+ targetMap
5195
+ ]);
5196
+ (0, react.useEffect)(() => {
5197
+ const flightSpot = flightSpotRef.current;
5198
+ if (!flightSpot) return;
5199
+ if (props.visible === false) flightSpot.setMap(null);
5200
+ else if (targetMap) flightSpot.setMap(targetMap);
5201
+ }, [props.visible, targetMap]);
5202
+ (0, react.useEffect)(() => {
5203
+ return () => {
5204
+ teardownFlightSpot();
5205
+ };
5206
+ }, [teardownFlightSpot]);
5207
+ return null;
5208
+ });
5209
+ FlightSpot.displayName = "FlightSpot";
5210
+
5211
+ //#endregion
5212
+ //#region src/submodules/panorama/AroundControl.tsx
5213
+ const AroundControl = (0, react.forwardRef)(function AroundControlInner(props, ref) {
5214
+ const { panorama, sdkStatus, submodules } = usePanorama();
5215
+ if (sdkStatus === "ready" && !submodules.includes("panorama")) throw new Error("AroundControl component requires \"panorama\" submodule. Add submodules={[\"panorama\"]} to your NaverMapProvider.");
5216
+ const aroundControlRef = (0, react.useRef)(null);
5217
+ const onAroundControlDestroyRef = (0, react.useRef)(props.onAroundControlDestroy);
5218
+ const propsRef = (0, react.useRef)(props);
5219
+ (0, react.useEffect)(() => {
5220
+ propsRef.current = props;
5221
+ });
5222
+ (0, react.useEffect)(() => {
5223
+ onAroundControlDestroyRef.current = props.onAroundControlDestroy;
5224
+ }, [props.onAroundControlDestroy]);
5225
+ const invokeAroundControlMethod = (0, react.useCallback)((methodName, ...args) => {
5226
+ const aroundControl = aroundControlRef.current;
5227
+ if (!aroundControl) return void 0;
5228
+ const method = aroundControl[methodName];
5229
+ if (typeof method !== "function") return void 0;
5230
+ return method.apply(aroundControl, args);
5231
+ }, []);
5232
+ const teardownAroundControl = (0, react.useCallback)(() => {
5233
+ const aroundControl = aroundControlRef.current;
5234
+ if (!aroundControl) return;
5235
+ try {
5236
+ naver.maps.Event.clearInstanceListeners(aroundControl);
5237
+ } catch (error) {
5238
+ console.error("[react-naver-maps-kit] failed to clear aroundControl listeners", error);
5239
+ }
5240
+ aroundControl.setMap(null);
5241
+ aroundControlRef.current = null;
5242
+ onAroundControlDestroyRef.current?.();
5243
+ }, []);
5244
+ (0, react.useImperativeHandle)(ref, () => ({
5245
+ getInstance: () => aroundControlRef.current,
5246
+ getElement: (...args) => invokeAroundControlMethod("getElement", ...args),
5247
+ getMap: (...args) => invokeAroundControlMethod("getMap", ...args),
5248
+ getOptions: (...args) => invokeAroundControlMethod("getOptions", ...args),
5249
+ html: (...args) => invokeAroundControlMethod("html", ...args),
5250
+ setMap: (...args) => invokeAroundControlMethod("setMap", ...args),
5251
+ setOptions: (...args) => invokeAroundControlMethod("setOptions", ...args),
5252
+ setPosition: (...args) => invokeAroundControlMethod("setPosition", ...args)
5253
+ }), [invokeAroundControlMethod]);
5254
+ (0, react.useEffect)(() => {
5255
+ if (sdkStatus !== "ready" || !panorama || aroundControlRef.current) return;
5256
+ try {
5257
+ const options = { position: propsRef.current.position ?? naver.maps.Position.TOP_RIGHT };
5258
+ const aroundControl = new naver.maps.AroundControl(options);
5259
+ aroundControlRef.current = aroundControl;
5260
+ if (propsRef.current.visible !== false) aroundControl.setMap(panorama);
5261
+ propsRef.current.onAroundControlReady?.(aroundControl);
5262
+ } catch (error) {
5263
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.AroundControl instance.");
5264
+ propsRef.current.onAroundControlError?.(normalizedError);
5265
+ }
5266
+ }, [sdkStatus, panorama]);
5267
+ (0, react.useEffect)(() => {
5268
+ const aroundControl = aroundControlRef.current;
5269
+ if (!aroundControl || !panorama) return;
5270
+ const ctrl = aroundControl;
5271
+ if (props.visible === false) ctrl.setMap(null);
5272
+ else {
5273
+ ctrl.setMap(panorama);
5274
+ if (props.position !== void 0) aroundControl.setPosition(props.position);
5275
+ }
5276
+ }, [
5277
+ props.visible,
5278
+ props.position,
5279
+ panorama
5280
+ ]);
5281
+ (0, react.useEffect)(() => {
5282
+ return () => {
5283
+ teardownAroundControl();
5284
+ };
5285
+ }, [teardownAroundControl]);
5286
+ return null;
5287
+ });
5288
+ AroundControl.displayName = "AroundControl";
5289
+
5290
+ //#endregion
5291
+ //#region src/submodules/visualization/HeatMap.tsx
5292
+ const HeatMap = (0, react.forwardRef)(function HeatMap({ data, opacity, radius, colorMap, colorMapReverse, onHeatMapReady }, ref) {
5293
+ const map = useMap();
5294
+ const heatMapRef = (0, react.useRef)(null);
5295
+ const onHeatMapReadyRef = (0, react.useRef)(onHeatMapReady);
5296
+ onHeatMapReadyRef.current = onHeatMapReady;
5297
+ const normalizeData = (0, react.useCallback)((inputData) => {
5298
+ if (!inputData || inputData.length === 0) return [];
5299
+ const first = inputData[0];
5300
+ if (first instanceof naver.maps.LatLng) return inputData;
5301
+ if (first instanceof naver.maps.visualization.WeightedLocation) return inputData;
5302
+ if (Array.isArray(first)) return inputData;
5303
+ if (typeof first === "object" && "lat" in first && "lng" in first) {
5304
+ const items = inputData;
5305
+ if (items.some((item) => item.weight !== void 0)) return items.map((item) => new naver.maps.visualization.WeightedLocation(item.lat, item.lng, item.weight ?? 1));
5306
+ return items.map((item) => new naver.maps.LatLng(item.lat, item.lng));
5307
+ }
5308
+ return inputData;
5309
+ }, []);
5310
+ (0, react.useImperativeHandle)(ref, () => ({
5311
+ getInstance: () => heatMapRef.current,
5312
+ getMap: () => heatMapRef.current?.getMap() ?? null,
5313
+ setData: (newData) => {
5314
+ heatMapRef.current?.setData(newData);
5315
+ },
5316
+ addData: (newData) => {
5317
+ heatMapRef.current?.addData(newData);
5318
+ },
5319
+ redraw: () => {
5320
+ heatMapRef.current?.redraw();
5321
+ }
5322
+ }), []);
5323
+ (0, react.useEffect)(() => {
5324
+ if (!map) return;
5325
+ if (typeof naver.maps.visualization?.HeatMap !== "function") {
5326
+ console.warn("[HeatMap] visualization 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['visualization']}을 추가하세요.");
5327
+ return;
5328
+ }
5329
+ let heatMap = null;
5330
+ let listener = null;
5331
+ const createHeatMap = () => {
5332
+ if (heatMapRef.current) return;
5333
+ const normalizedData = normalizeData(data);
5334
+ heatMap = new naver.maps.visualization.HeatMap({
5335
+ map,
5336
+ data: normalizedData,
5337
+ opacity: opacity ?? .6,
5338
+ radius: radius ?? 20,
5339
+ colorMap,
5340
+ colorMapReverse: colorMapReverse ?? false
5341
+ });
5342
+ heatMapRef.current = heatMap;
5343
+ onHeatMapReadyRef.current?.(heatMap);
5344
+ };
5345
+ if (map.isReady) createHeatMap();
5346
+ else listener = naver.maps.Event.addListener(map, "init", createHeatMap);
5347
+ return () => {
5348
+ if (listener) naver.maps.Event.removeListener(listener);
5349
+ if (heatMap) heatMap.setMap(null);
5350
+ heatMapRef.current = null;
5351
+ };
5352
+ }, [map]);
5353
+ (0, react.useEffect)(() => {
5354
+ if (!heatMapRef.current) return;
5355
+ const normalizedData = normalizeData(data);
5356
+ heatMapRef.current.setData(normalizedData);
5357
+ heatMapRef.current.redraw();
5358
+ }, [data, normalizeData]);
5359
+ (0, react.useEffect)(() => {
5360
+ if (!heatMapRef.current || opacity === void 0) return;
5361
+ heatMapRef.current.setOptions({ opacity });
5362
+ heatMapRef.current.redraw();
5363
+ }, [opacity]);
5364
+ (0, react.useEffect)(() => {
5365
+ if (!heatMapRef.current || radius === void 0) return;
5366
+ heatMapRef.current.setOptions({ radius });
5367
+ heatMapRef.current.redraw();
5368
+ }, [radius]);
5369
+ (0, react.useEffect)(() => {
5370
+ if (!heatMapRef.current || colorMap === void 0) return;
5371
+ heatMapRef.current.setOptions({
5372
+ colorMap,
5373
+ colorMapReverse: colorMapReverse ?? false
5374
+ });
5375
+ heatMapRef.current.redraw();
5376
+ }, [colorMap, colorMapReverse]);
5377
+ return null;
5378
+ });
5379
+
5380
+ //#endregion
5381
+ //#region src/submodules/visualization/DotMap.tsx
5382
+ const DotMap = (0, react.forwardRef)(function DotMap({ data, opacity, radius, strokeWeight, strokeColor, strokeLineCap, strokeLineJoin, fillColor, onDotMapReady }, ref) {
5383
+ const map = useMap();
5384
+ const dotMapRef = (0, react.useRef)(null);
5385
+ const onDotMapReadyRef = (0, react.useRef)(onDotMapReady);
5386
+ onDotMapReadyRef.current = onDotMapReady;
5387
+ const normalizeData = (0, react.useCallback)((inputData) => {
5388
+ if (!inputData || inputData.length === 0) return [];
5389
+ const first = inputData[0];
5390
+ if (first instanceof naver.maps.LatLng) return inputData;
5391
+ if (Array.isArray(first)) return inputData;
5392
+ if (typeof first === "object" && "lat" in first && "lng" in first) return inputData.map((item) => new naver.maps.LatLng(item.lat, item.lng));
5393
+ return inputData;
5394
+ }, []);
5395
+ (0, react.useImperativeHandle)(ref, () => ({
5396
+ getInstance: () => dotMapRef.current,
5397
+ getMap: () => dotMapRef.current?.getMap() ?? null,
5398
+ setData: (newData) => {
5399
+ dotMapRef.current?.setData(newData);
5400
+ },
5401
+ addData: (newData) => {
5402
+ dotMapRef.current?.addData(newData);
5403
+ },
5404
+ redraw: () => {
5405
+ dotMapRef.current?.redraw();
5406
+ }
5407
+ }), []);
5408
+ (0, react.useEffect)(() => {
5409
+ if (!map) return;
5410
+ if (typeof naver.maps.visualization?.DotMap !== "function") {
5411
+ console.warn("[DotMap] visualization 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['visualization']}을 추가하세요.");
5412
+ return;
5413
+ }
5414
+ let dotMap = null;
5415
+ let listener = null;
5416
+ const createDotMap = () => {
5417
+ if (dotMapRef.current) return;
5418
+ const normalizedData = normalizeData(data);
5419
+ dotMap = new naver.maps.visualization.DotMap({
5420
+ map,
5421
+ data: normalizedData,
5422
+ opacity: opacity ?? .6,
5423
+ radius: radius ?? 5,
5424
+ strokeWeight: strokeWeight ?? 1,
5425
+ strokeColor: strokeColor ?? "#fff",
5426
+ strokeLineCap: strokeLineCap ?? "round",
5427
+ strokeLineJoin: strokeLineJoin ?? "round",
5428
+ fillColor: fillColor ?? "#ff0000"
5429
+ });
5430
+ dotMapRef.current = dotMap;
5431
+ onDotMapReadyRef.current?.(dotMap);
5432
+ };
5433
+ if (map.isReady) createDotMap();
5434
+ else listener = naver.maps.Event.addListener(map, "init", createDotMap);
5435
+ return () => {
5436
+ if (listener) naver.maps.Event.removeListener(listener);
5437
+ if (dotMap) dotMap.setMap(null);
5438
+ dotMapRef.current = null;
5439
+ };
5440
+ }, [map]);
5441
+ (0, react.useEffect)(() => {
5442
+ if (!dotMapRef.current) return;
5443
+ const normalizedData = normalizeData(data);
5444
+ dotMapRef.current.setData(normalizedData);
5445
+ dotMapRef.current.redraw();
5446
+ }, [data, normalizeData]);
5447
+ (0, react.useEffect)(() => {
5448
+ if (!dotMapRef.current || opacity === void 0) return;
5449
+ dotMapRef.current.setOptions({ opacity });
5450
+ dotMapRef.current.redraw();
5451
+ }, [opacity]);
5452
+ (0, react.useEffect)(() => {
5453
+ if (!dotMapRef.current || radius === void 0) return;
5454
+ dotMapRef.current.setOptions({ radius });
5455
+ dotMapRef.current.redraw();
5456
+ }, [radius]);
5457
+ (0, react.useEffect)(() => {
5458
+ if (!dotMapRef.current) return;
5459
+ dotMapRef.current.setOptions({
5460
+ strokeWeight,
5461
+ strokeColor,
5462
+ strokeLineCap,
5463
+ strokeLineJoin,
5464
+ fillColor
5465
+ });
5466
+ dotMapRef.current.redraw();
5467
+ }, [
5468
+ strokeWeight,
5469
+ strokeColor,
5470
+ strokeLineCap,
5471
+ strokeLineJoin,
5472
+ fillColor
5473
+ ]);
5474
+ return null;
5475
+ });
5476
+
5477
+ //#endregion
5478
+ //#region src/submodules/drawing/DrawingManager.tsx
5479
+ const DrawingManager = (0, react.forwardRef)(function DrawingManager({ drawingControl, drawingControlOptions, drawingMode, controlPointOptions, rectangleOptions, ellipseOptions, polylineOptions, arrowlineOptions, polygonOptions, markerOptions, onDrawingAdded, onDrawingRemoved, onDrawingSelect, onDrawingStart, onDrawingCanceled, onDrawingManagerReady }, ref) {
5480
+ const map = useMap();
5481
+ const managerRef = (0, react.useRef)(null);
5482
+ const listenersRef = (0, react.useRef)([]);
5483
+ const onDrawingManagerReadyRef = (0, react.useRef)(onDrawingManagerReady);
5484
+ onDrawingManagerReadyRef.current = onDrawingManagerReady;
5485
+ const eventPropsRef = (0, react.useRef)({
5486
+ onDrawingAdded,
5487
+ onDrawingRemoved,
5488
+ onDrawingSelect,
5489
+ onDrawingStart,
5490
+ onDrawingCanceled
5491
+ });
5492
+ eventPropsRef.current = {
5493
+ onDrawingAdded,
5494
+ onDrawingRemoved,
5495
+ onDrawingSelect,
5496
+ onDrawingStart,
5497
+ onDrawingCanceled
5498
+ };
5499
+ (0, react.useImperativeHandle)(ref, () => ({
5500
+ getInstance: () => managerRef.current,
5501
+ getMap: () => managerRef.current?.getMap() ?? null,
5502
+ getDrawings: () => managerRef.current?.getDrawings() ?? {},
5503
+ getDrawing: (id) => managerRef.current?.getDrawing(id),
5504
+ addDrawing: (overlay, mode, id) => {
5505
+ managerRef.current?.addDrawing(overlay, mode, id);
5506
+ },
5507
+ removeDrawing: (overlayOrId) => {
5508
+ managerRef.current?.removeDrawing(overlayOrId);
5509
+ },
5510
+ toGeoJson: () => managerRef.current?.toGeoJson() ?? {},
5511
+ setDrawingMode: (mode) => {
5512
+ managerRef.current?.setOptions({ drawingMode: mode });
5513
+ },
5514
+ getDrawingMode: () => {
5515
+ return managerRef.current?.getOptions("drawingMode");
5516
+ }
5517
+ }), []);
5518
+ (0, react.useEffect)(() => {
5519
+ if (!map) return;
5520
+ if (typeof naver.maps.drawing?.DrawingManager !== "function") {
5521
+ console.warn("[DrawingManager] drawing 서브모듈이 로드되지 않았습니다. NaverMapProvider에 submodules={['drawing']}을 추가하세요.");
5522
+ return;
5523
+ }
5524
+ let manager = null;
5525
+ const createManager = () => {
5526
+ if (managerRef.current) return;
5527
+ const options = { map };
5528
+ if (drawingControl !== void 0) options.drawingControl = drawingControl;
5529
+ if (drawingControlOptions) options.drawingControlOptions = drawingControlOptions;
5530
+ if (drawingMode) options.drawingMode = drawingMode;
5531
+ if (controlPointOptions) options.controlPointOptions = controlPointOptions;
5532
+ if (rectangleOptions) options.rectangleOptions = rectangleOptions;
5533
+ if (ellipseOptions) options.ellipseOptions = ellipseOptions;
5534
+ if (polylineOptions) options.polylineOptions = polylineOptions;
5535
+ if (arrowlineOptions) options.arrowlineOptions = arrowlineOptions;
5536
+ if (polygonOptions) options.polygonOptions = polygonOptions;
5537
+ if (markerOptions) options.markerOptions = markerOptions;
5538
+ manager = new naver.maps.drawing.DrawingManager(options);
5539
+ managerRef.current = manager;
5540
+ const listeners = [];
5541
+ const addedListener = manager.addListener(naver.maps.drawing.DrawingEvents.ADD, (overlay) => {
5542
+ eventPropsRef.current.onDrawingAdded?.(overlay);
5543
+ });
5544
+ listeners.push(addedListener);
5545
+ const removedListener = manager.addListener(naver.maps.drawing.DrawingEvents.REMOVE, (overlay) => {
5546
+ eventPropsRef.current.onDrawingRemoved?.(overlay);
5547
+ });
5548
+ listeners.push(removedListener);
5549
+ const selectListener = manager.addListener(naver.maps.drawing.DrawingEvents.SELECT, (overlay) => {
5550
+ eventPropsRef.current.onDrawingSelect?.(overlay);
5551
+ });
5552
+ listeners.push(selectListener);
5553
+ const startListener = manager.addListener(naver.maps.drawing.DrawingEvents.START, (overlay) => {
5554
+ eventPropsRef.current.onDrawingStart?.(overlay);
5555
+ });
5556
+ listeners.push(startListener);
5557
+ const canceledListener = manager.addListener(naver.maps.drawing.DrawingEvents.CANCLE, (overlay) => {
5558
+ eventPropsRef.current.onDrawingCanceled?.(overlay);
5559
+ });
5560
+ listeners.push(canceledListener);
5561
+ listenersRef.current = listeners;
5562
+ onDrawingManagerReadyRef.current?.(manager);
5563
+ };
5564
+ if (map.isReady) createManager();
5565
+ else {
5566
+ const listener = naver.maps.Event.addListener(map, "init", createManager);
5567
+ return () => {
5568
+ naver.maps.Event.removeListener(listener);
5569
+ listenersRef.current.forEach((l) => naver.maps.Event.removeListener(l));
5570
+ if (manager) manager.destroy();
5571
+ managerRef.current = null;
5572
+ };
5573
+ }
5574
+ return () => {
5575
+ listenersRef.current.forEach((l) => naver.maps.Event.removeListener(l));
5576
+ if (manager) manager.destroy();
5577
+ managerRef.current = null;
5578
+ };
5579
+ }, [map]);
5580
+ (0, react.useEffect)(() => {
5581
+ if (!managerRef.current || drawingMode === void 0) return;
5582
+ managerRef.current.setOptions({ drawingMode });
5583
+ }, [drawingMode]);
5584
+ return null;
5585
+ });
5586
+
4800
5587
  //#endregion
4801
5588
  //#region src/index.ts
4802
- const version = "1.2.0";
5589
+ const version = "1.3.0";
4803
5590
 
4804
5591
  //#endregion
5592
+ exports.AroundControl = AroundControl;
4805
5593
  exports.Circle = Circle;
4806
5594
  exports.ClustererContext = ClustererContext;
5595
+ exports.DotMap = DotMap;
5596
+ exports.DrawingManager = DrawingManager;
4807
5597
  exports.Ellipse = Ellipse;
5598
+ exports.FlightSpot = FlightSpot;
4808
5599
  exports.GeoJson = GeoJson;
4809
5600
  exports.Gpx = Gpx;
4810
5601
  exports.GroundOverlay = GroundOverlay;
5602
+ exports.HeatMap = HeatMap;
4811
5603
  exports.InfoWindow = InfoWindow;
4812
5604
  exports.Kmz = Kmz;
5605
+ exports.MapInstanceContext = MapInstanceContext;
4813
5606
  exports.Marker = Marker;
4814
5607
  exports.MarkerClusterer = MarkerClusterer;
4815
5608
  exports.NaverMap = NaverMap;
4816
5609
  exports.NaverMapContext = NaverMapContext;
4817
5610
  exports.NaverMapProvider = NaverMapProvider;
5611
+ exports.Panorama = Panorama;
5612
+ exports.PanoramaContext = PanoramaContext;
4818
5613
  exports.Polygon = Polygon;
4819
5614
  exports.Polyline = Polyline;
4820
5615
  exports.Rectangle = Rectangle;
4821
5616
  exports.loadNaverMapsScript = loadNaverMapsScript;
5617
+ exports.useMap = useMap;
5618
+ exports.useMapInstance = useMapInstance;
5619
+ exports.useMapInstanceRequired = useMapInstanceRequired;
4822
5620
  exports.useNaverMap = useNaverMap;
4823
5621
  exports.useNaverMapInstance = useNaverMapInstance;
5622
+ exports.usePanorama = usePanorama;
5623
+ exports.usePanoramaInstance = usePanoramaInstance;
4824
5624
  exports.version = version;
4825
5625
  //# sourceMappingURL=index.cjs.map