react-naver-maps-kit 1.0.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 (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +330 -0
  3. package/dist/core/loader/loadNaverMapsScript.d.ts +13 -0
  4. package/dist/core/loader/loadNaverMapsScript.d.ts.map +1 -0
  5. package/dist/index.cjs +2646 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.ts +36 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +2631 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/overlays/circle/Circle.d.ts +79 -0
  12. package/dist/overlays/circle/Circle.d.ts.map +1 -0
  13. package/dist/overlays/ellipse/Ellipse.d.ts +74 -0
  14. package/dist/overlays/ellipse/Ellipse.d.ts.map +1 -0
  15. package/dist/overlays/ground-overlay/GroundOverlay.d.ts +46 -0
  16. package/dist/overlays/ground-overlay/GroundOverlay.d.ts.map +1 -0
  17. package/dist/overlays/infowindow/InfoWindow.d.ts +67 -0
  18. package/dist/overlays/infowindow/InfoWindow.d.ts.map +1 -0
  19. package/dist/overlays/marker/Marker.d.ts +81 -0
  20. package/dist/overlays/marker/Marker.d.ts.map +1 -0
  21. package/dist/overlays/polygon/Polygon.d.ts +78 -0
  22. package/dist/overlays/polygon/Polygon.d.ts.map +1 -0
  23. package/dist/overlays/polyline/Polyline.d.ts +79 -0
  24. package/dist/overlays/polyline/Polyline.d.ts.map +1 -0
  25. package/dist/overlays/rectangle/Rectangle.d.ts +74 -0
  26. package/dist/overlays/rectangle/Rectangle.d.ts.map +1 -0
  27. package/dist/overlays/shared/overlayUtils.d.ts +9 -0
  28. package/dist/overlays/shared/overlayUtils.d.ts.map +1 -0
  29. package/dist/react/components/NaverMap.d.ts +137 -0
  30. package/dist/react/components/NaverMap.d.ts.map +1 -0
  31. package/dist/react/components/NaverMap.test.d.ts +2 -0
  32. package/dist/react/components/NaverMap.test.d.ts.map +1 -0
  33. package/dist/react/hooks/useNaverMap.d.ts +10 -0
  34. package/dist/react/hooks/useNaverMap.d.ts.map +1 -0
  35. package/dist/react/provider/NaverMapProvider.d.ts +21 -0
  36. package/dist/react/provider/NaverMapProvider.d.ts.map +1 -0
  37. package/package.json +84 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,2646 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let react = require("react");
3
+ let react_jsx_runtime = require("react/jsx-runtime");
4
+ let react_dom = require("react-dom");
5
+
6
+ //#region src/core/loader/loadNaverMapsScript.ts
7
+ const NAVER_MAPS_SCRIPT_BASE_URL = "https://oapi.map.naver.com/openapi/v3/maps.js";
8
+ let inFlightLoad = null;
9
+ let inFlightScriptUrl = null;
10
+ function getClientKey(options) {
11
+ if (options.ncpKeyId) return {
12
+ param: "ncpKeyId",
13
+ value: options.ncpKeyId
14
+ };
15
+ const legacy = [
16
+ {
17
+ param: "ncpClientId",
18
+ value: options.ncpClientId
19
+ },
20
+ {
21
+ param: "govClientId",
22
+ value: options.govClientId
23
+ },
24
+ {
25
+ param: "finClientId",
26
+ value: options.finClientId
27
+ }
28
+ ].find((candidate) => Boolean(candidate.value));
29
+ if (legacy?.value) return {
30
+ param: legacy.param,
31
+ value: legacy.value
32
+ };
33
+ throw new Error("loadNaverMapsScript requires ncpKeyId. For backward compatibility, ncpClientId, govClientId, or finClientId can be provided.");
34
+ }
35
+ function isNaverMapsReady() {
36
+ if (typeof window === "undefined") return false;
37
+ const browserWindow = window;
38
+ return Boolean(browserWindow.naver?.maps);
39
+ }
40
+ function createScriptUrl(options) {
41
+ const clientKey = getClientKey(options);
42
+ const params = new URLSearchParams();
43
+ params.set(clientKey.param, clientKey.value);
44
+ if (options.submodules && options.submodules.length > 0) params.set("submodules", options.submodules.join(","));
45
+ return `${NAVER_MAPS_SCRIPT_BASE_URL}?${params.toString()}`;
46
+ }
47
+ function waitForNaverMapsReady(timeoutMs) {
48
+ return new Promise((resolve, reject) => {
49
+ if (isNaverMapsReady()) {
50
+ resolve();
51
+ return;
52
+ }
53
+ const startedAt = Date.now();
54
+ const intervalId = setInterval(() => {
55
+ if (isNaverMapsReady()) {
56
+ clearInterval(intervalId);
57
+ resolve();
58
+ return;
59
+ }
60
+ if (Date.now() - startedAt >= timeoutMs) {
61
+ clearInterval(intervalId);
62
+ reject(/* @__PURE__ */ new Error(`Timed out after ${timeoutMs}ms while waiting for window.naver.maps.`));
63
+ }
64
+ }, 50);
65
+ });
66
+ }
67
+ function attachAuthFailureHandler(reject) {
68
+ const browserWindow = window;
69
+ const previousAuthFailure = browserWindow.navermap_authFailure;
70
+ browserWindow.navermap_authFailure = () => {
71
+ reject(/* @__PURE__ */ new Error("Naver Maps authentication failed. Check your client key and allowed domains."));
72
+ if (previousAuthFailure) previousAuthFailure();
73
+ };
74
+ return () => {
75
+ browserWindow.navermap_authFailure = previousAuthFailure;
76
+ };
77
+ }
78
+ function loadNaverMapsScript(options) {
79
+ if (typeof window === "undefined" || typeof document === "undefined") return Promise.reject(/* @__PURE__ */ new Error("loadNaverMapsScript can only run in a browser environment."));
80
+ if (isNaverMapsReady()) return Promise.resolve();
81
+ const scriptUrl = createScriptUrl(options);
82
+ if (inFlightLoad && inFlightScriptUrl === scriptUrl) return inFlightLoad;
83
+ const existingScript = document.querySelector(`script[src="${scriptUrl}"]`);
84
+ if (existingScript) {
85
+ const trackedPromise = new Promise((resolve, reject) => {
86
+ const existingScriptWithState = existingScript;
87
+ const timeoutMs = options.timeoutMs ?? 1e4;
88
+ const restoreAuthFailure = attachAuthFailureHandler(reject);
89
+ const timeoutId = setTimeout(() => {
90
+ restoreAuthFailure();
91
+ reject(/* @__PURE__ */ new Error(`Timed out after ${timeoutMs}ms while waiting for Naver Maps script.`));
92
+ }, timeoutMs);
93
+ const cleanup = () => {
94
+ clearTimeout(timeoutId);
95
+ restoreAuthFailure();
96
+ };
97
+ const handleReady = () => {
98
+ waitForNaverMapsReady(timeoutMs).then(() => {
99
+ cleanup();
100
+ resolve();
101
+ }).catch((error) => {
102
+ cleanup();
103
+ reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Naver Maps is not ready."));
104
+ });
105
+ };
106
+ const onLoad = () => {
107
+ handleReady();
108
+ };
109
+ const onError = () => {
110
+ cleanup();
111
+ reject(/* @__PURE__ */ new Error("Failed to load Naver Maps script."));
112
+ };
113
+ if (existingScript.dataset.reactNaverMapsKitLoaded === "true") {
114
+ handleReady();
115
+ return;
116
+ }
117
+ if (existingScriptWithState.readyState === "loaded" || existingScriptWithState.readyState === "complete") {
118
+ handleReady();
119
+ return;
120
+ }
121
+ existingScript.addEventListener("load", onLoad, { once: true });
122
+ existingScript.addEventListener("error", onError, { once: true });
123
+ }).finally(() => {
124
+ inFlightLoad = null;
125
+ inFlightScriptUrl = null;
126
+ });
127
+ inFlightLoad = trackedPromise;
128
+ inFlightScriptUrl = scriptUrl;
129
+ return trackedPromise;
130
+ }
131
+ const trackedPromise = new Promise((resolve, reject) => {
132
+ const timeoutMs = options.timeoutMs ?? 1e4;
133
+ const script = document.createElement("script");
134
+ const restoreAuthFailure = attachAuthFailureHandler(reject);
135
+ const timeoutId = setTimeout(() => {
136
+ cleanup();
137
+ script.remove();
138
+ reject(/* @__PURE__ */ new Error(`Timed out after ${timeoutMs}ms while loading Naver Maps script.`));
139
+ }, timeoutMs);
140
+ const cleanup = () => {
141
+ script.removeEventListener("load", onLoad);
142
+ script.removeEventListener("error", onError);
143
+ clearTimeout(timeoutId);
144
+ restoreAuthFailure();
145
+ };
146
+ const onLoad = () => {
147
+ script.dataset.reactNaverMapsKitLoaded = "true";
148
+ waitForNaverMapsReady(timeoutMs).then(() => {
149
+ cleanup();
150
+ resolve();
151
+ }).catch((error) => {
152
+ cleanup();
153
+ reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Naver Maps is not ready."));
154
+ });
155
+ };
156
+ const onError = () => {
157
+ cleanup();
158
+ reject(/* @__PURE__ */ new Error("Failed to load Naver Maps script."));
159
+ };
160
+ script.src = scriptUrl;
161
+ script.setAttribute("data-react-naver-maps-kit", "true");
162
+ script.type = "text/javascript";
163
+ script.async = true;
164
+ script.defer = true;
165
+ if (options.nonce) script.nonce = options.nonce;
166
+ script.addEventListener("load", onLoad);
167
+ script.addEventListener("error", onError);
168
+ document.head.append(script);
169
+ }).finally(() => {
170
+ inFlightLoad = null;
171
+ inFlightScriptUrl = null;
172
+ });
173
+ inFlightLoad = trackedPromise;
174
+ inFlightScriptUrl = scriptUrl;
175
+ return trackedPromise;
176
+ }
177
+
178
+ //#endregion
179
+ //#region src/react/provider/NaverMapProvider.tsx
180
+ const NaverMapContext = (0, react.createContext)(null);
181
+ function NaverMapProvider({ children, autoLoad = true, onReady, onError, ncpKeyId, ncpClientId, govClientId, finClientId, submodules, timeoutMs, nonce }) {
182
+ const [sdkStatus, setSdkStatus] = (0, react.useState)("idle");
183
+ const [sdkError, setSdkError] = (0, react.useState)(null);
184
+ const [map, setMap] = (0, react.useState)(null);
185
+ const mountedRef = (0, react.useRef)(true);
186
+ const inFlightLoadRef = (0, react.useRef)(null);
187
+ (0, react.useEffect)(() => {
188
+ mountedRef.current = true;
189
+ return () => {
190
+ mountedRef.current = false;
191
+ };
192
+ }, []);
193
+ (0, react.useEffect)(() => {
194
+ if (typeof window === "undefined") return;
195
+ const browserWindow = window;
196
+ const previousAuthFailure = browserWindow.navermap_authFailure;
197
+ browserWindow.navermap_authFailure = () => {
198
+ const error = /* @__PURE__ */ new Error("Naver Maps authentication failed. Check key type (ncpKeyId) and allowed domain settings.");
199
+ if (mountedRef.current) {
200
+ setSdkStatus("error");
201
+ setSdkError(error);
202
+ }
203
+ onError?.(error);
204
+ if (previousAuthFailure) previousAuthFailure();
205
+ };
206
+ return () => {
207
+ browserWindow.navermap_authFailure = previousAuthFailure;
208
+ };
209
+ }, [onError]);
210
+ const reloadSdk = (0, react.useCallback)(async () => {
211
+ if (inFlightLoadRef.current) return inFlightLoadRef.current;
212
+ if (mountedRef.current) {
213
+ setSdkStatus("loading");
214
+ setSdkError(null);
215
+ }
216
+ const loadPromise = loadNaverMapsScript({
217
+ ncpKeyId,
218
+ ncpClientId,
219
+ govClientId,
220
+ finClientId,
221
+ submodules,
222
+ timeoutMs,
223
+ nonce
224
+ }).then(() => {
225
+ if (mountedRef.current) {
226
+ setSdkStatus("ready");
227
+ setSdkError(null);
228
+ }
229
+ onReady?.();
230
+ }).catch((error) => {
231
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to load Naver Maps SDK.");
232
+ if (mountedRef.current) {
233
+ setSdkStatus("error");
234
+ setSdkError(normalizedError);
235
+ }
236
+ onError?.(normalizedError);
237
+ throw normalizedError;
238
+ }).finally(() => {
239
+ inFlightLoadRef.current = null;
240
+ });
241
+ inFlightLoadRef.current = loadPromise;
242
+ return loadPromise;
243
+ }, [
244
+ finClientId,
245
+ govClientId,
246
+ ncpClientId,
247
+ ncpKeyId,
248
+ nonce,
249
+ onError,
250
+ onReady,
251
+ submodules,
252
+ timeoutMs
253
+ ]);
254
+ (0, react.useEffect)(() => {
255
+ if (!autoLoad) return;
256
+ reloadSdk().catch(() => void 0);
257
+ }, [autoLoad, reloadSdk]);
258
+ const clearSdkError = (0, react.useCallback)(() => {
259
+ if (mountedRef.current) {
260
+ setSdkError(null);
261
+ setSdkStatus((current) => current === "error" ? "idle" : current);
262
+ }
263
+ }, []);
264
+ const value = (0, react.useMemo)(() => ({
265
+ sdkStatus,
266
+ sdkError,
267
+ map,
268
+ setMap,
269
+ reloadSdk,
270
+ retrySdk: reloadSdk,
271
+ clearSdkError
272
+ }), [
273
+ clearSdkError,
274
+ map,
275
+ reloadSdk,
276
+ sdkError,
277
+ sdkStatus
278
+ ]);
279
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NaverMapContext.Provider, {
280
+ value,
281
+ children
282
+ });
283
+ }
284
+
285
+ //#endregion
286
+ //#region src/react/components/NaverMap.tsx
287
+ const MAP_OPTION_KEYS = [
288
+ "background",
289
+ "baseTileOpacity",
290
+ "bounds",
291
+ "center",
292
+ "zoom",
293
+ "disableDoubleClickZoom",
294
+ "disableDoubleTapZoom",
295
+ "disableKineticPan",
296
+ "disableTwoFingerTapZoom",
297
+ "draggable",
298
+ "keyboardShortcuts",
299
+ "logoControl",
300
+ "logoControlOptions",
301
+ "mapDataControl",
302
+ "mapDataControlOptions",
303
+ "mapTypeControl",
304
+ "mapTypeControlOptions",
305
+ "mapTypeId",
306
+ "mapTypes",
307
+ "maxBounds",
308
+ "maxZoom",
309
+ "minZoom",
310
+ "padding",
311
+ "pinchZoom",
312
+ "resizeOrigin",
313
+ "scaleControl",
314
+ "scaleControlOptions",
315
+ "scrollWheel",
316
+ "size",
317
+ "overlayZoomEffect",
318
+ "tileSpare",
319
+ "tileTransition",
320
+ "tileDuration",
321
+ "zoomControl",
322
+ "zoomControlOptions",
323
+ "zoomOrigin",
324
+ "blankTileImage",
325
+ "gl",
326
+ "customStyleId"
327
+ ];
328
+ const MAP_OPTION_KEY_SET = new Set(MAP_OPTION_KEYS);
329
+ const MAP_EVENT_PROP_KEY_SET = new Set([
330
+ "onAddLayer",
331
+ "onBoundsChanged",
332
+ "onCenterChanged",
333
+ "onCenterPointChanged",
334
+ "onClick",
335
+ "onDblClick",
336
+ "onDoubleTap",
337
+ "onDrag",
338
+ "onDragEnd",
339
+ "onDragStart",
340
+ "onIdle",
341
+ "onInit",
342
+ "onKeyDown",
343
+ "onKeyUp",
344
+ "onLongTap",
345
+ "onMapTypeChanged",
346
+ "onMapTypeIdChanged",
347
+ "onMouseDown",
348
+ "onMouseMove",
349
+ "onMouseOut",
350
+ "onMouseOver",
351
+ "onMouseUp",
352
+ "onPanning",
353
+ "onPinch",
354
+ "onPinchEnd",
355
+ "onPinchStart",
356
+ "onProjectionChanged",
357
+ "onRemoveLayer",
358
+ "onResize",
359
+ "onRightClick",
360
+ "onSingleTap",
361
+ "onTouchEnd",
362
+ "onTouchMove",
363
+ "onTouchStart",
364
+ "onTwoFingerTap",
365
+ "onWheel",
366
+ "onZoomChanged",
367
+ "onZooming",
368
+ "onZoomStart"
369
+ ]);
370
+ const MAP_EVENT_BINDINGS = [
371
+ {
372
+ prop: "onAddLayer",
373
+ eventName: "addLayer",
374
+ hasPayload: true
375
+ },
376
+ {
377
+ prop: "onBoundsChanged",
378
+ eventName: "bounds_changed",
379
+ hasPayload: true
380
+ },
381
+ {
382
+ prop: "onCenterChanged",
383
+ eventName: "center_changed",
384
+ hasPayload: true
385
+ },
386
+ {
387
+ prop: "onCenterPointChanged",
388
+ eventName: "centerPoint_changed",
389
+ hasPayload: true
390
+ },
391
+ {
392
+ prop: "onClick",
393
+ eventName: "click",
394
+ hasPayload: true
395
+ },
396
+ {
397
+ prop: "onDblClick",
398
+ eventName: "dblclick",
399
+ hasPayload: true
400
+ },
401
+ {
402
+ prop: "onDoubleTap",
403
+ eventName: "doubletap",
404
+ hasPayload: true
405
+ },
406
+ {
407
+ prop: "onDrag",
408
+ eventName: "drag",
409
+ hasPayload: true
410
+ },
411
+ {
412
+ prop: "onDragEnd",
413
+ eventName: "dragend",
414
+ hasPayload: true
415
+ },
416
+ {
417
+ prop: "onDragStart",
418
+ eventName: "dragstart",
419
+ hasPayload: true
420
+ },
421
+ {
422
+ prop: "onIdle",
423
+ eventName: "idle",
424
+ hasPayload: false
425
+ },
426
+ {
427
+ prop: "onInit",
428
+ eventName: "init",
429
+ hasPayload: false
430
+ },
431
+ {
432
+ prop: "onKeyDown",
433
+ eventName: "keydown",
434
+ hasPayload: true
435
+ },
436
+ {
437
+ prop: "onKeyUp",
438
+ eventName: "keyup",
439
+ hasPayload: true
440
+ },
441
+ {
442
+ prop: "onLongTap",
443
+ eventName: "longtap",
444
+ hasPayload: true
445
+ },
446
+ {
447
+ prop: "onMapTypeChanged",
448
+ eventName: "mapType_changed",
449
+ hasPayload: true
450
+ },
451
+ {
452
+ prop: "onMapTypeIdChanged",
453
+ eventName: "mapTypeId_changed",
454
+ hasPayload: true
455
+ },
456
+ {
457
+ prop: "onMouseDown",
458
+ eventName: "mousedown",
459
+ hasPayload: true
460
+ },
461
+ {
462
+ prop: "onMouseMove",
463
+ eventName: "mousemove",
464
+ hasPayload: true
465
+ },
466
+ {
467
+ prop: "onMouseOut",
468
+ eventName: "mouseout",
469
+ hasPayload: true
470
+ },
471
+ {
472
+ prop: "onMouseOver",
473
+ eventName: "mouseover",
474
+ hasPayload: true
475
+ },
476
+ {
477
+ prop: "onMouseUp",
478
+ eventName: "mouseup",
479
+ hasPayload: true
480
+ },
481
+ {
482
+ prop: "onPanning",
483
+ eventName: "panning",
484
+ hasPayload: false
485
+ },
486
+ {
487
+ prop: "onPinch",
488
+ eventName: "pinch",
489
+ hasPayload: true
490
+ },
491
+ {
492
+ prop: "onPinchEnd",
493
+ eventName: "pinchend",
494
+ hasPayload: true
495
+ },
496
+ {
497
+ prop: "onPinchStart",
498
+ eventName: "pinchstart",
499
+ hasPayload: true
500
+ },
501
+ {
502
+ prop: "onProjectionChanged",
503
+ eventName: "projection_changed",
504
+ hasPayload: true
505
+ },
506
+ {
507
+ prop: "onRemoveLayer",
508
+ eventName: "removeLayer",
509
+ hasPayload: true
510
+ },
511
+ {
512
+ prop: "onResize",
513
+ eventName: "resize",
514
+ hasPayload: false
515
+ },
516
+ {
517
+ prop: "onRightClick",
518
+ eventName: "rightclick",
519
+ hasPayload: true
520
+ },
521
+ {
522
+ prop: "onSingleTap",
523
+ eventName: "singletap",
524
+ hasPayload: true
525
+ },
526
+ {
527
+ prop: "onTouchEnd",
528
+ eventName: "touchend",
529
+ hasPayload: true
530
+ },
531
+ {
532
+ prop: "onTouchMove",
533
+ eventName: "touchmove",
534
+ hasPayload: true
535
+ },
536
+ {
537
+ prop: "onTouchStart",
538
+ eventName: "touchstart",
539
+ hasPayload: true
540
+ },
541
+ {
542
+ prop: "onTwoFingerTap",
543
+ eventName: "twofingertap",
544
+ hasPayload: true
545
+ },
546
+ {
547
+ prop: "onWheel",
548
+ eventName: "wheel",
549
+ hasPayload: true
550
+ },
551
+ {
552
+ prop: "onZoomChanged",
553
+ eventName: "zoom_changed",
554
+ hasPayload: true
555
+ },
556
+ {
557
+ prop: "onZooming",
558
+ eventName: "zooming",
559
+ hasPayload: false
560
+ },
561
+ {
562
+ prop: "onZoomStart",
563
+ eventName: "zoomstart",
564
+ hasPayload: false
565
+ }
566
+ ];
567
+ const NON_DIV_KEYS = new Set([
568
+ "onMapReady",
569
+ "onMapDestroy",
570
+ "onMapError",
571
+ "retryOnError",
572
+ "retryDelayMs",
573
+ "fallback",
574
+ "defaultCenter",
575
+ "defaultZoom",
576
+ "children"
577
+ ]);
578
+ function toCenterSignature(center) {
579
+ if (!center) return "";
580
+ if (typeof center === "object") {
581
+ const candidate = center;
582
+ const rawLat = candidate.lat;
583
+ const rawLng = candidate.lng;
584
+ const lat = typeof rawLat === "function" ? rawLat() : rawLat;
585
+ const lng = typeof rawLng === "function" ? rawLng() : rawLng;
586
+ if (typeof lat === "number" && typeof lng === "number") return `latlng:${lat},${lng}`;
587
+ const rawX = candidate.x;
588
+ const rawY = candidate.y;
589
+ const x = typeof rawX === "function" ? rawX() : rawX;
590
+ const y = typeof rawY === "function" ? rawY() : rawY;
591
+ if (typeof x === "number" && typeof y === "number") return `xy:${x},${y}`;
592
+ }
593
+ return String(center);
594
+ }
595
+ function areValuesEqual(left, right) {
596
+ if (left === right) return true;
597
+ if (left === null || right === null || left === void 0 || right === void 0) return false;
598
+ if (typeof left === "object" && typeof right === "object") {
599
+ const leftCenter = toCenterSignature(left);
600
+ const rightCenter = toCenterSignature(right);
601
+ if (leftCenter !== "" && rightCenter !== "") return leftCenter === rightCenter;
602
+ return JSON.stringify(left) === JSON.stringify(right);
603
+ }
604
+ return false;
605
+ }
606
+ function getChangedOptions(previous, next) {
607
+ const keys = new Set([...Object.keys(previous), ...Object.keys(next)]);
608
+ const changed = [];
609
+ for (const key of keys) {
610
+ const typedKey = key;
611
+ const previousValue = previous[typedKey];
612
+ const nextValue = next[typedKey];
613
+ if (!areValuesEqual(previousValue, nextValue) && nextValue !== void 0) changed.push([key, nextValue]);
614
+ }
615
+ return Object.fromEntries(changed);
616
+ }
617
+ function getDivProps(props) {
618
+ const entries = [];
619
+ for (const [key, value] of Object.entries(props)) {
620
+ if (NON_DIV_KEYS.has(key) || MAP_OPTION_KEY_SET.has(key) || MAP_EVENT_PROP_KEY_SET.has(key)) continue;
621
+ entries.push([key, value]);
622
+ }
623
+ return Object.fromEntries(entries);
624
+ }
625
+ /**
626
+ * memo 비교: children과 함수(콜백)는 skip.
627
+ * - children: React element는 JSON.stringify 불가
628
+ * - 함수: ref를 통해 항상 최신 값을 읽으므로 비교 불필요
629
+ */
630
+ function areNaverMapPropsEqual(previousProps, nextProps) {
631
+ const keys = new Set([...Object.keys(previousProps), ...Object.keys(nextProps)]);
632
+ for (const key of keys) {
633
+ if (key === "children") continue;
634
+ const previousValue = previousProps[key];
635
+ const nextValue = nextProps[key];
636
+ if (typeof previousValue === "function" && typeof nextValue === "function") continue;
637
+ if (!areValuesEqual(previousValue, nextValue)) return false;
638
+ }
639
+ return true;
640
+ }
641
+ const NaverMapBase = (0, react.forwardRef)(function NaverMapInner(props, ref) {
642
+ const context = (0, react.useContext)(NaverMapContext);
643
+ if (!context) throw new Error("NaverMap must be used inside NaverMapProvider.");
644
+ const { sdkStatus, setMap, reloadSdk } = context;
645
+ const [mapReady, setMapReady] = (0, react.useState)(false);
646
+ const propsRef = (0, react.useRef)(props);
647
+ (0, react.useEffect)(() => {
648
+ propsRef.current = props;
649
+ });
650
+ const initialCenterRef = (0, react.useRef)(props.center ?? props.defaultCenter);
651
+ const initialZoomRef = (0, react.useRef)(props.zoom ?? props.defaultZoom);
652
+ const isControlledCenter = props.center !== void 0;
653
+ const isControlledZoom = props.zoom !== void 0;
654
+ const mapOptions = (0, react.useMemo)(() => {
655
+ const entries = [];
656
+ for (const key of MAP_OPTION_KEYS) {
657
+ const value = props[key];
658
+ if (value !== void 0) entries.push([key, value]);
659
+ }
660
+ return Object.fromEntries(entries);
661
+ }, [
662
+ props.background,
663
+ props.baseTileOpacity,
664
+ props.bounds,
665
+ props.center,
666
+ props.zoom,
667
+ props.disableDoubleClickZoom,
668
+ props.disableDoubleTapZoom,
669
+ props.disableKineticPan,
670
+ props.disableTwoFingerTapZoom,
671
+ props.draggable,
672
+ props.keyboardShortcuts,
673
+ props.logoControl,
674
+ props.logoControlOptions,
675
+ props.mapDataControl,
676
+ props.mapDataControlOptions,
677
+ props.mapTypeControl,
678
+ props.mapTypeControlOptions,
679
+ props.mapTypeId,
680
+ props.mapTypes,
681
+ props.maxBounds,
682
+ props.maxZoom,
683
+ props.minZoom,
684
+ props.padding,
685
+ props.pinchZoom,
686
+ props.resizeOrigin,
687
+ props.scaleControl,
688
+ props.scaleControlOptions,
689
+ props.scrollWheel,
690
+ props.size,
691
+ props.overlayZoomEffect,
692
+ props.tileSpare,
693
+ props.tileTransition,
694
+ props.tileDuration,
695
+ props.zoomControl,
696
+ props.zoomControlOptions,
697
+ props.zoomOrigin,
698
+ props.blankTileImage,
699
+ props.gl,
700
+ props.customStyleId
701
+ ]);
702
+ const divProps = (0, react.useMemo)(() => getDivProps(props), [props]);
703
+ const containerRef = (0, react.useRef)(null);
704
+ const mapRef = (0, react.useRef)(null);
705
+ const appliedOptionsRef = (0, react.useRef)({});
706
+ const retryTimerRef = (0, react.useRef)(null);
707
+ const mapOptionsRef = (0, react.useRef)(mapOptions);
708
+ mapOptionsRef.current = mapOptions;
709
+ const invokeMapMethod = (0, react.useCallback)((methodName, ...args) => {
710
+ const mapInstance = mapRef.current;
711
+ if (!mapInstance) return;
712
+ const method = mapInstance[methodName];
713
+ if (typeof method !== "function") return;
714
+ return method.apply(mapInstance, args);
715
+ }, []);
716
+ (0, react.useImperativeHandle)(ref, () => ({
717
+ getInstance: () => mapRef.current,
718
+ addOverlayPane: (name, elementOrZIndex) => {
719
+ mapRef.current?.addOverlayPane?.(name, elementOrZIndex);
720
+ },
721
+ addPane: (...args) => invokeMapMethod("addPane", ...args),
722
+ autoResize: (...args) => invokeMapMethod("autoResize", ...args),
723
+ destroy: (...args) => {
724
+ const mapInstance = mapRef.current;
725
+ if (!mapInstance) return;
726
+ try {
727
+ return mapInstance.destroy?.(...args);
728
+ } catch {
729
+ return;
730
+ }
731
+ },
732
+ fitBounds: (...args) => invokeMapMethod("fitBounds", ...args),
733
+ getBounds: (...args) => invokeMapMethod("getBounds", ...args),
734
+ getCenter: (...args) => invokeMapMethod("getCenter", ...args),
735
+ getCenterPoint: (...args) => invokeMapMethod("getCenterPoint", ...args),
736
+ getElement: (...args) => invokeMapMethod("getElement", ...args),
737
+ getMapTypeId: (...args) => invokeMapMethod("getMapTypeId", ...args),
738
+ getMaxZoom: (...args) => invokeMapMethod("getMaxZoom", ...args),
739
+ getMinZoom: (...args) => invokeMapMethod("getMinZoom", ...args),
740
+ getOptions: (...args) => invokeMapMethod("getOptions", ...args),
741
+ getPanes: (...args) => invokeMapMethod("getPanes", ...args),
742
+ getPrimitiveProjection: (...args) => invokeMapMethod("getPrimitiveProjection", ...args),
743
+ getProjection: (...args) => invokeMapMethod("getProjection", ...args),
744
+ getSize: (...args) => invokeMapMethod("getSize", ...args),
745
+ getZoom: (...args) => invokeMapMethod("getZoom", ...args),
746
+ morph: (...args) => invokeMapMethod("morph", ...args),
747
+ panBy: (...args) => invokeMapMethod("panBy", ...args),
748
+ panTo: (...args) => invokeMapMethod("panTo", ...args),
749
+ panToBounds: (...args) => invokeMapMethod("panToBounds", ...args),
750
+ refresh: (...args) => invokeMapMethod("refresh", ...args),
751
+ removeOverlayPane: (name) => {
752
+ mapRef.current?.removeOverlayPane?.(name);
753
+ },
754
+ removePane: (...args) => invokeMapMethod("removePane", ...args),
755
+ setCenter: (...args) => invokeMapMethod("setCenter", ...args),
756
+ setCenterPoint: (...args) => invokeMapMethod("setCenterPoint", ...args),
757
+ setMapTypeId: (...args) => invokeMapMethod("setMapTypeId", ...args),
758
+ setOptions: (...args) => invokeMapMethod("setOptions", ...args),
759
+ setSize: (...args) => invokeMapMethod("setSize", ...args),
760
+ setZoom: (...args) => invokeMapMethod("setZoom", ...args),
761
+ stop: (...args) => invokeMapMethod("stop", ...args),
762
+ updateBy: (...args) => invokeMapMethod("updateBy", ...args),
763
+ zoomBy: (...args) => invokeMapMethod("zoomBy", ...args)
764
+ }), [invokeMapMethod]);
765
+ (0, react.useEffect)(() => {
766
+ if (sdkStatus !== "ready" || !containerRef.current) return;
767
+ const container = containerRef.current;
768
+ const initOptions = { ...mapOptionsRef.current };
769
+ if (initOptions.center === void 0 && initialCenterRef.current !== void 0) initOptions.center = initialCenterRef.current;
770
+ if (initOptions.zoom === void 0 && initialZoomRef.current !== void 0) initOptions.zoom = initialZoomRef.current;
771
+ let mapInstance;
772
+ try {
773
+ mapInstance = new naver.maps.Map(container, initOptions);
774
+ } catch (error) {
775
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Map instance.");
776
+ propsRef.current.onMapError?.(normalizedError);
777
+ if (propsRef.current.retryOnError) retryTimerRef.current = setTimeout(() => {
778
+ reloadSdk().catch(() => void 0);
779
+ }, propsRef.current.retryDelayMs ?? 1e3);
780
+ return () => {
781
+ if (retryTimerRef.current) {
782
+ clearTimeout(retryTimerRef.current);
783
+ retryTimerRef.current = null;
784
+ }
785
+ };
786
+ }
787
+ mapRef.current = mapInstance;
788
+ appliedOptionsRef.current = initOptions;
789
+ setMap(mapInstance);
790
+ setMapReady(true);
791
+ propsRef.current.onMapReady?.(mapInstance);
792
+ const listeners = MAP_EVENT_BINDINGS.map((binding) => naver.maps.Event.addListener(mapInstance, binding.eventName, (event) => {
793
+ const handler = propsRef.current[binding.prop];
794
+ if (typeof handler !== "function") return;
795
+ if (binding.hasPayload) handler(event);
796
+ else handler();
797
+ }));
798
+ return () => {
799
+ try {
800
+ naver.maps.Event.removeListener(listeners);
801
+ naver.maps.Event.clearInstanceListeners(mapInstance);
802
+ } catch {}
803
+ if (retryTimerRef.current) {
804
+ clearTimeout(retryTimerRef.current);
805
+ retryTimerRef.current = null;
806
+ }
807
+ container.innerHTML = "";
808
+ mapRef.current = null;
809
+ appliedOptionsRef.current = {};
810
+ setMap(null);
811
+ setMapReady(false);
812
+ propsRef.current.onMapDestroy?.();
813
+ };
814
+ }, [
815
+ sdkStatus,
816
+ setMap,
817
+ reloadSdk
818
+ ]);
819
+ (0, react.useEffect)(() => {
820
+ const mapInstance = mapRef.current;
821
+ if (!mapInstance) return;
822
+ const changed = getChangedOptions(appliedOptionsRef.current, mapOptions);
823
+ if (Object.keys(changed).length === 0) {
824
+ appliedOptionsRef.current = mapOptions;
825
+ return;
826
+ }
827
+ const { center: changedCenter, zoom: changedZoom, mapTypeId: changedMapTypeId, ...otherChanged } = changed;
828
+ const savedCenter = !isControlledCenter ? mapInstance.getCenter() : null;
829
+ const savedZoom = !isControlledZoom ? mapInstance.getZoom() : null;
830
+ if (Object.keys(otherChanged).length > 0) mapInstance.setOptions(otherChanged);
831
+ if (changedMapTypeId !== void 0 && mapOptions.mapTypeId !== void 0) mapInstance.setMapTypeId(mapOptions.mapTypeId);
832
+ if (isControlledCenter && changedCenter !== void 0) mapInstance.setCenter(changedCenter);
833
+ if (isControlledZoom && changedZoom !== void 0 && mapOptions.zoom !== void 0) mapInstance.setZoom(mapOptions.zoom);
834
+ if (savedCenter) mapInstance.setCenter(savedCenter);
835
+ if (savedZoom !== null) mapInstance.setZoom(savedZoom);
836
+ appliedOptionsRef.current = mapOptions;
837
+ }, [
838
+ mapOptions,
839
+ isControlledCenter,
840
+ isControlledZoom
841
+ ]);
842
+ if (sdkStatus === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: props.fallback ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
843
+ ...divProps,
844
+ children: "지도를 불러올 수 없습니다."
845
+ }) });
846
+ 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 }) });
847
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
848
+ ref: containerRef,
849
+ ...divProps,
850
+ children: mapReady ? props.children : null
851
+ });
852
+ });
853
+ NaverMapBase.displayName = "NaverMap";
854
+ const NaverMap = (0, react.memo)(NaverMapBase, areNaverMapPropsEqual);
855
+
856
+ //#endregion
857
+ //#region src/react/hooks/useNaverMap.ts
858
+ function useNaverMap(options = {}) {
859
+ const context = (0, react.useContext)(NaverMapContext);
860
+ if (!context) throw new Error("useNaverMap must be used within NaverMapProvider.");
861
+ if (options.requireReady && context.sdkStatus !== "ready") throw new Error(`Naver Maps SDK is not ready. Current status: ${context.sdkStatus}.`);
862
+ if (options.requireMapInstance && !context.map) throw new Error("Naver map instance is not available yet.");
863
+ return context;
864
+ }
865
+ function useNaverMapInstance(options = {}) {
866
+ return useNaverMap({
867
+ requireReady: options.requireReady,
868
+ requireMapInstance: false
869
+ }).map;
870
+ }
871
+
872
+ //#endregion
873
+ //#region src/overlays/marker/Marker.tsx
874
+ function pickHtmlIconAnchor(icon) {
875
+ if ("anchor" in icon) return icon.anchor;
876
+ }
877
+ function pickHtmlIconSize(icon) {
878
+ if ("size" in icon) return icon.size;
879
+ }
880
+ function resolveMarkerIcon(icon, childrenContainer, hasChildren) {
881
+ if (!hasChildren || !childrenContainer) return icon;
882
+ const iconObject = typeof icon === "object" && icon !== null ? icon : void 0;
883
+ return {
884
+ content: childrenContainer,
885
+ anchor: iconObject ? pickHtmlIconAnchor(iconObject) : void 0,
886
+ size: iconObject ? pickHtmlIconSize(iconObject) : void 0
887
+ };
888
+ }
889
+ function toMarkerOptions(props, targetMap, icon) {
890
+ const options = {
891
+ position: props.position,
892
+ icon
893
+ };
894
+ if (targetMap) options.map = targetMap;
895
+ if (props.animation !== void 0) options.animation = props.animation;
896
+ if (props.shape !== void 0) options.shape = props.shape;
897
+ if (props.title !== void 0) options.title = props.title;
898
+ if (props.cursor !== void 0) options.cursor = props.cursor;
899
+ if (props.clickable !== void 0) options.clickable = props.clickable;
900
+ if (props.draggable !== void 0) options.draggable = props.draggable;
901
+ if (props.visible !== void 0) options.visible = props.visible;
902
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
903
+ return options;
904
+ }
905
+ function buildMarkerEventBindings(props) {
906
+ return [
907
+ {
908
+ eventName: "click",
909
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
910
+ },
911
+ {
912
+ eventName: "dblclick",
913
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
914
+ },
915
+ {
916
+ eventName: "rightclick",
917
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
918
+ },
919
+ {
920
+ eventName: "mousedown",
921
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
922
+ },
923
+ {
924
+ eventName: "mouseup",
925
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
926
+ },
927
+ {
928
+ eventName: "touchstart",
929
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
930
+ },
931
+ {
932
+ eventName: "touchend",
933
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
934
+ },
935
+ {
936
+ eventName: "dragstart",
937
+ invoke: props.onDragStart ? (event) => props.onDragStart?.(event) : void 0
938
+ },
939
+ {
940
+ eventName: "drag",
941
+ invoke: props.onDrag ? (event) => props.onDrag?.(event) : void 0
942
+ },
943
+ {
944
+ eventName: "dragend",
945
+ invoke: props.onDragEnd ? (event) => props.onDragEnd?.(event) : void 0
946
+ },
947
+ {
948
+ eventName: "clickable_changed",
949
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
950
+ },
951
+ {
952
+ eventName: "cursor_changed",
953
+ invoke: props.onCursorChanged ? (event) => props.onCursorChanged?.(event) : void 0
954
+ },
955
+ {
956
+ eventName: "draggable_changed",
957
+ invoke: props.onDraggableChanged ? (event) => props.onDraggableChanged?.(event) : void 0
958
+ },
959
+ {
960
+ eventName: "icon_changed",
961
+ invoke: props.onIconChanged ? (event) => props.onIconChanged?.(event) : void 0
962
+ },
963
+ {
964
+ eventName: "icon_loaded",
965
+ invoke: props.onIconLoaded ? (event) => props.onIconLoaded?.(event) : void 0
966
+ },
967
+ {
968
+ eventName: "position_changed",
969
+ invoke: props.onPositionChanged ? (event) => props.onPositionChanged?.(event) : void 0
970
+ },
971
+ {
972
+ eventName: "shape_changed",
973
+ invoke: props.onShapeChanged ? (event) => props.onShapeChanged?.(event) : void 0
974
+ },
975
+ {
976
+ eventName: "title_changed",
977
+ invoke: props.onTitleChanged ? (event) => props.onTitleChanged?.(event) : void 0
978
+ },
979
+ {
980
+ eventName: "visible_changed",
981
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
982
+ },
983
+ {
984
+ eventName: "zIndex_changed",
985
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
986
+ }
987
+ ];
988
+ }
989
+ function bindMarkerEventListeners(marker, listenersRef, bindings) {
990
+ if (listenersRef.current.length > 0) {
991
+ naver.maps.Event.removeListener(listenersRef.current);
992
+ listenersRef.current = [];
993
+ }
994
+ listenersRef.current = bindings.filter((binding) => typeof binding.invoke === "function").map((binding) => naver.maps.Event.addListener(marker, binding.eventName, (event) => {
995
+ binding.invoke?.(event);
996
+ }));
997
+ }
998
+ const Marker = (0, react.forwardRef)(function MarkerInner(props, ref) {
999
+ const { map: contextMap, sdkStatus } = useNaverMap();
1000
+ const markerRef = (0, react.useRef)(null);
1001
+ const markerEventListenersRef = (0, react.useRef)([]);
1002
+ const onMarkerDestroyRef = (0, react.useRef)(props.onMarkerDestroy);
1003
+ const [markerDiv, setMarkerDiv] = (0, react.useState)(null);
1004
+ const [portalReady, setPortalReady] = (0, react.useState)(false);
1005
+ const hasChildren = props.children !== void 0 && props.children !== null;
1006
+ const targetMap = props.map ?? contextMap;
1007
+ (0, react.useEffect)(() => {
1008
+ onMarkerDestroyRef.current = props.onMarkerDestroy;
1009
+ }, [props.onMarkerDestroy]);
1010
+ (0, react.useEffect)(() => {
1011
+ if (typeof document === "undefined") return;
1012
+ setMarkerDiv(document.createElement("div"));
1013
+ }, []);
1014
+ (0, react.useEffect)(() => {
1015
+ if (!hasChildren || !markerDiv) {
1016
+ setPortalReady(false);
1017
+ return;
1018
+ }
1019
+ const updateReadyState = () => {
1020
+ setPortalReady(markerDiv.childNodes.length > 0);
1021
+ };
1022
+ updateReadyState();
1023
+ const observer = new MutationObserver(updateReadyState);
1024
+ observer.observe(markerDiv, {
1025
+ childList: true,
1026
+ subtree: true
1027
+ });
1028
+ return () => {
1029
+ observer.disconnect();
1030
+ };
1031
+ }, [hasChildren, markerDiv]);
1032
+ const invokeMarkerMethod = (0, react.useCallback)((methodName, ...args) => {
1033
+ const marker = markerRef.current;
1034
+ if (!marker) return;
1035
+ const method = marker[methodName];
1036
+ if (typeof method !== "function") return;
1037
+ return method.apply(marker, args);
1038
+ }, []);
1039
+ const teardownMarker = (0, react.useCallback)(() => {
1040
+ const marker = markerRef.current;
1041
+ if (!marker) return;
1042
+ try {
1043
+ if (markerEventListenersRef.current.length > 0) {
1044
+ naver.maps.Event.removeListener(markerEventListenersRef.current);
1045
+ markerEventListenersRef.current = [];
1046
+ }
1047
+ naver.maps.Event.clearInstanceListeners(marker);
1048
+ } catch (error) {
1049
+ console.error("[react-naver-maps-kit] failed to clear marker listeners", error);
1050
+ }
1051
+ marker.setMap(null);
1052
+ markerRef.current = null;
1053
+ onMarkerDestroyRef.current?.();
1054
+ }, []);
1055
+ (0, react.useImperativeHandle)(ref, () => ({
1056
+ getInstance: () => markerRef.current,
1057
+ getAnimation: (...args) => invokeMarkerMethod("getAnimation", ...args),
1058
+ getClickable: (...args) => invokeMarkerMethod("getClickable", ...args),
1059
+ getCursor: (...args) => invokeMarkerMethod("getCursor", ...args),
1060
+ getDraggable: (...args) => invokeMarkerMethod("getDraggable", ...args),
1061
+ getDrawingRect: (...args) => invokeMarkerMethod("getDrawingRect", ...args),
1062
+ getElement: (...args) => invokeMarkerMethod("getElement", ...args),
1063
+ getIcon: (...args) => invokeMarkerMethod("getIcon", ...args),
1064
+ getMap: (...args) => invokeMarkerMethod("getMap", ...args),
1065
+ getOptions: (...args) => invokeMarkerMethod("getOptions", ...args),
1066
+ getPanes: (...args) => invokeMarkerMethod("getPanes", ...args),
1067
+ getPosition: (...args) => invokeMarkerMethod("getPosition", ...args),
1068
+ getProjection: (...args) => invokeMarkerMethod("getProjection", ...args),
1069
+ getShape: (...args) => invokeMarkerMethod("getShape", ...args),
1070
+ getTitle: (...args) => invokeMarkerMethod("getTitle", ...args),
1071
+ getVisible: (...args) => invokeMarkerMethod("getVisible", ...args),
1072
+ getZIndex: (...args) => invokeMarkerMethod("getZIndex", ...args),
1073
+ setAnimation: (...args) => invokeMarkerMethod("setAnimation", ...args),
1074
+ setClickable: (...args) => invokeMarkerMethod("setClickable", ...args),
1075
+ setCursor: (...args) => invokeMarkerMethod("setCursor", ...args),
1076
+ setDraggable: (...args) => invokeMarkerMethod("setDraggable", ...args),
1077
+ setIcon: (...args) => invokeMarkerMethod("setIcon", ...args),
1078
+ setMap: (...args) => invokeMarkerMethod("setMap", ...args),
1079
+ setOptions: (...args) => invokeMarkerMethod("setOptions", ...args),
1080
+ setPosition: (...args) => invokeMarkerMethod("setPosition", ...args),
1081
+ setShape: (...args) => invokeMarkerMethod("setShape", ...args),
1082
+ setTitle: (...args) => invokeMarkerMethod("setTitle", ...args),
1083
+ setVisible: (...args) => invokeMarkerMethod("setVisible", ...args),
1084
+ setZIndex: (...args) => invokeMarkerMethod("setZIndex", ...args)
1085
+ }), [invokeMarkerMethod]);
1086
+ (0, react.useEffect)(() => {
1087
+ if (sdkStatus !== "ready" || !targetMap || markerRef.current) return;
1088
+ if (hasChildren && !portalReady) return;
1089
+ try {
1090
+ const resolvedIcon = resolveMarkerIcon(props.icon, markerDiv, hasChildren);
1091
+ const marker = new naver.maps.Marker(toMarkerOptions(props, targetMap, resolvedIcon));
1092
+ markerRef.current = marker;
1093
+ if (props.collisionBehavior !== void 0) marker.setOptions("collisionBehavior", props.collisionBehavior);
1094
+ if (props.collisionBoxSize !== void 0) marker.setOptions("collisionBoxSize", props.collisionBoxSize);
1095
+ bindMarkerEventListeners(marker, markerEventListenersRef, buildMarkerEventBindings(props));
1096
+ props.onMarkerReady?.(marker);
1097
+ } catch (error) {
1098
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Marker instance.");
1099
+ props.onMarkerError?.(normalizedError);
1100
+ }
1101
+ }, [
1102
+ hasChildren,
1103
+ markerDiv,
1104
+ portalReady,
1105
+ props,
1106
+ sdkStatus,
1107
+ targetMap
1108
+ ]);
1109
+ (0, react.useLayoutEffect)(() => {
1110
+ const marker = markerRef.current;
1111
+ if (!marker || !targetMap) return;
1112
+ const rafId = requestAnimationFrame(() => {
1113
+ const nextOptions = toMarkerOptions(props, targetMap, hasChildren && portalReady ? resolveMarkerIcon(props.icon, markerDiv, hasChildren) : props.icon);
1114
+ marker.setOptions(nextOptions);
1115
+ if (props.collisionBehavior !== void 0) marker.setOptions("collisionBehavior", props.collisionBehavior);
1116
+ if (props.collisionBoxSize !== void 0) marker.setOptions("collisionBoxSize", props.collisionBoxSize);
1117
+ });
1118
+ return () => {
1119
+ cancelAnimationFrame(rafId);
1120
+ };
1121
+ }, [
1122
+ hasChildren,
1123
+ markerDiv,
1124
+ portalReady,
1125
+ props,
1126
+ targetMap
1127
+ ]);
1128
+ (0, react.useEffect)(() => {
1129
+ const marker = markerRef.current;
1130
+ if (!marker) return;
1131
+ bindMarkerEventListeners(marker, markerEventListenersRef, buildMarkerEventBindings(props));
1132
+ return () => {
1133
+ if (markerEventListenersRef.current.length > 0) {
1134
+ naver.maps.Event.removeListener(markerEventListenersRef.current);
1135
+ markerEventListenersRef.current = [];
1136
+ }
1137
+ };
1138
+ }, [props]);
1139
+ (0, react.useEffect)(() => {
1140
+ return () => {
1141
+ teardownMarker();
1142
+ };
1143
+ }, [teardownMarker]);
1144
+ if (!hasChildren || !markerDiv) return null;
1145
+ return (0, react_dom.createPortal)(props.children, markerDiv);
1146
+ });
1147
+ Marker.displayName = "Marker";
1148
+
1149
+ //#endregion
1150
+ //#region src/overlays/infowindow/InfoWindow.tsx
1151
+ function toInfoWindowOptions(props) {
1152
+ const { anchorColor, anchorSize, anchorSkew, backgroundColor, borderColor, borderWidth, disableAnchor, disableAutoPan, maxWidth, pixelOffset, position, zIndex } = props;
1153
+ const options = {};
1154
+ if (anchorColor !== void 0) options.anchorColor = anchorColor;
1155
+ if (anchorSize !== void 0) options.anchorSize = anchorSize;
1156
+ if (anchorSkew !== void 0) options.anchorSkew = anchorSkew;
1157
+ if (backgroundColor !== void 0) options.backgroundColor = backgroundColor;
1158
+ if (borderColor !== void 0) options.borderColor = borderColor;
1159
+ if (borderWidth !== void 0) options.borderWidth = borderWidth;
1160
+ if (disableAnchor !== void 0) options.disableAnchor = disableAnchor;
1161
+ if (disableAutoPan !== void 0) options.disableAutoPan = disableAutoPan;
1162
+ if (maxWidth !== void 0) options.maxWidth = maxWidth;
1163
+ if (pixelOffset !== void 0) options.pixelOffset = pixelOffset;
1164
+ if (position !== void 0) options.position = position;
1165
+ if (zIndex !== void 0) options.zIndex = zIndex;
1166
+ return options;
1167
+ }
1168
+ function resolveInfoWindowContent(content, childrenContainer, hasChildren) {
1169
+ if (hasChildren && childrenContainer) return childrenContainer;
1170
+ if (content !== void 0) return content;
1171
+ return "";
1172
+ }
1173
+ function buildInfoWindowEventBindings(props) {
1174
+ return [
1175
+ {
1176
+ eventName: "open",
1177
+ invoke: props.onOpen ? (event) => props.onOpen?.(event) : void 0
1178
+ },
1179
+ {
1180
+ eventName: "close",
1181
+ invoke: props.onClose ? (event) => props.onClose?.(event) : void 0
1182
+ },
1183
+ {
1184
+ eventName: "anchorColor_changed",
1185
+ invoke: props.onAnchorColorChanged ? (event) => props.onAnchorColorChanged?.(event) : void 0
1186
+ },
1187
+ {
1188
+ eventName: "anchorSize_changed",
1189
+ invoke: props.onAnchorSizeChanged ? (event) => props.onAnchorSizeChanged?.(event) : void 0
1190
+ },
1191
+ {
1192
+ eventName: "anchorSkew_changed",
1193
+ invoke: props.onAnchorSkewChanged ? (event) => props.onAnchorSkewChanged?.(event) : void 0
1194
+ },
1195
+ {
1196
+ eventName: "backgroundColor_changed",
1197
+ invoke: props.onBackgroundColorChanged ? (event) => props.onBackgroundColorChanged?.(event) : void 0
1198
+ },
1199
+ {
1200
+ eventName: "borderColor_changed",
1201
+ invoke: props.onBorderColorChanged ? (event) => props.onBorderColorChanged?.(event) : void 0
1202
+ },
1203
+ {
1204
+ eventName: "borderWidth_changed",
1205
+ invoke: props.onBorderWidthChanged ? (event) => props.onBorderWidthChanged?.(event) : void 0
1206
+ },
1207
+ {
1208
+ eventName: "content_changed",
1209
+ invoke: props.onContentChanged ? (event) => props.onContentChanged?.(event) : void 0
1210
+ },
1211
+ {
1212
+ eventName: "disableAnchor_changed",
1213
+ invoke: props.onDisableAnchorChanged ? (event) => props.onDisableAnchorChanged?.(event) : void 0
1214
+ },
1215
+ {
1216
+ eventName: "disableAutoPan_changed",
1217
+ invoke: props.onDisableAutoPanChanged ? (event) => props.onDisableAutoPanChanged?.(event) : void 0
1218
+ },
1219
+ {
1220
+ eventName: "maxWidth_changed",
1221
+ invoke: props.onMaxWidthChanged ? (event) => props.onMaxWidthChanged?.(event) : void 0
1222
+ },
1223
+ {
1224
+ eventName: "pixelOffset_changed",
1225
+ invoke: props.onPixelOffsetChanged ? (event) => props.onPixelOffsetChanged?.(event) : void 0
1226
+ },
1227
+ {
1228
+ eventName: "position_changed",
1229
+ invoke: props.onPositionChanged ? (event) => props.onPositionChanged?.(event) : void 0
1230
+ },
1231
+ {
1232
+ eventName: "zIndex_changed",
1233
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
1234
+ }
1235
+ ];
1236
+ }
1237
+ function bindInfoWindowEventListeners(infoWindow, listenersRef, bindings) {
1238
+ if (listenersRef.current.length > 0) {
1239
+ naver.maps.Event.removeListener(listenersRef.current);
1240
+ listenersRef.current = [];
1241
+ }
1242
+ listenersRef.current = bindings.filter((binding) => typeof binding.invoke === "function").map((binding) => naver.maps.Event.addListener(infoWindow, binding.eventName, (event) => {
1243
+ binding.invoke?.(event);
1244
+ }));
1245
+ }
1246
+ function setInfoWindowOptionByKey(infoWindow, key, value) {
1247
+ infoWindow.setOptions(key, value);
1248
+ }
1249
+ const InfoWindow = (0, react.forwardRef)(function InfoWindowInner(props, ref) {
1250
+ const { map, sdkStatus } = useNaverMap();
1251
+ const infoWindowRef = (0, react.useRef)(null);
1252
+ const infoWindowEventListenersRef = (0, react.useRef)([]);
1253
+ const onInfoWindowDestroyRef = (0, react.useRef)(props.onInfoWindowDestroy);
1254
+ const childrenContainer = (0, react.useMemo)(() => {
1255
+ if (typeof document === "undefined") return null;
1256
+ return document.createElement("div");
1257
+ }, []);
1258
+ const visible = props.visible ?? true;
1259
+ const hasChildren = props.children !== void 0 && props.children !== null;
1260
+ const optionSnapshot = (0, react.useMemo)(() => toInfoWindowOptions(props), [props]);
1261
+ (0, react.useEffect)(() => {
1262
+ onInfoWindowDestroyRef.current = props.onInfoWindowDestroy;
1263
+ }, [props.onInfoWindowDestroy]);
1264
+ const invokeInfoWindowMethod = (0, react.useCallback)((methodName, ...args) => {
1265
+ const infoWindow = infoWindowRef.current;
1266
+ if (!infoWindow) return;
1267
+ const method = infoWindow[methodName];
1268
+ if (typeof method !== "function") return;
1269
+ return method.apply(infoWindow, args);
1270
+ }, []);
1271
+ const teardownInfoWindow = (0, react.useCallback)(() => {
1272
+ const infoWindow = infoWindowRef.current;
1273
+ if (!infoWindow) return;
1274
+ try {
1275
+ if (infoWindowEventListenersRef.current.length > 0) {
1276
+ naver.maps.Event.removeListener(infoWindowEventListenersRef.current);
1277
+ infoWindowEventListenersRef.current = [];
1278
+ }
1279
+ naver.maps.Event.clearInstanceListeners(infoWindow);
1280
+ } catch (error) {
1281
+ console.error("[react-naver-maps-kit] failed to clear infoWindow listeners", error);
1282
+ }
1283
+ infoWindow.close();
1284
+ infoWindow.setMap(null);
1285
+ infoWindowRef.current = null;
1286
+ onInfoWindowDestroyRef.current?.();
1287
+ }, []);
1288
+ (0, react.useImperativeHandle)(ref, () => ({
1289
+ getInstance: () => infoWindowRef.current,
1290
+ close: (...args) => invokeInfoWindowMethod("close", ...args),
1291
+ getContent: (...args) => invokeInfoWindowMethod("getContent", ...args),
1292
+ getContentElement: (...args) => invokeInfoWindowMethod("getContentElement", ...args),
1293
+ getMap: (...args) => invokeInfoWindowMethod("getMap", ...args),
1294
+ getOptions: (...args) => invokeInfoWindowMethod("getOptions", ...args),
1295
+ getPanes: (...args) => invokeInfoWindowMethod("getPanes", ...args),
1296
+ getPosition: (...args) => invokeInfoWindowMethod("getPosition", ...args),
1297
+ getProjection: (...args) => invokeInfoWindowMethod("getProjection", ...args),
1298
+ getZIndex: (...args) => invokeInfoWindowMethod("getZIndex", ...args),
1299
+ open: (...args) => invokeInfoWindowMethod("open", ...args),
1300
+ setContent: (...args) => invokeInfoWindowMethod("setContent", ...args),
1301
+ setMap: (...args) => invokeInfoWindowMethod("setMap", ...args),
1302
+ setOptions: (...args) => invokeInfoWindowMethod("setOptions", ...args),
1303
+ setPosition: (...args) => invokeInfoWindowMethod("setPosition", ...args),
1304
+ setZIndex: (...args) => invokeInfoWindowMethod("setZIndex", ...args)
1305
+ }), [invokeInfoWindowMethod]);
1306
+ (0, react.useEffect)(() => {
1307
+ if (sdkStatus !== "ready" || !map || infoWindowRef.current) return;
1308
+ try {
1309
+ const infoWindow = new naver.maps.InfoWindow({
1310
+ ...optionSnapshot,
1311
+ content: resolveInfoWindowContent(props.content, childrenContainer, hasChildren)
1312
+ });
1313
+ if (props.autoPanPadding !== void 0) setInfoWindowOptionByKey(infoWindow, "autoPanPadding", props.autoPanPadding);
1314
+ infoWindowRef.current = infoWindow;
1315
+ bindInfoWindowEventListeners(infoWindow, infoWindowEventListenersRef, buildInfoWindowEventBindings(props));
1316
+ props.onInfoWindowReady?.(infoWindow);
1317
+ } catch (error) {
1318
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.InfoWindow instance.");
1319
+ props.onInfoWindowError?.(normalizedError);
1320
+ }
1321
+ }, [
1322
+ childrenContainer,
1323
+ hasChildren,
1324
+ map,
1325
+ optionSnapshot,
1326
+ props,
1327
+ sdkStatus
1328
+ ]);
1329
+ (0, react.useEffect)(() => {
1330
+ const infoWindow = infoWindowRef.current;
1331
+ if (!infoWindow) return;
1332
+ const resolvedContent = resolveInfoWindowContent(props.content, childrenContainer, hasChildren);
1333
+ infoWindow.setOptions({
1334
+ ...optionSnapshot,
1335
+ content: resolvedContent
1336
+ });
1337
+ infoWindow.setContent(resolvedContent);
1338
+ if (props.autoPanPadding !== void 0) setInfoWindowOptionByKey(infoWindow, "autoPanPadding", props.autoPanPadding);
1339
+ if (props.position) infoWindow.setPosition(props.position);
1340
+ if (!map || !visible) {
1341
+ infoWindow.close();
1342
+ return;
1343
+ }
1344
+ if (props.anchor) {
1345
+ infoWindow.open(map, props.anchor);
1346
+ return;
1347
+ }
1348
+ if (props.position) {
1349
+ infoWindow.open(map, props.position);
1350
+ return;
1351
+ }
1352
+ infoWindow.open(map);
1353
+ }, [
1354
+ childrenContainer,
1355
+ hasChildren,
1356
+ map,
1357
+ optionSnapshot,
1358
+ props.anchor,
1359
+ props.content,
1360
+ props.position,
1361
+ props.autoPanPadding,
1362
+ visible
1363
+ ]);
1364
+ (0, react.useEffect)(() => {
1365
+ const infoWindow = infoWindowRef.current;
1366
+ if (!infoWindow) return;
1367
+ bindInfoWindowEventListeners(infoWindow, infoWindowEventListenersRef, buildInfoWindowEventBindings(props));
1368
+ return () => {
1369
+ if (infoWindowEventListenersRef.current.length > 0) {
1370
+ naver.maps.Event.removeListener(infoWindowEventListenersRef.current);
1371
+ infoWindowEventListenersRef.current = [];
1372
+ }
1373
+ };
1374
+ }, [props]);
1375
+ (0, react.useEffect)(() => {
1376
+ return () => {
1377
+ teardownInfoWindow();
1378
+ };
1379
+ }, [teardownInfoWindow]);
1380
+ if (!hasChildren || !childrenContainer) return null;
1381
+ return (0, react_dom.createPortal)(props.children, childrenContainer);
1382
+ });
1383
+ InfoWindow.displayName = "InfoWindow";
1384
+
1385
+ //#endregion
1386
+ //#region src/overlays/shared/overlayUtils.ts
1387
+ function bindOverlayEventListeners(target, listenersRef, bindings) {
1388
+ if (listenersRef.current.length > 0) {
1389
+ naver.maps.Event.removeListener(listenersRef.current);
1390
+ listenersRef.current = [];
1391
+ }
1392
+ listenersRef.current = bindings.filter((binding) => typeof binding.invoke === "function").map((binding) => naver.maps.Event.addListener(target, binding.eventName, (event) => {
1393
+ binding.invoke?.(event);
1394
+ }));
1395
+ }
1396
+ function removeOverlayEventListeners(listeners) {
1397
+ if (listeners.length > 0) naver.maps.Event.removeListener(listeners);
1398
+ }
1399
+
1400
+ //#endregion
1401
+ //#region src/overlays/circle/Circle.tsx
1402
+ function toCircleOptions(props, targetMap) {
1403
+ const options = { center: props.center };
1404
+ if (targetMap) options.map = targetMap;
1405
+ if (props.radius !== void 0) options.radius = props.radius;
1406
+ if (props.strokeWeight !== void 0) options.strokeWeight = props.strokeWeight;
1407
+ if (props.strokeOpacity !== void 0) options.strokeOpacity = props.strokeOpacity;
1408
+ if (props.strokeColor !== void 0) options.strokeColor = props.strokeColor;
1409
+ if (props.strokeStyle !== void 0) options.strokeStyle = props.strokeStyle;
1410
+ if (props.strokeLineCap !== void 0) options.strokeLineCap = props.strokeLineCap;
1411
+ if (props.strokeLineJoin !== void 0) options.strokeLineJoin = props.strokeLineJoin;
1412
+ if (props.fillColor !== void 0) options.fillColor = props.fillColor;
1413
+ if (props.fillOpacity !== void 0) options.fillOpacity = props.fillOpacity;
1414
+ if (props.clickable !== void 0) options.clickable = props.clickable;
1415
+ if (props.visible !== void 0) options.visible = props.visible;
1416
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
1417
+ return options;
1418
+ }
1419
+ function buildCircleEventBindings(props) {
1420
+ return [
1421
+ {
1422
+ eventName: "click",
1423
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
1424
+ },
1425
+ {
1426
+ eventName: "dblclick",
1427
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
1428
+ },
1429
+ {
1430
+ eventName: "mousedown",
1431
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
1432
+ },
1433
+ {
1434
+ eventName: "mousemove",
1435
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
1436
+ },
1437
+ {
1438
+ eventName: "mouseout",
1439
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
1440
+ },
1441
+ {
1442
+ eventName: "mouseover",
1443
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
1444
+ },
1445
+ {
1446
+ eventName: "mouseup",
1447
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
1448
+ },
1449
+ {
1450
+ eventName: "rightclick",
1451
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
1452
+ },
1453
+ {
1454
+ eventName: "touchstart",
1455
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
1456
+ },
1457
+ {
1458
+ eventName: "touchmove",
1459
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
1460
+ },
1461
+ {
1462
+ eventName: "touchend",
1463
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
1464
+ },
1465
+ {
1466
+ eventName: "center_changed",
1467
+ invoke: props.onCenterChanged ? (event) => props.onCenterChanged?.(event) : void 0
1468
+ },
1469
+ {
1470
+ eventName: "clickable_changed",
1471
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
1472
+ },
1473
+ {
1474
+ eventName: "fillColor_changed",
1475
+ invoke: props.onFillColorChanged ? (event) => props.onFillColorChanged?.(event) : void 0
1476
+ },
1477
+ {
1478
+ eventName: "fillOpacity_changed",
1479
+ invoke: props.onFillOpacityChanged ? (event) => props.onFillOpacityChanged?.(event) : void 0
1480
+ },
1481
+ {
1482
+ eventName: "map_changed",
1483
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
1484
+ },
1485
+ {
1486
+ eventName: "radius_changed",
1487
+ invoke: props.onRadiusChanged ? (event) => props.onRadiusChanged?.(event) : void 0
1488
+ },
1489
+ {
1490
+ eventName: "strokeColor_changed",
1491
+ invoke: props.onStrokeColorChanged ? (event) => props.onStrokeColorChanged?.(event) : void 0
1492
+ },
1493
+ {
1494
+ eventName: "strokeLineCap_changed",
1495
+ invoke: props.onStrokeLineCapChanged ? (event) => props.onStrokeLineCapChanged?.(event) : void 0
1496
+ },
1497
+ {
1498
+ eventName: "strokeLineJoin_changed",
1499
+ invoke: props.onStrokeLineJoinChanged ? (event) => props.onStrokeLineJoinChanged?.(event) : void 0
1500
+ },
1501
+ {
1502
+ eventName: "strokeOpacity_changed",
1503
+ invoke: props.onStrokeOpacityChanged ? (event) => props.onStrokeOpacityChanged?.(event) : void 0
1504
+ },
1505
+ {
1506
+ eventName: "strokeStyle_changed",
1507
+ invoke: props.onStrokeStyleChanged ? (event) => props.onStrokeStyleChanged?.(event) : void 0
1508
+ },
1509
+ {
1510
+ eventName: "strokeWeight_changed",
1511
+ invoke: props.onStrokeWeightChanged ? (event) => props.onStrokeWeightChanged?.(event) : void 0
1512
+ },
1513
+ {
1514
+ eventName: "visible_changed",
1515
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
1516
+ },
1517
+ {
1518
+ eventName: "zIndex_changed",
1519
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
1520
+ }
1521
+ ];
1522
+ }
1523
+ const Circle = (0, react.forwardRef)(function CircleInner(props, ref) {
1524
+ const { map: contextMap, sdkStatus } = useNaverMap();
1525
+ const circleRef = (0, react.useRef)(null);
1526
+ const circleEventListenersRef = (0, react.useRef)([]);
1527
+ const onCircleDestroyRef = (0, react.useRef)(props.onCircleDestroy);
1528
+ const targetMap = props.map ?? contextMap;
1529
+ (0, react.useEffect)(() => {
1530
+ onCircleDestroyRef.current = props.onCircleDestroy;
1531
+ }, [props.onCircleDestroy]);
1532
+ const invokeCircleMethod = (0, react.useCallback)((methodName, ...args) => {
1533
+ const circle = circleRef.current;
1534
+ if (!circle) return;
1535
+ const method = circle[methodName];
1536
+ if (typeof method !== "function") return;
1537
+ return method.apply(circle, args);
1538
+ }, []);
1539
+ const teardownCircle = (0, react.useCallback)(() => {
1540
+ const circle = circleRef.current;
1541
+ if (!circle) return;
1542
+ try {
1543
+ removeOverlayEventListeners(circleEventListenersRef.current);
1544
+ circleEventListenersRef.current = [];
1545
+ naver.maps.Event.clearInstanceListeners(circle);
1546
+ } catch (error) {
1547
+ console.error("[react-naver-maps-kit] failed to clear circle listeners", error);
1548
+ }
1549
+ circle.setMap(null);
1550
+ circleRef.current = null;
1551
+ onCircleDestroyRef.current?.();
1552
+ }, []);
1553
+ (0, react.useImperativeHandle)(ref, () => ({
1554
+ getInstance: () => circleRef.current,
1555
+ getAreaSize: (...args) => invokeCircleMethod("getAreaSize", ...args),
1556
+ getBounds: (...args) => invokeCircleMethod("getBounds", ...args),
1557
+ getCenter: (...args) => invokeCircleMethod("getCenter", ...args),
1558
+ getClickable: (...args) => invokeCircleMethod("getClickable", ...args),
1559
+ getDrawingRect: (...args) => invokeCircleMethod("getDrawingRect", ...args),
1560
+ getElement: (...args) => invokeCircleMethod("getElement", ...args),
1561
+ getMap: (...args) => invokeCircleMethod("getMap", ...args),
1562
+ getOptions: (...args) => invokeCircleMethod("getOptions", ...args),
1563
+ getPanes: (...args) => invokeCircleMethod("getPanes", ...args),
1564
+ getProjection: (...args) => invokeCircleMethod("getProjection", ...args),
1565
+ getRadius: (...args) => invokeCircleMethod("getRadius", ...args),
1566
+ getStyles: (...args) => invokeCircleMethod("getStyles", ...args),
1567
+ getVisible: (...args) => invokeCircleMethod("getVisible", ...args),
1568
+ getZIndex: (...args) => invokeCircleMethod("getZIndex", ...args),
1569
+ setCenter: (...args) => invokeCircleMethod("setCenter", ...args),
1570
+ setClickable: (...args) => invokeCircleMethod("setClickable", ...args),
1571
+ setMap: (...args) => invokeCircleMethod("setMap", ...args),
1572
+ setOptions: (...args) => invokeCircleMethod("setOptions", ...args),
1573
+ setRadius: (...args) => invokeCircleMethod("setRadius", ...args),
1574
+ setStyles: (...args) => invokeCircleMethod("setStyles", ...args),
1575
+ setVisible: (...args) => invokeCircleMethod("setVisible", ...args),
1576
+ setZIndex: (...args) => invokeCircleMethod("setZIndex", ...args)
1577
+ }), [invokeCircleMethod]);
1578
+ (0, react.useEffect)(() => {
1579
+ if (sdkStatus !== "ready" || !targetMap || circleRef.current) return;
1580
+ try {
1581
+ const circle = new naver.maps.Circle(toCircleOptions(props, targetMap));
1582
+ circleRef.current = circle;
1583
+ bindOverlayEventListeners(circle, circleEventListenersRef, buildCircleEventBindings(props));
1584
+ props.onCircleReady?.(circle);
1585
+ } catch (error) {
1586
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Circle instance.");
1587
+ props.onCircleError?.(normalizedError);
1588
+ }
1589
+ }, [
1590
+ props,
1591
+ sdkStatus,
1592
+ targetMap
1593
+ ]);
1594
+ (0, react.useEffect)(() => {
1595
+ const circle = circleRef.current;
1596
+ if (!circle || !targetMap) return;
1597
+ circle.setOptions(toCircleOptions(props, targetMap));
1598
+ }, [props, targetMap]);
1599
+ (0, react.useEffect)(() => {
1600
+ const circle = circleRef.current;
1601
+ if (!circle) return;
1602
+ bindOverlayEventListeners(circle, circleEventListenersRef, buildCircleEventBindings(props));
1603
+ return () => {
1604
+ removeOverlayEventListeners(circleEventListenersRef.current);
1605
+ circleEventListenersRef.current = [];
1606
+ };
1607
+ }, [props]);
1608
+ (0, react.useEffect)(() => {
1609
+ return () => {
1610
+ teardownCircle();
1611
+ };
1612
+ }, [teardownCircle]);
1613
+ return null;
1614
+ });
1615
+ Circle.displayName = "Circle";
1616
+
1617
+ //#endregion
1618
+ //#region src/overlays/ellipse/Ellipse.tsx
1619
+ function toEllipseOptions(props, targetMap) {
1620
+ const options = { bounds: props.bounds };
1621
+ if (targetMap) options.map = targetMap;
1622
+ if (props.strokeWeight !== void 0) options.strokeWeight = props.strokeWeight;
1623
+ if (props.strokeOpacity !== void 0) options.strokeOpacity = props.strokeOpacity;
1624
+ if (props.strokeColor !== void 0) options.strokeColor = props.strokeColor;
1625
+ if (props.strokeStyle !== void 0) options.strokeStyle = props.strokeStyle;
1626
+ if (props.strokeLineCap !== void 0) options.strokeLineCap = props.strokeLineCap;
1627
+ if (props.strokeLineJoin !== void 0) options.strokeLineJoin = props.strokeLineJoin;
1628
+ if (props.fillColor !== void 0) options.fillColor = props.fillColor;
1629
+ if (props.fillOpacity !== void 0) options.fillOpacity = props.fillOpacity;
1630
+ if (props.clickable !== void 0) options.clickable = props.clickable;
1631
+ if (props.visible !== void 0) options.visible = props.visible;
1632
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
1633
+ return options;
1634
+ }
1635
+ function buildEllipseEventBindings(props) {
1636
+ return [
1637
+ {
1638
+ eventName: "click",
1639
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
1640
+ },
1641
+ {
1642
+ eventName: "dblclick",
1643
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
1644
+ },
1645
+ {
1646
+ eventName: "mousedown",
1647
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
1648
+ },
1649
+ {
1650
+ eventName: "mousemove",
1651
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
1652
+ },
1653
+ {
1654
+ eventName: "mouseout",
1655
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
1656
+ },
1657
+ {
1658
+ eventName: "mouseover",
1659
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
1660
+ },
1661
+ {
1662
+ eventName: "mouseup",
1663
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
1664
+ },
1665
+ {
1666
+ eventName: "rightclick",
1667
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
1668
+ },
1669
+ {
1670
+ eventName: "touchstart",
1671
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
1672
+ },
1673
+ {
1674
+ eventName: "touchmove",
1675
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
1676
+ },
1677
+ {
1678
+ eventName: "touchend",
1679
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
1680
+ },
1681
+ {
1682
+ eventName: "bounds_changed",
1683
+ invoke: props.onBoundsChanged ? (event) => props.onBoundsChanged?.(event) : void 0
1684
+ },
1685
+ {
1686
+ eventName: "clickable_changed",
1687
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
1688
+ },
1689
+ {
1690
+ eventName: "fillColor_changed",
1691
+ invoke: props.onFillColorChanged ? (event) => props.onFillColorChanged?.(event) : void 0
1692
+ },
1693
+ {
1694
+ eventName: "fillOpacity_changed",
1695
+ invoke: props.onFillOpacityChanged ? (event) => props.onFillOpacityChanged?.(event) : void 0
1696
+ },
1697
+ {
1698
+ eventName: "map_changed",
1699
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
1700
+ },
1701
+ {
1702
+ eventName: "strokeColor_changed",
1703
+ invoke: props.onStrokeColorChanged ? (event) => props.onStrokeColorChanged?.(event) : void 0
1704
+ },
1705
+ {
1706
+ eventName: "strokeLineCap_changed",
1707
+ invoke: props.onStrokeLineCapChanged ? (event) => props.onStrokeLineCapChanged?.(event) : void 0
1708
+ },
1709
+ {
1710
+ eventName: "strokeLineJoin_changed",
1711
+ invoke: props.onStrokeLineJoinChanged ? (event) => props.onStrokeLineJoinChanged?.(event) : void 0
1712
+ },
1713
+ {
1714
+ eventName: "strokeOpacity_changed",
1715
+ invoke: props.onStrokeOpacityChanged ? (event) => props.onStrokeOpacityChanged?.(event) : void 0
1716
+ },
1717
+ {
1718
+ eventName: "strokeStyle_changed",
1719
+ invoke: props.onStrokeStyleChanged ? (event) => props.onStrokeStyleChanged?.(event) : void 0
1720
+ },
1721
+ {
1722
+ eventName: "strokeWeight_changed",
1723
+ invoke: props.onStrokeWeightChanged ? (event) => props.onStrokeWeightChanged?.(event) : void 0
1724
+ },
1725
+ {
1726
+ eventName: "visible_changed",
1727
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
1728
+ },
1729
+ {
1730
+ eventName: "zIndex_changed",
1731
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
1732
+ }
1733
+ ];
1734
+ }
1735
+ const Ellipse = (0, react.forwardRef)(function EllipseInner(props, ref) {
1736
+ const { map: contextMap, sdkStatus } = useNaverMap();
1737
+ const ellipseRef = (0, react.useRef)(null);
1738
+ const ellipseEventListenersRef = (0, react.useRef)([]);
1739
+ const onEllipseDestroyRef = (0, react.useRef)(props.onEllipseDestroy);
1740
+ const targetMap = props.map ?? contextMap;
1741
+ (0, react.useEffect)(() => {
1742
+ onEllipseDestroyRef.current = props.onEllipseDestroy;
1743
+ }, [props.onEllipseDestroy]);
1744
+ const invokeEllipseMethod = (0, react.useCallback)((methodName, ...args) => {
1745
+ const ellipse = ellipseRef.current;
1746
+ if (!ellipse) return;
1747
+ const method = ellipse[methodName];
1748
+ if (typeof method !== "function") return;
1749
+ return method.apply(ellipse, args);
1750
+ }, []);
1751
+ const teardownEllipse = (0, react.useCallback)(() => {
1752
+ const ellipse = ellipseRef.current;
1753
+ if (!ellipse) return;
1754
+ try {
1755
+ removeOverlayEventListeners(ellipseEventListenersRef.current);
1756
+ ellipseEventListenersRef.current = [];
1757
+ naver.maps.Event.clearInstanceListeners(ellipse);
1758
+ } catch (error) {
1759
+ console.error("[react-naver-maps-kit] failed to clear ellipse listeners", error);
1760
+ }
1761
+ ellipse.setMap(null);
1762
+ ellipseRef.current = null;
1763
+ onEllipseDestroyRef.current?.();
1764
+ }, []);
1765
+ (0, react.useImperativeHandle)(ref, () => ({
1766
+ getInstance: () => ellipseRef.current,
1767
+ getAreaSize: (...args) => invokeEllipseMethod("getAreaSize", ...args),
1768
+ getBounds: (...args) => invokeEllipseMethod("getBounds", ...args),
1769
+ getClickable: (...args) => invokeEllipseMethod("getClickable", ...args),
1770
+ getDrawingRect: (...args) => invokeEllipseMethod("getDrawingRect", ...args),
1771
+ getElement: (...args) => invokeEllipseMethod("getElement", ...args),
1772
+ getMap: (...args) => invokeEllipseMethod("getMap", ...args),
1773
+ getOptions: (...args) => invokeEllipseMethod("getOptions", ...args),
1774
+ getPanes: (...args) => invokeEllipseMethod("getPanes", ...args),
1775
+ getProjection: (...args) => invokeEllipseMethod("getProjection", ...args),
1776
+ getStyles: (...args) => invokeEllipseMethod("getStyles", ...args),
1777
+ getVisible: (...args) => invokeEllipseMethod("getVisible", ...args),
1778
+ getZIndex: (...args) => invokeEllipseMethod("getZIndex", ...args),
1779
+ setBounds: (...args) => invokeEllipseMethod("setBounds", ...args),
1780
+ setClickable: (...args) => invokeEllipseMethod("setClickable", ...args),
1781
+ setMap: (...args) => invokeEllipseMethod("setMap", ...args),
1782
+ setOptions: (...args) => invokeEllipseMethod("setOptions", ...args),
1783
+ setStyles: (...args) => invokeEllipseMethod("setStyles", ...args),
1784
+ setVisible: (...args) => invokeEllipseMethod("setVisible", ...args),
1785
+ setZIndex: (...args) => invokeEllipseMethod("setZIndex", ...args)
1786
+ }), [invokeEllipseMethod]);
1787
+ (0, react.useEffect)(() => {
1788
+ if (sdkStatus !== "ready" || !targetMap || ellipseRef.current) return;
1789
+ try {
1790
+ const ellipse = new naver.maps.Ellipse(toEllipseOptions(props, targetMap));
1791
+ ellipseRef.current = ellipse;
1792
+ bindOverlayEventListeners(ellipse, ellipseEventListenersRef, buildEllipseEventBindings(props));
1793
+ props.onEllipseReady?.(ellipse);
1794
+ } catch (error) {
1795
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Ellipse instance.");
1796
+ props.onEllipseError?.(normalizedError);
1797
+ }
1798
+ }, [
1799
+ props,
1800
+ sdkStatus,
1801
+ targetMap
1802
+ ]);
1803
+ (0, react.useEffect)(() => {
1804
+ const ellipse = ellipseRef.current;
1805
+ if (!ellipse || !targetMap) return;
1806
+ ellipse.setOptions(toEllipseOptions(props, targetMap));
1807
+ }, [props, targetMap]);
1808
+ (0, react.useEffect)(() => {
1809
+ const ellipse = ellipseRef.current;
1810
+ if (!ellipse) return;
1811
+ bindOverlayEventListeners(ellipse, ellipseEventListenersRef, buildEllipseEventBindings(props));
1812
+ return () => {
1813
+ removeOverlayEventListeners(ellipseEventListenersRef.current);
1814
+ ellipseEventListenersRef.current = [];
1815
+ };
1816
+ }, [props]);
1817
+ (0, react.useEffect)(() => {
1818
+ return () => {
1819
+ teardownEllipse();
1820
+ };
1821
+ }, [teardownEllipse]);
1822
+ return null;
1823
+ });
1824
+ Ellipse.displayName = "Ellipse";
1825
+
1826
+ //#endregion
1827
+ //#region src/overlays/ground-overlay/GroundOverlay.tsx
1828
+ function toGroundOverlayOptions(props, targetMap) {
1829
+ const options = {};
1830
+ if (targetMap) options.map = targetMap;
1831
+ if (props.clickable !== void 0) options.clickable = props.clickable;
1832
+ if (props.opacity !== void 0) options.opacity = props.opacity;
1833
+ return options;
1834
+ }
1835
+ function buildGroundOverlayEventBindings(props) {
1836
+ return [
1837
+ {
1838
+ eventName: "click",
1839
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
1840
+ },
1841
+ {
1842
+ eventName: "dblclick",
1843
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
1844
+ },
1845
+ {
1846
+ eventName: "mousedown",
1847
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
1848
+ },
1849
+ {
1850
+ eventName: "mousemove",
1851
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
1852
+ },
1853
+ {
1854
+ eventName: "mouseout",
1855
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
1856
+ },
1857
+ {
1858
+ eventName: "mouseover",
1859
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
1860
+ },
1861
+ {
1862
+ eventName: "mouseup",
1863
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
1864
+ },
1865
+ {
1866
+ eventName: "rightclick",
1867
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
1868
+ },
1869
+ {
1870
+ eventName: "touchstart",
1871
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
1872
+ },
1873
+ {
1874
+ eventName: "touchmove",
1875
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
1876
+ },
1877
+ {
1878
+ eventName: "touchend",
1879
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
1880
+ },
1881
+ {
1882
+ eventName: "bounds_changed",
1883
+ invoke: props.onBoundsChanged ? (event) => props.onBoundsChanged?.(event) : void 0
1884
+ },
1885
+ {
1886
+ eventName: "clickable_changed",
1887
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
1888
+ },
1889
+ {
1890
+ eventName: "map_changed",
1891
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
1892
+ },
1893
+ {
1894
+ eventName: "opacity_changed",
1895
+ invoke: props.onOpacityChanged ? (event) => props.onOpacityChanged?.(event) : void 0
1896
+ }
1897
+ ];
1898
+ }
1899
+ const GroundOverlay = (0, react.forwardRef)(function GroundOverlayInner(props, ref) {
1900
+ const { map: contextMap, sdkStatus } = useNaverMap();
1901
+ const groundOverlayRef = (0, react.useRef)(null);
1902
+ const groundOverlayEventListenersRef = (0, react.useRef)([]);
1903
+ const onGroundOverlayDestroyRef = (0, react.useRef)(props.onGroundOverlayDestroy);
1904
+ const targetMap = props.map ?? contextMap;
1905
+ (0, react.useEffect)(() => {
1906
+ onGroundOverlayDestroyRef.current = props.onGroundOverlayDestroy;
1907
+ }, [props.onGroundOverlayDestroy]);
1908
+ const invokeGroundOverlayMethod = (0, react.useCallback)((methodName, ...args) => {
1909
+ const groundOverlay = groundOverlayRef.current;
1910
+ if (!groundOverlay) return;
1911
+ const method = groundOverlay[methodName];
1912
+ if (typeof method !== "function") return;
1913
+ return method.apply(groundOverlay, args);
1914
+ }, []);
1915
+ const teardownGroundOverlay = (0, react.useCallback)(() => {
1916
+ const groundOverlay = groundOverlayRef.current;
1917
+ if (!groundOverlay) return;
1918
+ try {
1919
+ removeOverlayEventListeners(groundOverlayEventListenersRef.current);
1920
+ groundOverlayEventListenersRef.current = [];
1921
+ naver.maps.Event.clearInstanceListeners(groundOverlay);
1922
+ } catch (error) {
1923
+ console.error("[react-naver-maps-kit] failed to clear ground overlay listeners", error);
1924
+ }
1925
+ groundOverlay.setMap(null);
1926
+ groundOverlayRef.current = null;
1927
+ onGroundOverlayDestroyRef.current?.();
1928
+ }, []);
1929
+ (0, react.useImperativeHandle)(ref, () => ({
1930
+ getInstance: () => groundOverlayRef.current,
1931
+ getBounds: (...args) => invokeGroundOverlayMethod("getBounds", ...args),
1932
+ getMap: (...args) => invokeGroundOverlayMethod("getMap", ...args),
1933
+ getOpacity: (...args) => invokeGroundOverlayMethod("getOpacity", ...args),
1934
+ getPanes: (...args) => invokeGroundOverlayMethod("getPanes", ...args),
1935
+ getProjection: (...args) => invokeGroundOverlayMethod("getProjection", ...args),
1936
+ getUrl: (...args) => invokeGroundOverlayMethod("getUrl", ...args),
1937
+ setMap: (...args) => invokeGroundOverlayMethod("setMap", ...args),
1938
+ setOpacity: (...args) => invokeGroundOverlayMethod("setOpacity", ...args)
1939
+ }), [invokeGroundOverlayMethod]);
1940
+ (0, react.useEffect)(() => {
1941
+ if (sdkStatus !== "ready" || !targetMap || groundOverlayRef.current) return;
1942
+ try {
1943
+ const groundOverlay = new naver.maps.GroundOverlay(props.url, props.bounds, toGroundOverlayOptions(props, targetMap));
1944
+ groundOverlayRef.current = groundOverlay;
1945
+ bindOverlayEventListeners(groundOverlay, groundOverlayEventListenersRef, buildGroundOverlayEventBindings(props));
1946
+ props.onGroundOverlayReady?.(groundOverlay);
1947
+ } catch (error) {
1948
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.GroundOverlay instance.");
1949
+ props.onGroundOverlayError?.(normalizedError);
1950
+ }
1951
+ }, [
1952
+ props,
1953
+ sdkStatus,
1954
+ targetMap
1955
+ ]);
1956
+ (0, react.useEffect)(() => {
1957
+ const groundOverlay = groundOverlayRef.current;
1958
+ if (!groundOverlay || !targetMap) return;
1959
+ groundOverlay.setMap(targetMap);
1960
+ if (props.opacity !== void 0) groundOverlay.setOpacity(props.opacity);
1961
+ groundOverlay.setOptions?.(toGroundOverlayOptions(props, targetMap));
1962
+ }, [props, targetMap]);
1963
+ (0, react.useEffect)(() => {
1964
+ const groundOverlay = groundOverlayRef.current;
1965
+ if (!groundOverlay) return;
1966
+ bindOverlayEventListeners(groundOverlay, groundOverlayEventListenersRef, buildGroundOverlayEventBindings(props));
1967
+ return () => {
1968
+ removeOverlayEventListeners(groundOverlayEventListenersRef.current);
1969
+ groundOverlayEventListenersRef.current = [];
1970
+ };
1971
+ }, [props]);
1972
+ (0, react.useEffect)(() => {
1973
+ return () => {
1974
+ teardownGroundOverlay();
1975
+ };
1976
+ }, [teardownGroundOverlay]);
1977
+ return null;
1978
+ });
1979
+ GroundOverlay.displayName = "GroundOverlay";
1980
+
1981
+ //#endregion
1982
+ //#region src/overlays/polygon/Polygon.tsx
1983
+ function toPolygonOptions(props, targetMap) {
1984
+ const options = { paths: props.paths };
1985
+ if (targetMap) options.map = targetMap;
1986
+ if (props.strokeWeight !== void 0) options.strokeWeight = props.strokeWeight;
1987
+ if (props.strokeOpacity !== void 0) options.strokeOpacity = props.strokeOpacity;
1988
+ if (props.strokeColor !== void 0) options.strokeColor = props.strokeColor;
1989
+ if (props.strokeStyle !== void 0) options.strokeStyle = props.strokeStyle;
1990
+ if (props.strokeLineCap !== void 0) options.strokeLineCap = props.strokeLineCap;
1991
+ if (props.strokeLineJoin !== void 0) options.strokeLineJoin = props.strokeLineJoin;
1992
+ if (props.fillColor !== void 0) options.fillColor = props.fillColor;
1993
+ if (props.fillOpacity !== void 0) options.fillOpacity = props.fillOpacity;
1994
+ if (props.clickable !== void 0) options.clickable = props.clickable;
1995
+ if (props.visible !== void 0) options.visible = props.visible;
1996
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
1997
+ return options;
1998
+ }
1999
+ function buildPolygonEventBindings(props) {
2000
+ return [
2001
+ {
2002
+ eventName: "click",
2003
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
2004
+ },
2005
+ {
2006
+ eventName: "dblclick",
2007
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
2008
+ },
2009
+ {
2010
+ eventName: "mousedown",
2011
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
2012
+ },
2013
+ {
2014
+ eventName: "mousemove",
2015
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
2016
+ },
2017
+ {
2018
+ eventName: "mouseout",
2019
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
2020
+ },
2021
+ {
2022
+ eventName: "mouseover",
2023
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
2024
+ },
2025
+ {
2026
+ eventName: "mouseup",
2027
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
2028
+ },
2029
+ {
2030
+ eventName: "rightclick",
2031
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
2032
+ },
2033
+ {
2034
+ eventName: "touchstart",
2035
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
2036
+ },
2037
+ {
2038
+ eventName: "touchmove",
2039
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
2040
+ },
2041
+ {
2042
+ eventName: "touchend",
2043
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
2044
+ },
2045
+ {
2046
+ eventName: "clickable_changed",
2047
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
2048
+ },
2049
+ {
2050
+ eventName: "fillColor_changed",
2051
+ invoke: props.onFillColorChanged ? (event) => props.onFillColorChanged?.(event) : void 0
2052
+ },
2053
+ {
2054
+ eventName: "fillOpacity_changed",
2055
+ invoke: props.onFillOpacityChanged ? (event) => props.onFillOpacityChanged?.(event) : void 0
2056
+ },
2057
+ {
2058
+ eventName: "map_changed",
2059
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
2060
+ },
2061
+ {
2062
+ eventName: "path_changed",
2063
+ invoke: props.onPathChanged ? (event) => props.onPathChanged?.(event) : void 0
2064
+ },
2065
+ {
2066
+ eventName: "paths_changed",
2067
+ invoke: props.onPathsChanged ? (event) => props.onPathsChanged?.(event) : void 0
2068
+ },
2069
+ {
2070
+ eventName: "strokeColor_changed",
2071
+ invoke: props.onStrokeColorChanged ? (event) => props.onStrokeColorChanged?.(event) : void 0
2072
+ },
2073
+ {
2074
+ eventName: "strokeLineCap_changed",
2075
+ invoke: props.onStrokeLineCapChanged ? (event) => props.onStrokeLineCapChanged?.(event) : void 0
2076
+ },
2077
+ {
2078
+ eventName: "strokeLineJoin_changed",
2079
+ invoke: props.onStrokeLineJoinChanged ? (event) => props.onStrokeLineJoinChanged?.(event) : void 0
2080
+ },
2081
+ {
2082
+ eventName: "strokeOpacity_changed",
2083
+ invoke: props.onStrokeOpacityChanged ? (event) => props.onStrokeOpacityChanged?.(event) : void 0
2084
+ },
2085
+ {
2086
+ eventName: "strokeStyle_changed",
2087
+ invoke: props.onStrokeStyleChanged ? (event) => props.onStrokeStyleChanged?.(event) : void 0
2088
+ },
2089
+ {
2090
+ eventName: "strokeWeight_changed",
2091
+ invoke: props.onStrokeWeightChanged ? (event) => props.onStrokeWeightChanged?.(event) : void 0
2092
+ },
2093
+ {
2094
+ eventName: "visible_changed",
2095
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
2096
+ },
2097
+ {
2098
+ eventName: "zIndex_changed",
2099
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
2100
+ }
2101
+ ];
2102
+ }
2103
+ const Polygon = (0, react.forwardRef)(function PolygonInner(props, ref) {
2104
+ const { map: contextMap, sdkStatus } = useNaverMap();
2105
+ const polygonRef = (0, react.useRef)(null);
2106
+ const polygonEventListenersRef = (0, react.useRef)([]);
2107
+ const onPolygonDestroyRef = (0, react.useRef)(props.onPolygonDestroy);
2108
+ const targetMap = props.map ?? contextMap;
2109
+ (0, react.useEffect)(() => {
2110
+ onPolygonDestroyRef.current = props.onPolygonDestroy;
2111
+ }, [props.onPolygonDestroy]);
2112
+ const invokePolygonMethod = (0, react.useCallback)((methodName, ...args) => {
2113
+ const polygon = polygonRef.current;
2114
+ if (!polygon) return;
2115
+ const method = polygon[methodName];
2116
+ if (typeof method !== "function") return;
2117
+ return method.apply(polygon, args);
2118
+ }, []);
2119
+ const teardownPolygon = (0, react.useCallback)(() => {
2120
+ const polygon = polygonRef.current;
2121
+ if (!polygon) return;
2122
+ try {
2123
+ removeOverlayEventListeners(polygonEventListenersRef.current);
2124
+ polygonEventListenersRef.current = [];
2125
+ naver.maps.Event.clearInstanceListeners(polygon);
2126
+ } catch (error) {
2127
+ console.error("[react-naver-maps-kit] failed to clear polygon listeners", error);
2128
+ }
2129
+ polygon.setMap(null);
2130
+ polygonRef.current = null;
2131
+ onPolygonDestroyRef.current?.();
2132
+ }, []);
2133
+ (0, react.useImperativeHandle)(ref, () => ({
2134
+ getInstance: () => polygonRef.current,
2135
+ getAreaSize: (...args) => invokePolygonMethod("getAreaSize", ...args),
2136
+ getBounds: (...args) => invokePolygonMethod("getBounds", ...args),
2137
+ getClickable: (...args) => invokePolygonMethod("getClickable", ...args),
2138
+ getDrawingRect: (...args) => invokePolygonMethod("getDrawingRect", ...args),
2139
+ getElement: (...args) => invokePolygonMethod("getElement", ...args),
2140
+ getMap: (...args) => invokePolygonMethod("getMap", ...args),
2141
+ getOptions: (...args) => invokePolygonMethod("getOptions", ...args),
2142
+ getPanes: (...args) => invokePolygonMethod("getPanes", ...args),
2143
+ getPath: (...args) => invokePolygonMethod("getPath", ...args),
2144
+ getPaths: (...args) => invokePolygonMethod("getPaths", ...args),
2145
+ getProjection: (...args) => invokePolygonMethod("getProjection", ...args),
2146
+ getStyles: (...args) => invokePolygonMethod("getStyles", ...args),
2147
+ getVisible: (...args) => invokePolygonMethod("getVisible", ...args),
2148
+ getZIndex: (...args) => invokePolygonMethod("getZIndex", ...args),
2149
+ setClickable: (...args) => invokePolygonMethod("setClickable", ...args),
2150
+ setMap: (...args) => invokePolygonMethod("setMap", ...args),
2151
+ setOptions: (...args) => invokePolygonMethod("setOptions", ...args),
2152
+ setPath: (...args) => invokePolygonMethod("setPath", ...args),
2153
+ setPaths: (...args) => invokePolygonMethod("setPaths", ...args),
2154
+ setStyles: (...args) => invokePolygonMethod("setStyles", ...args),
2155
+ setVisible: (...args) => invokePolygonMethod("setVisible", ...args),
2156
+ setZIndex: (...args) => invokePolygonMethod("setZIndex", ...args)
2157
+ }), [invokePolygonMethod]);
2158
+ (0, react.useEffect)(() => {
2159
+ if (sdkStatus !== "ready" || !targetMap || polygonRef.current) return;
2160
+ try {
2161
+ const polygon = new naver.maps.Polygon(toPolygonOptions(props, targetMap));
2162
+ polygonRef.current = polygon;
2163
+ bindOverlayEventListeners(polygon, polygonEventListenersRef, buildPolygonEventBindings(props));
2164
+ props.onPolygonReady?.(polygon);
2165
+ } catch (error) {
2166
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Polygon instance.");
2167
+ props.onPolygonError?.(normalizedError);
2168
+ }
2169
+ }, [
2170
+ props,
2171
+ sdkStatus,
2172
+ targetMap
2173
+ ]);
2174
+ (0, react.useEffect)(() => {
2175
+ const polygon = polygonRef.current;
2176
+ if (!polygon || !targetMap) return;
2177
+ polygon.setOptions(toPolygonOptions(props, targetMap));
2178
+ }, [props, targetMap]);
2179
+ (0, react.useEffect)(() => {
2180
+ const polygon = polygonRef.current;
2181
+ if (!polygon) return;
2182
+ bindOverlayEventListeners(polygon, polygonEventListenersRef, buildPolygonEventBindings(props));
2183
+ return () => {
2184
+ removeOverlayEventListeners(polygonEventListenersRef.current);
2185
+ polygonEventListenersRef.current = [];
2186
+ };
2187
+ }, [props]);
2188
+ (0, react.useEffect)(() => {
2189
+ return () => {
2190
+ teardownPolygon();
2191
+ };
2192
+ }, [teardownPolygon]);
2193
+ return null;
2194
+ });
2195
+ Polygon.displayName = "Polygon";
2196
+
2197
+ //#endregion
2198
+ //#region src/overlays/polyline/Polyline.tsx
2199
+ function toPolylineOptions(props, targetMap) {
2200
+ const options = { path: props.path };
2201
+ if (targetMap) options.map = targetMap;
2202
+ if (props.strokeWeight !== void 0) options.strokeWeight = props.strokeWeight;
2203
+ if (props.strokeOpacity !== void 0) options.strokeOpacity = props.strokeOpacity;
2204
+ if (props.strokeColor !== void 0) options.strokeColor = props.strokeColor;
2205
+ if (props.strokeStyle !== void 0) options.strokeStyle = props.strokeStyle;
2206
+ if (props.strokeLineCap !== void 0) options.strokeLineCap = props.strokeLineCap;
2207
+ if (props.strokeLineJoin !== void 0) options.strokeLineJoin = props.strokeLineJoin;
2208
+ if (props.clickable !== void 0) options.clickable = props.clickable;
2209
+ if (props.visible !== void 0) options.visible = props.visible;
2210
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
2211
+ if (props.startIcon !== void 0) options.startIcon = props.startIcon;
2212
+ if (props.startIconSize !== void 0) options.startIconSize = props.startIconSize;
2213
+ if (props.endIcon !== void 0) options.endIcon = props.endIcon;
2214
+ if (props.endIconSize !== void 0) options.endIconSize = props.endIconSize;
2215
+ return options;
2216
+ }
2217
+ function buildPolylineEventBindings(props) {
2218
+ return [
2219
+ {
2220
+ eventName: "click",
2221
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
2222
+ },
2223
+ {
2224
+ eventName: "dblclick",
2225
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
2226
+ },
2227
+ {
2228
+ eventName: "mousedown",
2229
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
2230
+ },
2231
+ {
2232
+ eventName: "mousemove",
2233
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
2234
+ },
2235
+ {
2236
+ eventName: "mouseout",
2237
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
2238
+ },
2239
+ {
2240
+ eventName: "mouseover",
2241
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
2242
+ },
2243
+ {
2244
+ eventName: "mouseup",
2245
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
2246
+ },
2247
+ {
2248
+ eventName: "rightclick",
2249
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
2250
+ },
2251
+ {
2252
+ eventName: "touchstart",
2253
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
2254
+ },
2255
+ {
2256
+ eventName: "touchmove",
2257
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
2258
+ },
2259
+ {
2260
+ eventName: "touchend",
2261
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
2262
+ },
2263
+ {
2264
+ eventName: "clickable_changed",
2265
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
2266
+ },
2267
+ {
2268
+ eventName: "endIcon_changed",
2269
+ invoke: props.onEndIconChanged ? (event) => props.onEndIconChanged?.(event) : void 0
2270
+ },
2271
+ {
2272
+ eventName: "endIconSize_changed",
2273
+ invoke: props.onEndIconSizeChanged ? (event) => props.onEndIconSizeChanged?.(event) : void 0
2274
+ },
2275
+ {
2276
+ eventName: "map_changed",
2277
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
2278
+ },
2279
+ {
2280
+ eventName: "path_changed",
2281
+ invoke: props.onPathChanged ? (event) => props.onPathChanged?.(event) : void 0
2282
+ },
2283
+ {
2284
+ eventName: "startIcon_changed",
2285
+ invoke: props.onStartIconChanged ? (event) => props.onStartIconChanged?.(event) : void 0
2286
+ },
2287
+ {
2288
+ eventName: "startIconSize_changed",
2289
+ invoke: props.onStartIconSizeChanged ? (event) => props.onStartIconSizeChanged?.(event) : void 0
2290
+ },
2291
+ {
2292
+ eventName: "strokeColor_changed",
2293
+ invoke: props.onStrokeColorChanged ? (event) => props.onStrokeColorChanged?.(event) : void 0
2294
+ },
2295
+ {
2296
+ eventName: "strokeLineCap_changed",
2297
+ invoke: props.onStrokeLineCapChanged ? (event) => props.onStrokeLineCapChanged?.(event) : void 0
2298
+ },
2299
+ {
2300
+ eventName: "strokeLineJoin_changed",
2301
+ invoke: props.onStrokeLineJoinChanged ? (event) => props.onStrokeLineJoinChanged?.(event) : void 0
2302
+ },
2303
+ {
2304
+ eventName: "strokeOpacity_changed",
2305
+ invoke: props.onStrokeOpacityChanged ? (event) => props.onStrokeOpacityChanged?.(event) : void 0
2306
+ },
2307
+ {
2308
+ eventName: "strokeStyle_changed",
2309
+ invoke: props.onStrokeStyleChanged ? (event) => props.onStrokeStyleChanged?.(event) : void 0
2310
+ },
2311
+ {
2312
+ eventName: "strokeWeight_changed",
2313
+ invoke: props.onStrokeWeightChanged ? (event) => props.onStrokeWeightChanged?.(event) : void 0
2314
+ },
2315
+ {
2316
+ eventName: "visible_changed",
2317
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
2318
+ },
2319
+ {
2320
+ eventName: "zIndex_changed",
2321
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
2322
+ }
2323
+ ];
2324
+ }
2325
+ const Polyline = (0, react.forwardRef)(function PolylineInner(props, ref) {
2326
+ const { map: contextMap, sdkStatus } = useNaverMap();
2327
+ const polylineRef = (0, react.useRef)(null);
2328
+ const polylineEventListenersRef = (0, react.useRef)([]);
2329
+ const onPolylineDestroyRef = (0, react.useRef)(props.onPolylineDestroy);
2330
+ const targetMap = props.map ?? contextMap;
2331
+ (0, react.useEffect)(() => {
2332
+ onPolylineDestroyRef.current = props.onPolylineDestroy;
2333
+ }, [props.onPolylineDestroy]);
2334
+ const invokePolylineMethod = (0, react.useCallback)((methodName, ...args) => {
2335
+ const polyline = polylineRef.current;
2336
+ if (!polyline) return;
2337
+ const method = polyline[methodName];
2338
+ if (typeof method !== "function") return;
2339
+ return method.apply(polyline, args);
2340
+ }, []);
2341
+ const teardownPolyline = (0, react.useCallback)(() => {
2342
+ const polyline = polylineRef.current;
2343
+ if (!polyline) return;
2344
+ try {
2345
+ removeOverlayEventListeners(polylineEventListenersRef.current);
2346
+ polylineEventListenersRef.current = [];
2347
+ naver.maps.Event.clearInstanceListeners(polyline);
2348
+ } catch (error) {
2349
+ console.error("[react-naver-maps-kit] failed to clear polyline listeners", error);
2350
+ }
2351
+ polyline.setMap(null);
2352
+ polylineRef.current = null;
2353
+ onPolylineDestroyRef.current?.();
2354
+ }, []);
2355
+ (0, react.useImperativeHandle)(ref, () => ({
2356
+ getInstance: () => polylineRef.current,
2357
+ getBounds: (...args) => invokePolylineMethod("getBounds", ...args),
2358
+ getClickable: (...args) => invokePolylineMethod("getClickable", ...args),
2359
+ getDistance: (...args) => invokePolylineMethod("getDistance", ...args),
2360
+ getDrawingRect: (...args) => invokePolylineMethod("getDrawingRect", ...args),
2361
+ getElement: (...args) => invokePolylineMethod("getElement", ...args),
2362
+ getMap: (...args) => invokePolylineMethod("getMap", ...args),
2363
+ getOptions: (...args) => invokePolylineMethod("getOptions", ...args),
2364
+ getPanes: (...args) => invokePolylineMethod("getPanes", ...args),
2365
+ getPath: (...args) => invokePolylineMethod("getPath", ...args),
2366
+ getProjection: (...args) => invokePolylineMethod("getProjection", ...args),
2367
+ getStyles: (...args) => invokePolylineMethod("getStyles", ...args),
2368
+ getVisible: (...args) => invokePolylineMethod("getVisible", ...args),
2369
+ getZIndex: (...args) => invokePolylineMethod("getZIndex", ...args),
2370
+ setClickable: (...args) => invokePolylineMethod("setClickable", ...args),
2371
+ setMap: (...args) => invokePolylineMethod("setMap", ...args),
2372
+ setOptions: (...args) => invokePolylineMethod("setOptions", ...args),
2373
+ setPath: (...args) => invokePolylineMethod("setPath", ...args),
2374
+ setStyles: (...args) => invokePolylineMethod("setStyles", ...args),
2375
+ setVisible: (...args) => invokePolylineMethod("setVisible", ...args),
2376
+ setZIndex: (...args) => invokePolylineMethod("setZIndex", ...args)
2377
+ }), [invokePolylineMethod]);
2378
+ (0, react.useEffect)(() => {
2379
+ if (sdkStatus !== "ready" || !targetMap || polylineRef.current) return;
2380
+ try {
2381
+ const polyline = new naver.maps.Polyline(toPolylineOptions(props, targetMap));
2382
+ polylineRef.current = polyline;
2383
+ bindOverlayEventListeners(polyline, polylineEventListenersRef, buildPolylineEventBindings(props));
2384
+ props.onPolylineReady?.(polyline);
2385
+ } catch (error) {
2386
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Polyline instance.");
2387
+ props.onPolylineError?.(normalizedError);
2388
+ }
2389
+ }, [
2390
+ props,
2391
+ sdkStatus,
2392
+ targetMap
2393
+ ]);
2394
+ (0, react.useEffect)(() => {
2395
+ const polyline = polylineRef.current;
2396
+ if (!polyline || !targetMap) return;
2397
+ polyline.setOptions(toPolylineOptions(props, targetMap));
2398
+ }, [props, targetMap]);
2399
+ (0, react.useEffect)(() => {
2400
+ const polyline = polylineRef.current;
2401
+ if (!polyline) return;
2402
+ bindOverlayEventListeners(polyline, polylineEventListenersRef, buildPolylineEventBindings(props));
2403
+ return () => {
2404
+ removeOverlayEventListeners(polylineEventListenersRef.current);
2405
+ polylineEventListenersRef.current = [];
2406
+ };
2407
+ }, [props]);
2408
+ (0, react.useEffect)(() => {
2409
+ return () => {
2410
+ teardownPolyline();
2411
+ };
2412
+ }, [teardownPolyline]);
2413
+ return null;
2414
+ });
2415
+ Polyline.displayName = "Polyline";
2416
+
2417
+ //#endregion
2418
+ //#region src/overlays/rectangle/Rectangle.tsx
2419
+ function toRectangleOptions(props, targetMap) {
2420
+ const options = { bounds: props.bounds };
2421
+ if (targetMap) options.map = targetMap;
2422
+ if (props.strokeWeight !== void 0) options.strokeWeight = props.strokeWeight;
2423
+ if (props.strokeOpacity !== void 0) options.strokeOpacity = props.strokeOpacity;
2424
+ if (props.strokeColor !== void 0) options.strokeColor = props.strokeColor;
2425
+ if (props.strokeStyle !== void 0) options.strokeStyle = props.strokeStyle;
2426
+ if (props.strokeLineCap !== void 0) options.strokeLineCap = props.strokeLineCap;
2427
+ if (props.strokeLineJoin !== void 0) options.strokeLineJoin = props.strokeLineJoin;
2428
+ if (props.fillColor !== void 0) options.fillColor = props.fillColor;
2429
+ if (props.fillOpacity !== void 0) options.fillOpacity = props.fillOpacity;
2430
+ if (props.clickable !== void 0) options.clickable = props.clickable;
2431
+ if (props.visible !== void 0) options.visible = props.visible;
2432
+ if (props.zIndex !== void 0) options.zIndex = props.zIndex;
2433
+ return options;
2434
+ }
2435
+ function buildRectangleEventBindings(props) {
2436
+ return [
2437
+ {
2438
+ eventName: "click",
2439
+ invoke: props.onClick ? (event) => props.onClick?.(event) : void 0
2440
+ },
2441
+ {
2442
+ eventName: "dblclick",
2443
+ invoke: props.onDblClick ? (event) => props.onDblClick?.(event) : void 0
2444
+ },
2445
+ {
2446
+ eventName: "mousedown",
2447
+ invoke: props.onMouseDown ? (event) => props.onMouseDown?.(event) : void 0
2448
+ },
2449
+ {
2450
+ eventName: "mousemove",
2451
+ invoke: props.onMouseMove ? (event) => props.onMouseMove?.(event) : void 0
2452
+ },
2453
+ {
2454
+ eventName: "mouseout",
2455
+ invoke: props.onMouseOut ? (event) => props.onMouseOut?.(event) : void 0
2456
+ },
2457
+ {
2458
+ eventName: "mouseover",
2459
+ invoke: props.onMouseOver ? (event) => props.onMouseOver?.(event) : void 0
2460
+ },
2461
+ {
2462
+ eventName: "mouseup",
2463
+ invoke: props.onMouseUp ? (event) => props.onMouseUp?.(event) : void 0
2464
+ },
2465
+ {
2466
+ eventName: "rightclick",
2467
+ invoke: props.onRightClick ? (event) => props.onRightClick?.(event) : void 0
2468
+ },
2469
+ {
2470
+ eventName: "touchstart",
2471
+ invoke: props.onTouchStart ? (event) => props.onTouchStart?.(event) : void 0
2472
+ },
2473
+ {
2474
+ eventName: "touchmove",
2475
+ invoke: props.onTouchMove ? (event) => props.onTouchMove?.(event) : void 0
2476
+ },
2477
+ {
2478
+ eventName: "touchend",
2479
+ invoke: props.onTouchEnd ? (event) => props.onTouchEnd?.(event) : void 0
2480
+ },
2481
+ {
2482
+ eventName: "bounds_changed",
2483
+ invoke: props.onBoundsChanged ? (event) => props.onBoundsChanged?.(event) : void 0
2484
+ },
2485
+ {
2486
+ eventName: "clickable_changed",
2487
+ invoke: props.onClickableChanged ? (event) => props.onClickableChanged?.(event) : void 0
2488
+ },
2489
+ {
2490
+ eventName: "fillColor_changed",
2491
+ invoke: props.onFillColorChanged ? (event) => props.onFillColorChanged?.(event) : void 0
2492
+ },
2493
+ {
2494
+ eventName: "fillOpacity_changed",
2495
+ invoke: props.onFillOpacityChanged ? (event) => props.onFillOpacityChanged?.(event) : void 0
2496
+ },
2497
+ {
2498
+ eventName: "map_changed",
2499
+ invoke: props.onMapChanged ? (event) => props.onMapChanged?.(event) : void 0
2500
+ },
2501
+ {
2502
+ eventName: "strokeColor_changed",
2503
+ invoke: props.onStrokeColorChanged ? (event) => props.onStrokeColorChanged?.(event) : void 0
2504
+ },
2505
+ {
2506
+ eventName: "strokeLineCap_changed",
2507
+ invoke: props.onStrokeLineCapChanged ? (event) => props.onStrokeLineCapChanged?.(event) : void 0
2508
+ },
2509
+ {
2510
+ eventName: "strokeLineJoin_changed",
2511
+ invoke: props.onStrokeLineJoinChanged ? (event) => props.onStrokeLineJoinChanged?.(event) : void 0
2512
+ },
2513
+ {
2514
+ eventName: "strokeOpacity_changed",
2515
+ invoke: props.onStrokeOpacityChanged ? (event) => props.onStrokeOpacityChanged?.(event) : void 0
2516
+ },
2517
+ {
2518
+ eventName: "strokeStyle_changed",
2519
+ invoke: props.onStrokeStyleChanged ? (event) => props.onStrokeStyleChanged?.(event) : void 0
2520
+ },
2521
+ {
2522
+ eventName: "strokeWeight_changed",
2523
+ invoke: props.onStrokeWeightChanged ? (event) => props.onStrokeWeightChanged?.(event) : void 0
2524
+ },
2525
+ {
2526
+ eventName: "visible_changed",
2527
+ invoke: props.onVisibleChanged ? (event) => props.onVisibleChanged?.(event) : void 0
2528
+ },
2529
+ {
2530
+ eventName: "zIndex_changed",
2531
+ invoke: props.onZIndexChanged ? (event) => props.onZIndexChanged?.(event) : void 0
2532
+ }
2533
+ ];
2534
+ }
2535
+ const Rectangle = (0, react.forwardRef)(function RectangleInner(props, ref) {
2536
+ const { map: contextMap, sdkStatus } = useNaverMap();
2537
+ const rectangleRef = (0, react.useRef)(null);
2538
+ const rectangleEventListenersRef = (0, react.useRef)([]);
2539
+ const onRectangleDestroyRef = (0, react.useRef)(props.onRectangleDestroy);
2540
+ const targetMap = props.map ?? contextMap;
2541
+ (0, react.useEffect)(() => {
2542
+ onRectangleDestroyRef.current = props.onRectangleDestroy;
2543
+ }, [props.onRectangleDestroy]);
2544
+ const invokeRectangleMethod = (0, react.useCallback)((methodName, ...args) => {
2545
+ const rectangle = rectangleRef.current;
2546
+ if (!rectangle) return;
2547
+ const method = rectangle[methodName];
2548
+ if (typeof method !== "function") return;
2549
+ return method.apply(rectangle, args);
2550
+ }, []);
2551
+ const teardownRectangle = (0, react.useCallback)(() => {
2552
+ const rectangle = rectangleRef.current;
2553
+ if (!rectangle) return;
2554
+ try {
2555
+ removeOverlayEventListeners(rectangleEventListenersRef.current);
2556
+ rectangleEventListenersRef.current = [];
2557
+ naver.maps.Event.clearInstanceListeners(rectangle);
2558
+ } catch (error) {
2559
+ console.error("[react-naver-maps-kit] failed to clear rectangle listeners", error);
2560
+ }
2561
+ rectangle.setMap(null);
2562
+ rectangleRef.current = null;
2563
+ onRectangleDestroyRef.current?.();
2564
+ }, []);
2565
+ (0, react.useImperativeHandle)(ref, () => ({
2566
+ getInstance: () => rectangleRef.current,
2567
+ getAreaSize: (...args) => invokeRectangleMethod("getAreaSize", ...args),
2568
+ getBounds: (...args) => invokeRectangleMethod("getBounds", ...args),
2569
+ getClickable: (...args) => invokeRectangleMethod("getClickable", ...args),
2570
+ getDrawingRect: (...args) => invokeRectangleMethod("getDrawingRect", ...args),
2571
+ getElement: (...args) => invokeRectangleMethod("getElement", ...args),
2572
+ getMap: (...args) => invokeRectangleMethod("getMap", ...args),
2573
+ getOptions: (...args) => invokeRectangleMethod("getOptions", ...args),
2574
+ getPanes: (...args) => invokeRectangleMethod("getPanes", ...args),
2575
+ getProjection: (...args) => invokeRectangleMethod("getProjection", ...args),
2576
+ getStyles: (...args) => invokeRectangleMethod("getStyles", ...args),
2577
+ getVisible: (...args) => invokeRectangleMethod("getVisible", ...args),
2578
+ getZIndex: (...args) => invokeRectangleMethod("getZIndex", ...args),
2579
+ setBounds: (...args) => invokeRectangleMethod("setBounds", ...args),
2580
+ setClickable: (...args) => invokeRectangleMethod("setClickable", ...args),
2581
+ setMap: (...args) => invokeRectangleMethod("setMap", ...args),
2582
+ setOptions: (...args) => invokeRectangleMethod("setOptions", ...args),
2583
+ setStyles: (...args) => invokeRectangleMethod("setStyles", ...args),
2584
+ setVisible: (...args) => invokeRectangleMethod("setVisible", ...args),
2585
+ setZIndex: (...args) => invokeRectangleMethod("setZIndex", ...args)
2586
+ }), [invokeRectangleMethod]);
2587
+ (0, react.useEffect)(() => {
2588
+ if (sdkStatus !== "ready" || !targetMap || rectangleRef.current) return;
2589
+ try {
2590
+ const rectangle = new naver.maps.Rectangle(toRectangleOptions(props, targetMap));
2591
+ rectangleRef.current = rectangle;
2592
+ bindOverlayEventListeners(rectangle, rectangleEventListenersRef, buildRectangleEventBindings(props));
2593
+ props.onRectangleReady?.(rectangle);
2594
+ } catch (error) {
2595
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new Error("Failed to create naver.maps.Rectangle instance.");
2596
+ props.onRectangleError?.(normalizedError);
2597
+ }
2598
+ }, [
2599
+ props,
2600
+ sdkStatus,
2601
+ targetMap
2602
+ ]);
2603
+ (0, react.useEffect)(() => {
2604
+ const rectangle = rectangleRef.current;
2605
+ if (!rectangle || !targetMap) return;
2606
+ rectangle.setOptions(toRectangleOptions(props, targetMap));
2607
+ }, [props, targetMap]);
2608
+ (0, react.useEffect)(() => {
2609
+ const rectangle = rectangleRef.current;
2610
+ if (!rectangle) return;
2611
+ bindOverlayEventListeners(rectangle, rectangleEventListenersRef, buildRectangleEventBindings(props));
2612
+ return () => {
2613
+ removeOverlayEventListeners(rectangleEventListenersRef.current);
2614
+ rectangleEventListenersRef.current = [];
2615
+ };
2616
+ }, [props]);
2617
+ (0, react.useEffect)(() => {
2618
+ return () => {
2619
+ teardownRectangle();
2620
+ };
2621
+ }, [teardownRectangle]);
2622
+ return null;
2623
+ });
2624
+ Rectangle.displayName = "Rectangle";
2625
+
2626
+ //#endregion
2627
+ //#region src/index.ts
2628
+ const version = "0.0.1";
2629
+
2630
+ //#endregion
2631
+ exports.Circle = Circle;
2632
+ exports.Ellipse = Ellipse;
2633
+ exports.GroundOverlay = GroundOverlay;
2634
+ exports.InfoWindow = InfoWindow;
2635
+ exports.Marker = Marker;
2636
+ exports.NaverMap = NaverMap;
2637
+ exports.NaverMapContext = NaverMapContext;
2638
+ exports.NaverMapProvider = NaverMapProvider;
2639
+ exports.Polygon = Polygon;
2640
+ exports.Polyline = Polyline;
2641
+ exports.Rectangle = Rectangle;
2642
+ exports.loadNaverMapsScript = loadNaverMapsScript;
2643
+ exports.useNaverMap = useNaverMap;
2644
+ exports.useNaverMapInstance = useNaverMapInstance;
2645
+ exports.version = version;
2646
+ //# sourceMappingURL=index.cjs.map