@mint-ui/map 1.2.0-test.62 → 1.2.0-test.65

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.
@@ -24,28 +24,48 @@ var Konva__default = /*#__PURE__*/_interopDefaultLegacy(Konva);
24
24
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
25
25
 
26
26
  var CanvasMarkerLayer = function (props) {
27
+ // 타입 가드: renderEvent가 있는지 확인
28
+ var hasRenderEvent = 'renderEvent' in props && props.renderEvent !== undefined; // renderEvent가 있는 경우와 없는 경우를 구분하여 props 추출
29
+
27
30
  var data = props.data,
28
- onClick = props.onClick,
29
- onMouseOver = props.onMouseOver,
30
- onMouseOut = props.onMouseOut,
31
- _a = props.enableMultiSelect,
32
- enableMultiSelect = _a === void 0 ? false : _a,
33
- _b = props.topOnHover,
34
- topOnHover = _b === void 0 ? false : _b,
35
- _c = props.enableViewportCulling,
36
- enableViewportCulling = _c === void 0 ? false : _c,
37
- _d = props.cullingMargin,
38
- cullingMargin = _d === void 0 ? performance.DEFAULT_CULLING_MARGIN : _d,
39
- _e = props.maxCacheSize,
40
- maxCacheSize = _e === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _e,
41
- externalSelectedItems = props.selectedItems,
42
- externalSelectedItem = props.selectedItem,
43
- _f = props.disableInteraction,
44
- disableInteraction = _f === void 0 ? false : _f,
31
+ _a = props.enableViewportCulling,
32
+ enableViewportCulling = _a === void 0 ? false : _a,
33
+ _b = props.cullingMargin,
34
+ cullingMargin = _b === void 0 ? performance.DEFAULT_CULLING_MARGIN : _b,
35
+ _c = props.maxCacheSize,
36
+ maxCacheSize = _c === void 0 ? performance.DEFAULT_MAX_CACHE_SIZE : _c,
45
37
  renderBase = props.renderBase,
46
- renderEvent = props.renderEvent,
47
- options = tslib.__rest(props, ["data", "onClick", "onMouseOver", "onMouseOut", "enableMultiSelect", "topOnHover", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction", "renderBase", "renderEvent"]);
48
-
38
+ options = tslib.__rest(props, ["data", "enableViewportCulling", "cullingMargin", "maxCacheSize", "renderBase"]); // renderEvent가 있는 경우에만 인터랙션 관련 props 추출
39
+
40
+
41
+ var _d = hasRenderEvent && 'renderEvent' in props ? props : {
42
+ disableInteraction: false,
43
+ enableMultiSelect: false,
44
+ onClick: undefined,
45
+ onMouseOut: undefined,
46
+ onMouseOver: undefined,
47
+ renderEvent: undefined,
48
+ selectedItem: undefined,
49
+ selectedItems: undefined,
50
+ topOnHover: false,
51
+ topStageZIndex: undefined
52
+ },
53
+ _e = _d.disableInteraction,
54
+ disableInteraction = _e === void 0 ? false : _e,
55
+ _f = _d.enableMultiSelect,
56
+ enableMultiSelect = _f === void 0 ? false : _f,
57
+ onClick = _d.onClick,
58
+ onMouseOut = _d.onMouseOut,
59
+ onMouseOver = _d.onMouseOver,
60
+ renderEvent = _d.renderEvent,
61
+ externalSelectedItem = _d.selectedItem,
62
+ externalSelectedItems = _d.selectedItems,
63
+ rawTopStageZIndex = _d.topStageZIndex,
64
+ _g = _d.topOnHover,
65
+ topOnHover = _g === void 0 ? false : _g; // topOnHover가 false이거나 없으면 topStageZIndex를 사용하지 못하도록 제한
66
+
67
+
68
+ var topStageZIndex = topOnHover && rawTopStageZIndex !== undefined ? rawTopStageZIndex : undefined;
49
69
  var controller = MintMapProvider.useMintMapController();
50
70
  var context$1 = context.useCanvasContext();
51
71
  var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
@@ -53,11 +73,18 @@ var CanvasMarkerLayer = function (props) {
53
73
  var divRef = React.useRef(document.createElement('div'));
54
74
  var divElement = divRef.current;
55
75
  var containerRef = React.useRef(null);
56
- var markerRef = React.useRef(); // Konva Refs
76
+ var markerRef = React.useRef(); // Top Layer용 별도 DOM Refs (topStageZIndex가 설정된 경우에만 사용)
77
+
78
+ var topDivRef = React.useRef(document.createElement('div'));
79
+ var topDivElement = topDivRef.current;
80
+ var topContainerRef = React.useRef(null);
81
+ var topMarkerRef = React.useRef(); // Konva Refs
57
82
 
58
83
  var stageRef = React.useRef(null);
59
84
  var baseLayerRef = React.useRef(null);
60
- var eventLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
85
+ var eventLayerRef = React.useRef(null);
86
+ var topStageRef = React.useRef(null);
87
+ var topLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
61
88
 
62
89
  var dataRef = React.useRef(data);
63
90
  var disableInteractionRef = React.useRef(disableInteraction);
@@ -148,24 +175,34 @@ var CanvasMarkerLayer = function (props) {
148
175
 
149
176
  var visibleItems = enableViewportCullingRef.current ? dataRef.current.filter(function (item) {
150
177
  return isInViewport(item);
151
- }) : dataRef.current; // topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
178
+ }) : dataRef.current; // topStageZIndex가 설정되고 topOnHover true인 경우 hover된 항목은 Top Layer에서 처리
179
+ // topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
152
180
 
153
- if (topOnHover && !renderEvent && hovered) {
181
+ if (topStageZIndex !== undefined && topOnHover && hovered) {
182
+ visibleItems = visibleItems.filter(function (item) {
183
+ return item.id !== hovered.id;
184
+ });
185
+ } else if (topOnHover && !renderEvent && hovered) {
154
186
  visibleItems = visibleItems.filter(function (item) {
155
187
  return item.id !== hovered.id;
156
188
  });
157
189
  } // 일반 항목들 먼저 렌더링
190
+ // topOnHover가 false이고 renderEvent가 있으면 선택된 항목도 Base Layer에서 렌더링
191
+ // (Event Layer에서 선택된 항목을 렌더링하지 않으므로)
192
+ // topOnHover가 true이거나 renderEvent가 없으면 선택된 항목은 Base Layer에서 스킵됨
158
193
 
159
194
 
195
+ var baseSelectedIds = !topOnHover && renderEvent ? selectedIdsRef.current : new Set();
160
196
  renderBase({
161
197
  ctx: ctx,
162
198
  hoveredItem: hovered,
163
199
  items: visibleItems,
164
- selectedIds: selectedIdsRef.current,
200
+ selectedIds: baseSelectedIds,
165
201
  utils: renderUtils
166
- }); // hover된 항목을 마지막에 렌더링하여 최상위에 표시
202
+ }); // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리하므로 여기서는 스킵
203
+ // hover된 항목을 마지막에 렌더링하여 최상위에 표시
167
204
 
168
- if (topOnHover && !renderEvent && hovered) {
205
+ if (topStageZIndex === undefined && topOnHover && !renderEvent && hovered) {
169
206
  if (!enableViewportCullingRef.current || isInViewport(hovered)) {
170
207
  renderBase({
171
208
  ctx: ctx,
@@ -199,9 +236,24 @@ var CanvasMarkerLayer = function (props) {
199
236
  sceneFunc: function (konvaContext) {
200
237
  var ctx = konvaContext;
201
238
  var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
202
- var hovered = hoveredItemRef.current;
239
+ var hovered = hoveredItemRef.current; // topStageZIndex가 설정되고 topOnHover가 true이면 hover된 항목은 Top Layer에서 처리
240
+ // event 레이어에서는 hover된 항목을 완전히 제외하고 선택된 항목만 렌더링
241
+
242
+ if (topStageZIndex !== undefined && topOnHover && hovered) {
243
+ // hover된 항목을 제외한 선택된 항목들
244
+ var selectedItemsWithoutHovered = selectedItems.filter(function (item) {
245
+ return item.id !== hovered.id;
246
+ }); // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
203
247
 
204
- if (topOnHover && hovered) {
248
+ renderEvent({
249
+ ctx: ctx,
250
+ hoveredItem: null,
251
+ selectedItem: selectedItemRef.current,
252
+ selectedItems: selectedItemsWithoutHovered,
253
+ topOnHover: topOnHover,
254
+ utils: renderUtils
255
+ });
256
+ } else if (topOnHover && hovered) {
205
257
  renderEvent({
206
258
  ctx: ctx,
207
259
  hoveredItem: null,
@@ -209,6 +261,7 @@ var CanvasMarkerLayer = function (props) {
209
261
  selectedItems: selectedItems.filter(function (item) {
210
262
  return item.id !== hovered.id;
211
263
  }),
264
+ topOnHover: topOnHover,
212
265
  utils: renderUtils
213
266
  });
214
267
 
@@ -222,15 +275,25 @@ var CanvasMarkerLayer = function (props) {
222
275
  hoveredItem: hovered,
223
276
  selectedItem: selectedItemRef.current,
224
277
  selectedItems: hoverSelectedItems,
278
+ topOnHover: topOnHover,
225
279
  utils: renderUtils
226
280
  });
227
281
  }
228
282
  } else {
283
+ // topOnHover가 false일 때는 hover된 항목을 나중에 그리지 않음
284
+ // 하지만 hover 스타일은 적용해야 하므로, hover된 항목이 selectedItems에 포함되어 있지 않으면 추가
285
+ // renderEvent 함수에 topOnHover 정보를 전달하여,
286
+ // renderEvent 함수 내부에서 topOnHover가 false일 때는 hover된 항목을 마지막에 그리지 않도록 함
287
+ var hoveredIsSelected = hovered ? selectedItems.some(function (item) {
288
+ return item.id === hovered.id;
289
+ }) : false;
290
+ var finalSelectedItems = hovered && !hoveredIsSelected && !topOnHover ? tslib.__spreadArray(tslib.__spreadArray([], selectedItems, true), [hovered], false) : selectedItems;
229
291
  renderEvent({
230
292
  ctx: ctx,
231
293
  hoveredItem: hovered,
232
294
  selectedItem: selectedItemRef.current,
233
- selectedItems: selectedItems,
295
+ selectedItems: finalSelectedItems,
296
+ topOnHover: topOnHover,
234
297
  utils: renderUtils
235
298
  });
236
299
  }
@@ -239,6 +302,79 @@ var CanvasMarkerLayer = function (props) {
239
302
  layer.add(shape);
240
303
  }
241
304
 
305
+ layer.batchDraw();
306
+ }; // Top Layer 렌더링 (hover된 항목만, 별도 캔버스 DOM에 그리기)
307
+
308
+
309
+ var doRenderTop = function () {
310
+ var stage = topStageRef.current;
311
+ var layer = topLayerRef.current;
312
+ if (!stage || !layer || topStageZIndex === undefined || !topOnHover) return;
313
+ var hovered = hoveredItemRef.current;
314
+ var shape = layer.findOne('.top-render-shape'); // hover된 항목이 없으면 shape 제거
315
+
316
+ if (!hovered) {
317
+ if (shape) {
318
+ shape.destroy();
319
+ }
320
+
321
+ layer.batchDraw();
322
+ return;
323
+ } // shape가 없으면 생성
324
+
325
+
326
+ if (!shape) {
327
+ shape = new Konva__default["default"].Shape({
328
+ hitStrokeWidth: 0,
329
+ listening: false,
330
+ name: 'top-render-shape',
331
+ perfectDrawEnabled: false,
332
+ sceneFunc: function () {} // 초기화만
333
+
334
+ });
335
+ layer.add(shape);
336
+ } // sceneFunc를 매번 업데이트하여 최신 상태 반영
337
+
338
+
339
+ shape.sceneFunc(function (konvaContext) {
340
+ var ctx = konvaContext;
341
+ var currentHovered = hoveredItemRef.current; // hover된 항목이 없으면 아무것도 그리지 않음
342
+
343
+ if (!currentHovered) return; // 뷰포트 컬링 확인
344
+
345
+ if (enableViewportCullingRef.current && !isInViewport(currentHovered)) {
346
+ return;
347
+ }
348
+
349
+ var selectedItems = helpers.mapValuesToArray(selectedItemsMapRef.current);
350
+ var hoveredIsSelected = selectedItems.some(function (item) {
351
+ return item.id === currentHovered.id;
352
+ }); // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
353
+ // renderEvent가 있으면: base는 그리지 않고 event만 그리기 (hover 스타일 적용)
354
+ // renderEvent가 없으면: base를 hover 스타일로 그리기
355
+
356
+ if (renderEvent) {
357
+ // renderEvent가 있으면 hover 스타일로만 그리기
358
+ var hoverSelectedItems = hoveredIsSelected ? [currentHovered] : [];
359
+ renderEvent({
360
+ ctx: ctx,
361
+ hoveredItem: currentHovered,
362
+ selectedItem: selectedItemRef.current,
363
+ selectedItems: hoverSelectedItems,
364
+ topOnHover: topOnHover,
365
+ utils: renderUtils
366
+ });
367
+ } else {
368
+ // renderEvent가 없으면 base를 hover 스타일로 그리기
369
+ renderBase({
370
+ ctx: ctx,
371
+ hoveredItem: currentHovered,
372
+ items: [currentHovered],
373
+ selectedIds: selectedIdsRef.current,
374
+ utils: renderUtils
375
+ });
376
+ }
377
+ });
242
378
  layer.batchDraw();
243
379
  }; // 전체 즉시 렌더링
244
380
 
@@ -250,11 +386,19 @@ var CanvasMarkerLayer = function (props) {
250
386
 
251
387
  buildSpatialIndex();
252
388
  doRenderBase();
253
- doRenderEvent();
389
+ doRenderEvent(); // 메인 stage의 transform을 topStage에도 동기화
390
+
391
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
392
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
393
+ }
394
+
395
+ if (topStageZIndex !== undefined && topOnHover) {
396
+ doRenderTop();
397
+ }
254
398
  }; // 지도 이벤트 핸들러 생성
255
399
 
256
400
 
257
- var _g = hooks.createMapEventHandlers({
401
+ var _h = hooks.createMapEventHandlers({
258
402
  accumTranslateRef: accumTranslateRef,
259
403
  boundingBoxCacheRef: boundingBoxCacheRef,
260
404
  containerRef: containerRef,
@@ -265,19 +409,23 @@ var CanvasMarkerLayer = function (props) {
265
409
  prevCenterOffsetRef: prevCenterOffsetRef,
266
410
  renderAllImmediate: renderAllImmediate
267
411
  }),
268
- handleIdle = _g.handleIdle,
269
- handleZoomStart = _g.handleZoomStart,
270
- handleZoomEnd = _g.handleZoomEnd,
271
- handleCenterChanged = _g.handleCenterChanged,
272
- handleDragStartShared = _g.handleDragStart,
273
- handleDragEndShared = _g.handleDragEnd;
412
+ handleIdle = _h.handleIdle,
413
+ handleZoomStart = _h.handleZoomStart,
414
+ handleZoomEnd = _h.handleZoomEnd,
415
+ handleCenterChanged = _h.handleCenterChanged,
416
+ handleDragStartShared = _h.handleDragStart,
417
+ handleDragEndShared = _h.handleDragEnd;
274
418
 
275
419
  var handleDragStart = function () {
276
420
  handleDragStartShared(); // 드래그 시작 시점의 hover 상태 저장
277
421
 
278
422
  dragStartHoveredItemRef.current = hoveredItemRef.current;
279
423
  draggingRef.current = true;
280
- controller.setMapCursor('grabbing');
424
+ controller.setMapCursor('grabbing'); // 메인 stage의 transform을 topStage에도 동기화
425
+
426
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
427
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
428
+ }
281
429
  };
282
430
 
283
431
  var handleDragEnd = function () {
@@ -285,7 +433,11 @@ var CanvasMarkerLayer = function (props) {
285
433
  draggingRef.current = false; // 드래그 종료 후 hover 상태 초기화 (다음 MOUSEMOVE에서 업데이트됨)
286
434
 
287
435
  dragStartHoveredItemRef.current = null;
288
- controller.setMapCursor('grab');
436
+ controller.setMapCursor('grab'); // 메인 stage의 transform을 topStage에도 동기화
437
+
438
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
439
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
440
+ }
289
441
  }; // Hit Test: 특정 좌표의 마커 찾기
290
442
 
291
443
 
@@ -328,7 +480,19 @@ var CanvasMarkerLayer = function (props) {
328
480
  controller.setMapCursor(hoveredData ? 'pointer' : 'grab');
329
481
  }
330
482
 
331
- if (renderEvent) {
483
+ if (topStageZIndex !== undefined && topOnHover) {
484
+ // topStageZIndex가 설정되고 topOnHover가 true인 경우 Top Layer에서 hover된 항목 렌더링
485
+ // base 레이어와 event 레이어도 업데이트 (hover된 항목 제외)
486
+ doRenderBase();
487
+ doRenderEvent();
488
+ doRenderTop();
489
+ } else if (renderEvent) {
490
+ // renderEvent가 있을 때는 Event Layer 업데이트
491
+ // topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 적용해야 하므로 Base Layer도 업데이트
492
+ if (!topOnHover) {
493
+ doRenderBase();
494
+ }
495
+
332
496
  doRenderEvent();
333
497
  } else if (topOnHover) {
334
498
  doRenderBase();
@@ -365,6 +529,10 @@ var CanvasMarkerLayer = function (props) {
365
529
 
366
530
  doRenderBase();
367
531
  doRenderEvent();
532
+
533
+ if (topStageZIndex !== undefined && topOnHover) {
534
+ doRenderTop();
535
+ }
368
536
  }; // 클릭 이벤트 핸들러
369
537
 
370
538
 
@@ -425,13 +593,33 @@ var CanvasMarkerLayer = function (props) {
425
593
  if (!prevHovered) return;
426
594
  hoveredItemRef.current = null;
427
595
  controller.setMapCursor('grab');
428
- doRenderEvent();
596
+
597
+ if (topStageZIndex !== undefined && topOnHover) {
598
+ // base 레이어와 event 레이어도 업데이트 (hover된 항목 다시 표시)
599
+ doRenderBase();
600
+ doRenderEvent();
601
+ doRenderTop();
602
+ } else if (renderEvent) {
603
+ // renderEvent가 있을 때는 Event Layer 업데이트
604
+ // topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 제거해야 하므로 Base Layer도 업데이트
605
+ if (!topOnHover) {
606
+ doRenderBase();
607
+ }
608
+
609
+ doRenderEvent();
610
+ }
611
+
429
612
  onMouseOut === null || onMouseOut === void 0 ? void 0 : onMouseOut(prevHovered);
430
613
  }; // DOM 초기화
431
614
 
432
615
 
433
616
  React.useEffect(function () {
434
- divElement.style.width = 'fit-content';
617
+ divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
618
+
619
+ if (topStageZIndex !== undefined && topOnHover) {
620
+ topDivElement.style.width = 'fit-content';
621
+ }
622
+
435
623
  return function () {
436
624
  if (!markerRef.current) return;
437
625
  controller.clearDrawable(markerRef.current);
@@ -449,19 +637,18 @@ var CanvasMarkerLayer = function (props) {
449
637
 
450
638
  if (markerRef.current) {
451
639
  controller.updateMarker(markerRef.current, markerOptions);
452
- return;
453
- }
454
-
455
- markerRef.current = new MapDrawables.Marker(markerOptions);
456
- markerRef.current.element = divElement;
457
- controller.createMarker(markerRef.current);
640
+ } else {
641
+ markerRef.current = new MapDrawables.Marker(markerOptions);
642
+ markerRef.current.element = divElement;
643
+ controller.createMarker(markerRef.current);
458
644
 
459
- if (divElement.parentElement) {
460
- divElement.parentElement.style.pointerEvents = 'none';
461
- }
645
+ if (divElement.parentElement) {
646
+ divElement.parentElement.style.pointerEvents = 'none';
647
+ }
462
648
 
463
- if (options.zIndex !== undefined) {
464
- controller.setMarkerZIndex(markerRef.current, options.zIndex);
649
+ if (options.zIndex !== undefined) {
650
+ controller.setMarkerZIndex(markerRef.current, options.zIndex);
651
+ }
465
652
  }
466
653
  }, [options]); // Konva 초기화 및 이벤트 리스너 등록
467
654
 
@@ -615,19 +802,179 @@ var CanvasMarkerLayer = function (props) {
615
802
 
616
803
  renderAllImmediate();
617
804
  }
618
- }, [enableViewportCulling]); // 외부 selectedItems 동기화
805
+ }, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
806
+
807
+ React.useEffect(function () {
808
+ if (topStageZIndex === undefined || !topOnHover) return;
809
+ if (!topContainerRef.current) return;
810
+ var mapDiv = controller.mapDivElement; // Top Layer용 div 요소 설정
811
+
812
+ topDivElement.style.width = 'fit-content';
813
+ var bounds = controller.getCurrBounds();
814
+
815
+ var topMarkerOptions = tslib.__assign({
816
+ position: bounds.nw,
817
+ zIndex: topStageZIndex
818
+ }, options); // Top Layer용 Marker 생성 (zIndex: topStageZIndex로 DOM 마커보다 위에 위치)
819
+
820
+
821
+ var topMarker = new MapDrawables.Marker(topMarkerOptions);
822
+ topMarker.element = topDivElement;
823
+ controller.createMarker(topMarker);
824
+ topMarkerRef.current = topMarker;
825
+
826
+ if (topDivElement.parentElement) {
827
+ topDivElement.parentElement.style.pointerEvents = 'none';
828
+ } // Top Layer Marker의 zIndex 명시적으로 설정
829
+
830
+
831
+ controller.setMarkerZIndex(topMarker, topStageZIndex); // Top Layer용 Konva Stage 생성
832
+
833
+ var topStage = new Konva__default["default"].Stage({
834
+ container: topContainerRef.current,
835
+ height: mapDiv.offsetHeight,
836
+ width: mapDiv.offsetWidth
837
+ });
838
+ topStageRef.current = topStage;
839
+ var topLayer = new Konva__default["default"].Layer({
840
+ listening: false
841
+ });
842
+ topLayerRef.current = topLayer;
843
+ topStage.add(topLayer); // ResizeObserver: 맵 크기 변경 감지 (RAF로 debounce)
844
+
845
+ var topResizeRafId = null;
846
+ var topResizeObserver = new ResizeObserver(function () {
847
+ if (topResizeRafId !== null) {
848
+ cancelAnimationFrame(topResizeRafId);
849
+ }
850
+
851
+ topResizeRafId = requestAnimationFrame(function () {
852
+ topStage.width(mapDiv.offsetWidth);
853
+ topStage.height(mapDiv.offsetHeight);
854
+ doRenderTop();
855
+ topResizeRafId = null;
856
+ });
857
+ });
858
+ topResizeObserver.observe(mapDiv); // topMarker position 업데이트 함수
859
+
860
+ var updateTopMarkerPosition = function () {
861
+ if (topMarkerRef.current && markerRef.current) {
862
+ var currentBounds = controller.getCurrBounds();
863
+
864
+ var updatedOptions = tslib.__assign(tslib.__assign({}, options), {
865
+ position: currentBounds.nw,
866
+ zIndex: topStageZIndex
867
+ });
868
+
869
+ controller.updateMarker(topMarkerRef.current, updatedOptions); // zIndex 명시적으로 설정
870
+
871
+ controller.setMarkerZIndex(topMarkerRef.current, topStageZIndex);
872
+ }
873
+ }; // 지도 이벤트 핸들러 등록 (topStage 업데이트용)
874
+
875
+
876
+ var handleTopIdle = function () {
877
+ // topMarker의 position을 메인 marker와 동일하게 업데이트
878
+ updateTopMarkerPosition(); // topStage 크기 업데이트
879
+
880
+ if (topStageRef.current) {
881
+ topStageRef.current.width(mapDiv.offsetWidth);
882
+ topStageRef.current.height(mapDiv.offsetHeight);
883
+ } // 메인 stage의 transform을 topStage에도 동기화
884
+
885
+
886
+ if (topContainerRef.current && containerRef.current) {
887
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
888
+ }
889
+
890
+ doRenderTop();
891
+ };
892
+
893
+ var handleTopZoomStart = function () {
894
+ // 메인 stage의 transform을 topStage에도 동기화
895
+ if (topContainerRef.current && containerRef.current) {
896
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
897
+ }
898
+
899
+ doRenderTop();
900
+ };
901
+
902
+ var handleTopZoomEnd = function () {
903
+ // 메인 stage의 transform을 topStage에도 동기화
904
+ if (topContainerRef.current && containerRef.current) {
905
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
906
+ }
907
+
908
+ doRenderTop();
909
+ };
910
+
911
+ var handleTopCenterChanged = function () {
912
+ // topMarker의 position을 메인 marker와 동일하게 업데이트
913
+ updateTopMarkerPosition(); // topStage 크기 업데이트
914
+
915
+ if (topStageRef.current) {
916
+ topStageRef.current.width(mapDiv.offsetWidth);
917
+ topStageRef.current.height(mapDiv.offsetHeight);
918
+ } // 메인 stage의 transform을 topStage에도 동기화
919
+
920
+
921
+ if (topContainerRef.current && containerRef.current) {
922
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
923
+ }
924
+
925
+ doRenderTop();
926
+ };
927
+
928
+ controller.addEventListener('IDLE', handleTopIdle);
929
+ controller.addEventListener('ZOOMSTART', handleTopZoomStart);
930
+ controller.addEventListener('ZOOM_CHANGED', handleTopZoomEnd);
931
+ controller.addEventListener('CENTER_CHANGED', handleTopCenterChanged);
932
+ doRenderTop();
933
+ return function () {
934
+ if (topResizeRafId !== null) {
935
+ cancelAnimationFrame(topResizeRafId);
936
+ }
937
+
938
+ topResizeObserver.disconnect();
939
+ controller.removeEventListener('IDLE', handleTopIdle);
940
+ controller.removeEventListener('ZOOMSTART', handleTopZoomStart);
941
+ controller.removeEventListener('ZOOM_CHANGED', handleTopZoomEnd);
942
+ controller.removeEventListener('CENTER_CHANGED', handleTopCenterChanged);
943
+
944
+ if (topLayerRef.current) {
945
+ topLayerRef.current.destroyChildren();
946
+ }
947
+
948
+ if (topStageRef.current) {
949
+ topStageRef.current.destroy();
950
+ }
951
+
952
+ if (topMarkerRef.current) {
953
+ controller.clearDrawable(topMarkerRef.current);
954
+ topMarkerRef.current = undefined;
955
+ }
956
+ };
957
+ }, [topStageZIndex, renderEvent, options]); // 외부 selectedItems 동기화
619
958
 
620
959
  React.useEffect(function () {
621
960
  if (!stageRef.current) return;
622
961
  hooks.syncExternalSelectedItems(externalSelectedItems, selectedIdsRef, selectedItemsMapRef);
623
962
  doRenderBase();
624
963
  doRenderEvent();
964
+
965
+ if (topStageZIndex !== undefined && topOnHover) {
966
+ doRenderTop();
967
+ }
625
968
  }, [externalSelectedItems]); // 외부 selectedItem 변경 시 Event Layer 리렌더링
626
969
 
627
970
  React.useEffect(function () {
628
971
  if (!stageRef.current) return;
629
972
  selectedItemRef.current = externalSelectedItem;
630
973
  doRenderEvent();
974
+
975
+ if (topStageZIndex !== undefined && topOnHover) {
976
+ doRenderTop();
977
+ }
631
978
  }, [externalSelectedItem]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
632
979
 
633
980
  React.useEffect(function () {
@@ -648,14 +995,21 @@ var CanvasMarkerLayer = function (props) {
648
995
  selectedItemsMapRef.current = hooks.syncSelectedItems(data, selectedIdsRef.current, selectedItemsMapRef.current);
649
996
  renderAllImmediate();
650
997
  }, [data]);
651
- return reactDom.createPortal(React__default["default"].createElement("div", {
998
+ return React__default["default"].createElement(React__default["default"].Fragment, null, reactDom.createPortal(React__default["default"].createElement("div", {
652
999
  ref: containerRef,
653
1000
  style: {
654
1001
  height: '100%',
655
1002
  position: 'absolute',
656
1003
  width: '100%'
657
1004
  }
658
- }), divElement);
1005
+ }), divElement), topStageZIndex !== undefined && reactDom.createPortal(React__default["default"].createElement("div", {
1006
+ ref: topContainerRef,
1007
+ style: {
1008
+ height: '100%',
1009
+ position: 'absolute',
1010
+ width: '100%'
1011
+ }
1012
+ }), topDivElement));
659
1013
  };
660
1014
 
661
1015
  exports.CanvasProvider = context.CanvasProvider;