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

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.
package/dist/index.umd.js CHANGED
@@ -3939,28 +3939,48 @@
3939
3939
  });
3940
3940
 
3941
3941
  var CanvasMarkerLayer = function (props) {
3942
+ // 타입 가드: renderEvent가 있는지 확인
3943
+ var hasRenderEvent = 'renderEvent' in props && props.renderEvent !== undefined; // renderEvent가 있는 경우와 없는 경우를 구분하여 props 추출
3944
+
3942
3945
  var data = props.data,
3943
- onClick = props.onClick,
3944
- onMouseOver = props.onMouseOver,
3945
- onMouseOut = props.onMouseOut,
3946
- _a = props.enableMultiSelect,
3947
- enableMultiSelect = _a === void 0 ? false : _a,
3948
- _b = props.topOnHover,
3949
- topOnHover = _b === void 0 ? false : _b,
3950
- _c = props.enableViewportCulling,
3951
- enableViewportCulling = _c === void 0 ? false : _c,
3952
- _d = props.cullingMargin,
3953
- cullingMargin = _d === void 0 ? DEFAULT_CULLING_MARGIN : _d,
3954
- _e = props.maxCacheSize,
3955
- maxCacheSize = _e === void 0 ? DEFAULT_MAX_CACHE_SIZE : _e,
3956
- externalSelectedItems = props.selectedItems,
3957
- externalSelectedItem = props.selectedItem,
3958
- _f = props.disableInteraction,
3959
- disableInteraction = _f === void 0 ? false : _f,
3946
+ _a = props.enableViewportCulling,
3947
+ enableViewportCulling = _a === void 0 ? false : _a,
3948
+ _b = props.cullingMargin,
3949
+ cullingMargin = _b === void 0 ? DEFAULT_CULLING_MARGIN : _b,
3950
+ _c = props.maxCacheSize,
3951
+ maxCacheSize = _c === void 0 ? DEFAULT_MAX_CACHE_SIZE : _c,
3960
3952
  renderBase = props.renderBase,
3961
- renderEvent = props.renderEvent,
3962
- options = tslib.__rest(props, ["data", "onClick", "onMouseOver", "onMouseOut", "enableMultiSelect", "topOnHover", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction", "renderBase", "renderEvent"]);
3963
-
3953
+ options = tslib.__rest(props, ["data", "enableViewportCulling", "cullingMargin", "maxCacheSize", "renderBase"]); // renderEvent가 있는 경우에만 인터랙션 관련 props 추출
3954
+
3955
+
3956
+ var _d = hasRenderEvent && 'renderEvent' in props ? props : {
3957
+ disableInteraction: false,
3958
+ enableMultiSelect: false,
3959
+ onClick: undefined,
3960
+ onMouseOut: undefined,
3961
+ onMouseOver: undefined,
3962
+ renderEvent: undefined,
3963
+ selectedItem: undefined,
3964
+ selectedItems: undefined,
3965
+ topOnHover: false,
3966
+ topStageZIndex: undefined
3967
+ },
3968
+ _e = _d.disableInteraction,
3969
+ disableInteraction = _e === void 0 ? false : _e,
3970
+ _f = _d.enableMultiSelect,
3971
+ enableMultiSelect = _f === void 0 ? false : _f,
3972
+ onClick = _d.onClick,
3973
+ onMouseOut = _d.onMouseOut,
3974
+ onMouseOver = _d.onMouseOver,
3975
+ renderEvent = _d.renderEvent,
3976
+ externalSelectedItem = _d.selectedItem,
3977
+ externalSelectedItems = _d.selectedItems,
3978
+ rawTopStageZIndex = _d.topStageZIndex,
3979
+ _g = _d.topOnHover,
3980
+ topOnHover = _g === void 0 ? false : _g; // topOnHover가 false이거나 없으면 topStageZIndex를 사용하지 못하도록 제한
3981
+
3982
+
3983
+ var topStageZIndex = topOnHover && rawTopStageZIndex !== undefined ? rawTopStageZIndex : undefined;
3964
3984
  var controller = useMintMapController();
3965
3985
  var context = useCanvasContext();
3966
3986
  var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
@@ -3968,11 +3988,18 @@
3968
3988
  var divRef = React.useRef(document.createElement('div'));
3969
3989
  var divElement = divRef.current;
3970
3990
  var containerRef = React.useRef(null);
3971
- var markerRef = React.useRef(); // Konva Refs
3991
+ var markerRef = React.useRef(); // Top Layer용 별도 DOM Refs (topStageZIndex가 설정된 경우에만 사용)
3992
+
3993
+ var topDivRef = React.useRef(document.createElement('div'));
3994
+ var topDivElement = topDivRef.current;
3995
+ var topContainerRef = React.useRef(null);
3996
+ var topMarkerRef = React.useRef(); // Konva Refs
3972
3997
 
3973
3998
  var stageRef = React.useRef(null);
3974
3999
  var baseLayerRef = React.useRef(null);
3975
- var eventLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
4000
+ var eventLayerRef = React.useRef(null);
4001
+ var topStageRef = React.useRef(null);
4002
+ var topLayerRef = React.useRef(null); // 상태 관리 Refs (React 리렌더링 최소화)
3976
4003
 
3977
4004
  var dataRef = React.useRef(data);
3978
4005
  var disableInteractionRef = React.useRef(disableInteraction);
@@ -4063,24 +4090,34 @@
4063
4090
 
4064
4091
  var visibleItems = enableViewportCullingRef.current ? dataRef.current.filter(function (item) {
4065
4092
  return isInViewport$1(item);
4066
- }) : dataRef.current; // topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
4093
+ }) : dataRef.current; // topStageZIndex가 설정되고 topOnHover true인 경우 hover된 항목은 Top Layer에서 처리
4094
+ // topOnHover 옵션: hover된 항목을 나중에 그려서 최상위에 표시
4067
4095
 
4068
- if (topOnHover && !renderEvent && hovered) {
4096
+ if (topStageZIndex !== undefined && topOnHover && hovered) {
4097
+ visibleItems = visibleItems.filter(function (item) {
4098
+ return item.id !== hovered.id;
4099
+ });
4100
+ } else if (topOnHover && !renderEvent && hovered) {
4069
4101
  visibleItems = visibleItems.filter(function (item) {
4070
4102
  return item.id !== hovered.id;
4071
4103
  });
4072
4104
  } // 일반 항목들 먼저 렌더링
4105
+ // topOnHover가 false이고 renderEvent가 있으면 선택된 항목도 Base Layer에서 렌더링
4106
+ // (Event Layer에서 선택된 항목을 렌더링하지 않으므로)
4107
+ // topOnHover가 true이거나 renderEvent가 없으면 선택된 항목은 Base Layer에서 스킵됨
4073
4108
 
4074
4109
 
4110
+ var baseSelectedIds = !topOnHover && renderEvent ? selectedIdsRef.current : new Set();
4075
4111
  renderBase({
4076
4112
  ctx: ctx,
4077
4113
  hoveredItem: hovered,
4078
4114
  items: visibleItems,
4079
- selectedIds: selectedIdsRef.current,
4115
+ selectedIds: baseSelectedIds,
4080
4116
  utils: renderUtils
4081
- }); // hover된 항목을 마지막에 렌더링하여 최상위에 표시
4117
+ }); // topStageZIndex가 설정된 경우 hover된 항목은 Top Layer에서 처리하므로 여기서는 스킵
4118
+ // hover된 항목을 마지막에 렌더링하여 최상위에 표시
4082
4119
 
4083
- if (topOnHover && !renderEvent && hovered) {
4120
+ if (topStageZIndex === undefined && topOnHover && !renderEvent && hovered) {
4084
4121
  if (!enableViewportCullingRef.current || isInViewport$1(hovered)) {
4085
4122
  renderBase({
4086
4123
  ctx: ctx,
@@ -4114,9 +4151,24 @@
4114
4151
  sceneFunc: function (konvaContext) {
4115
4152
  var ctx = konvaContext;
4116
4153
  var selectedItems = mapValuesToArray(selectedItemsMapRef.current);
4117
- var hovered = hoveredItemRef.current;
4154
+ var hovered = hoveredItemRef.current; // topStageZIndex가 설정되고 topOnHover가 true이면 hover된 항목은 Top Layer에서 처리
4155
+ // event 레이어에서는 hover된 항목을 완전히 제외하고 선택된 항목만 렌더링
4118
4156
 
4119
- if (topOnHover && hovered) {
4157
+ if (topStageZIndex !== undefined && topOnHover && hovered) {
4158
+ // hover된 항목을 제외한 선택된 항목들
4159
+ var selectedItemsWithoutHovered = selectedItems.filter(function (item) {
4160
+ return item.id !== hovered.id;
4161
+ }); // 선택된 항목만 그리기 (hover된 항목은 Top Layer에서 처리)
4162
+
4163
+ renderEvent({
4164
+ ctx: ctx,
4165
+ hoveredItem: null,
4166
+ selectedItem: selectedItemRef.current,
4167
+ selectedItems: selectedItemsWithoutHovered,
4168
+ topOnHover: topOnHover,
4169
+ utils: renderUtils
4170
+ });
4171
+ } else if (topOnHover && hovered) {
4120
4172
  renderEvent({
4121
4173
  ctx: ctx,
4122
4174
  hoveredItem: null,
@@ -4124,6 +4176,7 @@
4124
4176
  selectedItems: selectedItems.filter(function (item) {
4125
4177
  return item.id !== hovered.id;
4126
4178
  }),
4179
+ topOnHover: topOnHover,
4127
4180
  utils: renderUtils
4128
4181
  });
4129
4182
 
@@ -4137,15 +4190,25 @@
4137
4190
  hoveredItem: hovered,
4138
4191
  selectedItem: selectedItemRef.current,
4139
4192
  selectedItems: hoverSelectedItems,
4193
+ topOnHover: topOnHover,
4140
4194
  utils: renderUtils
4141
4195
  });
4142
4196
  }
4143
4197
  } else {
4198
+ // topOnHover가 false일 때는 hover된 항목을 나중에 그리지 않음
4199
+ // 하지만 hover 스타일은 적용해야 하므로, hover된 항목이 selectedItems에 포함되어 있지 않으면 추가
4200
+ // renderEvent 함수에 topOnHover 정보를 전달하여,
4201
+ // renderEvent 함수 내부에서 topOnHover가 false일 때는 hover된 항목을 마지막에 그리지 않도록 함
4202
+ var hoveredIsSelected = hovered ? selectedItems.some(function (item) {
4203
+ return item.id === hovered.id;
4204
+ }) : false;
4205
+ var finalSelectedItems = hovered && !hoveredIsSelected && !topOnHover ? tslib.__spreadArray(tslib.__spreadArray([], selectedItems, true), [hovered], false) : selectedItems;
4144
4206
  renderEvent({
4145
4207
  ctx: ctx,
4146
4208
  hoveredItem: hovered,
4147
4209
  selectedItem: selectedItemRef.current,
4148
- selectedItems: selectedItems,
4210
+ selectedItems: finalSelectedItems,
4211
+ topOnHover: topOnHover,
4149
4212
  utils: renderUtils
4150
4213
  });
4151
4214
  }
@@ -4154,6 +4217,79 @@
4154
4217
  layer.add(shape);
4155
4218
  }
4156
4219
 
4220
+ layer.batchDraw();
4221
+ }; // Top Layer 렌더링 (hover된 항목만, 별도 캔버스 DOM에 그리기)
4222
+
4223
+
4224
+ var doRenderTop = function () {
4225
+ var stage = topStageRef.current;
4226
+ var layer = topLayerRef.current;
4227
+ if (!stage || !layer || topStageZIndex === undefined || !topOnHover) return;
4228
+ var hovered = hoveredItemRef.current;
4229
+ var shape = layer.findOne('.top-render-shape'); // hover된 항목이 없으면 shape 제거
4230
+
4231
+ if (!hovered) {
4232
+ if (shape) {
4233
+ shape.destroy();
4234
+ }
4235
+
4236
+ layer.batchDraw();
4237
+ return;
4238
+ } // shape가 없으면 생성
4239
+
4240
+
4241
+ if (!shape) {
4242
+ shape = new Konva__default["default"].Shape({
4243
+ hitStrokeWidth: 0,
4244
+ listening: false,
4245
+ name: 'top-render-shape',
4246
+ perfectDrawEnabled: false,
4247
+ sceneFunc: function () {} // 초기화만
4248
+
4249
+ });
4250
+ layer.add(shape);
4251
+ } // sceneFunc를 매번 업데이트하여 최신 상태 반영
4252
+
4253
+
4254
+ shape.sceneFunc(function (konvaContext) {
4255
+ var ctx = konvaContext;
4256
+ var currentHovered = hoveredItemRef.current; // hover된 항목이 없으면 아무것도 그리지 않음
4257
+
4258
+ if (!currentHovered) return; // 뷰포트 컬링 확인
4259
+
4260
+ if (enableViewportCullingRef.current && !isInViewport$1(currentHovered)) {
4261
+ return;
4262
+ }
4263
+
4264
+ var selectedItems = mapValuesToArray(selectedItemsMapRef.current);
4265
+ var hoveredIsSelected = selectedItems.some(function (item) {
4266
+ return item.id === currentHovered.id;
4267
+ }); // Top Layer에서는 hover된 마커만 hover 스타일로 그리기
4268
+ // renderEvent가 있으면: base는 그리지 않고 event만 그리기 (hover 스타일 적용)
4269
+ // renderEvent가 없으면: base를 hover 스타일로 그리기
4270
+
4271
+ if (renderEvent) {
4272
+ // renderEvent가 있으면 hover 스타일로만 그리기
4273
+ var hoverSelectedItems = hoveredIsSelected ? [currentHovered] : [];
4274
+ renderEvent({
4275
+ ctx: ctx,
4276
+ hoveredItem: currentHovered,
4277
+ selectedItem: selectedItemRef.current,
4278
+ selectedItems: hoverSelectedItems,
4279
+ topOnHover: topOnHover,
4280
+ utils: renderUtils
4281
+ });
4282
+ } else {
4283
+ // renderEvent가 없으면 base를 hover 스타일로 그리기
4284
+ renderBase({
4285
+ ctx: ctx,
4286
+ hoveredItem: currentHovered,
4287
+ items: [currentHovered],
4288
+ selectedIds: selectedIdsRef.current,
4289
+ utils: renderUtils
4290
+ });
4291
+ }
4292
+ });
4157
4293
  layer.batchDraw();
4158
4294
  }; // 전체 즉시 렌더링
4159
4295
 
@@ -4165,11 +4301,19 @@
4165
4301
 
4166
4302
  buildSpatialIndex$1();
4167
4303
  doRenderBase();
4168
- doRenderEvent();
4304
+ doRenderEvent(); // 메인 stage의 transform을 topStage에도 동기화
4305
+
4306
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
4307
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4308
+ }
4309
+
4310
+ if (topStageZIndex !== undefined && topOnHover) {
4311
+ doRenderTop();
4312
+ }
4169
4313
  }; // 지도 이벤트 핸들러 생성
4170
4314
 
4171
4315
 
4172
- var _g = createMapEventHandlers({
4316
+ var _h = createMapEventHandlers({
4173
4317
  accumTranslateRef: accumTranslateRef,
4174
4318
  boundingBoxCacheRef: boundingBoxCacheRef,
4175
4319
  containerRef: containerRef,
@@ -4180,19 +4324,23 @@
4180
4324
  prevCenterOffsetRef: prevCenterOffsetRef,
4181
4325
  renderAllImmediate: renderAllImmediate
4182
4326
  }),
4183
- handleIdle = _g.handleIdle,
4184
- handleZoomStart = _g.handleZoomStart,
4185
- handleZoomEnd = _g.handleZoomEnd,
4186
- handleCenterChanged = _g.handleCenterChanged,
4187
- handleDragStartShared = _g.handleDragStart,
4188
- handleDragEndShared = _g.handleDragEnd;
4327
+ handleIdle = _h.handleIdle,
4328
+ handleZoomStart = _h.handleZoomStart,
4329
+ handleZoomEnd = _h.handleZoomEnd,
4330
+ handleCenterChanged = _h.handleCenterChanged,
4331
+ handleDragStartShared = _h.handleDragStart,
4332
+ handleDragEndShared = _h.handleDragEnd;
4189
4333
 
4190
4334
  var handleDragStart = function () {
4191
4335
  handleDragStartShared(); // 드래그 시작 시점의 hover 상태 저장
4192
4336
 
4193
4337
  dragStartHoveredItemRef.current = hoveredItemRef.current;
4194
4338
  draggingRef.current = true;
4195
- controller.setMapCursor('grabbing');
4339
+ controller.setMapCursor('grabbing'); // 메인 stage의 transform을 topStage에도 동기화
4340
+
4341
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
4342
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4343
+ }
4196
4344
  };
4197
4345
 
4198
4346
  var handleDragEnd = function () {
@@ -4200,7 +4348,11 @@
4200
4348
  draggingRef.current = false; // 드래그 종료 후 hover 상태 초기화 (다음 MOUSEMOVE에서 업데이트됨)
4201
4349
 
4202
4350
  dragStartHoveredItemRef.current = null;
4203
- controller.setMapCursor('grab');
4351
+ controller.setMapCursor('grab'); // 메인 stage의 transform을 topStage에도 동기화
4352
+
4353
+ if (topStageZIndex !== undefined && topContainerRef.current && containerRef.current) {
4354
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4355
+ }
4204
4356
  }; // Hit Test: 특정 좌표의 마커 찾기
4205
4357
 
4206
4358
 
@@ -4243,7 +4395,19 @@
4243
4395
  controller.setMapCursor(hoveredData ? 'pointer' : 'grab');
4244
4396
  }
4245
4397
 
4246
- if (renderEvent) {
4398
+ if (topStageZIndex !== undefined && topOnHover) {
4399
+ // topStageZIndex가 설정되고 topOnHover가 true인 경우 Top Layer에서 hover된 항목 렌더링
4400
+ // base 레이어와 event 레이어도 업데이트 (hover된 항목 제외)
4401
+ doRenderBase();
4402
+ doRenderEvent();
4403
+ doRenderTop();
4404
+ } else if (renderEvent) {
4405
+ // renderEvent가 있을 때는 Event Layer 업데이트
4406
+ // topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 적용해야 하므로 Base Layer도 업데이트
4407
+ if (!topOnHover) {
4408
+ doRenderBase();
4409
+ }
4410
+
4247
4411
  doRenderEvent();
4248
4412
  } else if (topOnHover) {
4249
4413
  doRenderBase();
@@ -4280,6 +4444,10 @@
4280
4444
 
4281
4445
  doRenderBase();
4282
4446
  doRenderEvent();
4447
+
4448
+ if (topStageZIndex !== undefined && topOnHover) {
4449
+ doRenderTop();
4450
+ }
4283
4451
  }; // 클릭 이벤트 핸들러
4284
4452
 
4285
4453
 
@@ -4340,13 +4508,33 @@
4340
4508
  if (!prevHovered) return;
4341
4509
  hoveredItemRef.current = null;
4342
4510
  controller.setMapCursor('grab');
4343
- doRenderEvent();
4511
+
4512
+ if (topStageZIndex !== undefined && topOnHover) {
4513
+ // base 레이어와 event 레이어도 업데이트 (hover된 항목 다시 표시)
4514
+ doRenderBase();
4515
+ doRenderEvent();
4516
+ doRenderTop();
4517
+ } else if (renderEvent) {
4518
+ // renderEvent가 있을 때는 Event Layer 업데이트
4519
+ // topOnHover가 false일 때는 Base Layer에서도 hover 스타일을 제거해야 하므로 Base Layer도 업데이트
4520
+ if (!topOnHover) {
4521
+ doRenderBase();
4522
+ }
4523
+
4524
+ doRenderEvent();
4525
+ }
4526
+
4344
4527
  onMouseOut === null || onMouseOut === void 0 ? void 0 : onMouseOut(prevHovered);
4345
4528
  }; // DOM 초기화
4346
4529
 
4347
4530
 
4348
4531
  React.useEffect(function () {
4349
- divElement.style.width = 'fit-content';
4532
+ divElement.style.width = 'fit-content'; // Top Layer용 div도 초기화 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
4533
+
4534
+ if (topStageZIndex !== undefined && topOnHover) {
4535
+ topDivElement.style.width = 'fit-content';
4536
+ }
4537
+
4350
4538
  return function () {
4351
4539
  if (!markerRef.current) return;
4352
4540
  controller.clearDrawable(markerRef.current);
@@ -4364,19 +4552,18 @@
4364
4552
 
4365
4553
  if (markerRef.current) {
4366
4554
  controller.updateMarker(markerRef.current, markerOptions);
4367
- return;
4368
- }
4369
-
4370
- markerRef.current = new Marker(markerOptions);
4371
- markerRef.current.element = divElement;
4372
- controller.createMarker(markerRef.current);
4555
+ } else {
4556
+ markerRef.current = new Marker(markerOptions);
4557
+ markerRef.current.element = divElement;
4558
+ controller.createMarker(markerRef.current);
4373
4559
 
4374
- if (divElement.parentElement) {
4375
- divElement.parentElement.style.pointerEvents = 'none';
4376
- }
4560
+ if (divElement.parentElement) {
4561
+ divElement.parentElement.style.pointerEvents = 'none';
4562
+ }
4377
4563
 
4378
- if (options.zIndex !== undefined) {
4379
- controller.setMarkerZIndex(markerRef.current, options.zIndex);
4564
+ if (options.zIndex !== undefined) {
4565
+ controller.setMarkerZIndex(markerRef.current, options.zIndex);
4566
+ }
4380
4567
  }
4381
4568
  }, [options]); // Konva 초기화 및 이벤트 리스너 등록
4382
4569
 
@@ -4530,19 +4717,179 @@
4530
4717
 
4531
4718
  renderAllImmediate();
4532
4719
  }
4533
- }, [enableViewportCulling]); // 외부 selectedItems 동기화
4720
+ }, [enableViewportCulling]); // Top Layer용 별도 캔버스 DOM 생성 (topStageZIndex가 설정되고 topOnHover가 true인 경우)
4721
+
4722
+ React.useEffect(function () {
4723
+ if (topStageZIndex === undefined || !topOnHover) return;
4724
+ if (!topContainerRef.current) return;
4725
+ var mapDiv = controller.mapDivElement; // Top Layer용 div 요소 설정
4726
+
4727
+ topDivElement.style.width = 'fit-content';
4728
+ var bounds = controller.getCurrBounds();
4729
+
4730
+ var topMarkerOptions = tslib.__assign({
4731
+ position: bounds.nw,
4732
+ zIndex: topStageZIndex
4733
+ }, options); // Top Layer용 Marker 생성 (zIndex: topStageZIndex로 DOM 마커보다 위에 위치)
4734
+
4735
+
4736
+ var topMarker = new Marker(topMarkerOptions);
4737
+ topMarker.element = topDivElement;
4738
+ controller.createMarker(topMarker);
4739
+ topMarkerRef.current = topMarker;
4740
+
4741
+ if (topDivElement.parentElement) {
4742
+ topDivElement.parentElement.style.pointerEvents = 'none';
4743
+ } // Top Layer Marker의 zIndex 명시적으로 설정
4744
+
4745
+
4746
+ controller.setMarkerZIndex(topMarker, topStageZIndex); // Top Layer용 Konva Stage 생성
4747
+
4748
+ var topStage = new Konva__default["default"].Stage({
4749
+ container: topContainerRef.current,
4750
+ height: mapDiv.offsetHeight,
4751
+ width: mapDiv.offsetWidth
4752
+ });
4753
+ topStageRef.current = topStage;
4754
+ var topLayer = new Konva__default["default"].Layer({
4755
+ listening: false
4756
+ });
4757
+ topLayerRef.current = topLayer;
4758
+ topStage.add(topLayer); // ResizeObserver: 맵 크기 변경 감지 (RAF로 debounce)
4759
+
4760
+ var topResizeRafId = null;
4761
+ var topResizeObserver = new ResizeObserver(function () {
4762
+ if (topResizeRafId !== null) {
4763
+ cancelAnimationFrame(topResizeRafId);
4764
+ }
4765
+
4766
+ topResizeRafId = requestAnimationFrame(function () {
4767
+ topStage.width(mapDiv.offsetWidth);
4768
+ topStage.height(mapDiv.offsetHeight);
4769
+ doRenderTop();
4770
+ topResizeRafId = null;
4771
+ });
4772
+ });
4773
+ topResizeObserver.observe(mapDiv); // topMarker position 업데이트 함수
4774
+
4775
+ var updateTopMarkerPosition = function () {
4776
+ if (topMarkerRef.current && markerRef.current) {
4777
+ var currentBounds = controller.getCurrBounds();
4778
+
4779
+ var updatedOptions = tslib.__assign(tslib.__assign({}, options), {
4780
+ position: currentBounds.nw,
4781
+ zIndex: topStageZIndex
4782
+ });
4783
+
4784
+ controller.updateMarker(topMarkerRef.current, updatedOptions); // zIndex 명시적으로 설정
4785
+
4786
+ controller.setMarkerZIndex(topMarkerRef.current, topStageZIndex);
4787
+ }
4788
+ }; // 지도 이벤트 핸들러 등록 (topStage 업데이트용)
4789
+
4790
+
4791
+ var handleTopIdle = function () {
4792
+ // topMarker의 position을 메인 marker와 동일하게 업데이트
4793
+ updateTopMarkerPosition(); // topStage 크기 업데이트
4794
+
4795
+ if (topStageRef.current) {
4796
+ topStageRef.current.width(mapDiv.offsetWidth);
4797
+ topStageRef.current.height(mapDiv.offsetHeight);
4798
+ } // 메인 stage의 transform을 topStage에도 동기화
4799
+
4800
+
4801
+ if (topContainerRef.current && containerRef.current) {
4802
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4803
+ }
4804
+
4805
+ doRenderTop();
4806
+ };
4807
+
4808
+ var handleTopZoomStart = function () {
4809
+ // 메인 stage의 transform을 topStage에도 동기화
4810
+ if (topContainerRef.current && containerRef.current) {
4811
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4812
+ }
4813
+
4814
+ doRenderTop();
4815
+ };
4816
+
4817
+ var handleTopZoomEnd = function () {
4818
+ // 메인 stage의 transform을 topStage에도 동기화
4819
+ if (topContainerRef.current && containerRef.current) {
4820
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4821
+ }
4822
+
4823
+ doRenderTop();
4824
+ };
4825
+
4826
+ var handleTopCenterChanged = function () {
4827
+ // topMarker의 position을 메인 marker와 동일하게 업데이트
4828
+ updateTopMarkerPosition(); // topStage 크기 업데이트
4829
+
4830
+ if (topStageRef.current) {
4831
+ topStageRef.current.width(mapDiv.offsetWidth);
4832
+ topStageRef.current.height(mapDiv.offsetHeight);
4833
+ } // 메인 stage의 transform을 topStage에도 동기화
4834
+
4835
+
4836
+ if (topContainerRef.current && containerRef.current) {
4837
+ topContainerRef.current.style.transform = containerRef.current.style.transform || '';
4838
+ }
4839
+
4840
+ doRenderTop();
4841
+ };
4842
+
4843
+ controller.addEventListener('IDLE', handleTopIdle);
4844
+ controller.addEventListener('ZOOMSTART', handleTopZoomStart);
4845
+ controller.addEventListener('ZOOM_CHANGED', handleTopZoomEnd);
4846
+ controller.addEventListener('CENTER_CHANGED', handleTopCenterChanged);
4847
+ doRenderTop();
4848
+ return function () {
4849
+ if (topResizeRafId !== null) {
4850
+ cancelAnimationFrame(topResizeRafId);
4851
+ }
4852
+
4853
+ topResizeObserver.disconnect();
4854
+ controller.removeEventListener('IDLE', handleTopIdle);
4855
+ controller.removeEventListener('ZOOMSTART', handleTopZoomStart);
4856
+ controller.removeEventListener('ZOOM_CHANGED', handleTopZoomEnd);
4857
+ controller.removeEventListener('CENTER_CHANGED', handleTopCenterChanged);
4858
+
4859
+ if (topLayerRef.current) {
4860
+ topLayerRef.current.destroyChildren();
4861
+ }
4862
+
4863
+ if (topStageRef.current) {
4864
+ topStageRef.current.destroy();
4865
+ }
4866
+
4867
+ if (topMarkerRef.current) {
4868
+ controller.clearDrawable(topMarkerRef.current);
4869
+ topMarkerRef.current = undefined;
4870
+ }
4871
+ };
4872
+ }, [topStageZIndex, renderEvent, options]); // 외부 selectedItems 동기화
4534
4873
 
4535
4874
  React.useEffect(function () {
4536
4875
  if (!stageRef.current) return;
4537
4876
  syncExternalSelectedItems(externalSelectedItems, selectedIdsRef, selectedItemsMapRef);
4538
4877
  doRenderBase();
4539
4878
  doRenderEvent();
4879
+
4880
+ if (topStageZIndex !== undefined && topOnHover) {
4881
+ doRenderTop();
4882
+ }
4540
4883
  }, [externalSelectedItems]); // 외부 selectedItem 변경 시 Event Layer 리렌더링
4541
4884
 
4542
4885
  React.useEffect(function () {
4543
4886
  if (!stageRef.current) return;
4544
4887
  selectedItemRef.current = externalSelectedItem;
4545
4888
  doRenderEvent();
4889
+
4890
+ if (topStageZIndex !== undefined && topOnHover) {
4891
+ doRenderTop();
4892
+ }
4546
4893
  }, [externalSelectedItem]); // 데이터 변경 시 렌더링 (캐시 정리 및 선택 상태 동기화)
4547
4894
 
4548
4895
  React.useEffect(function () {
@@ -4563,14 +4910,21 @@
4563
4910
  selectedItemsMapRef.current = syncSelectedItems(data, selectedIdsRef.current, selectedItemsMapRef.current);
4564
4911
  renderAllImmediate();
4565
4912
  }, [data]);
4566
- return reactDom.createPortal(React__default["default"].createElement("div", {
4913
+ return React__default["default"].createElement(React__default["default"].Fragment, null, reactDom.createPortal(React__default["default"].createElement("div", {
4567
4914
  ref: containerRef,
4568
4915
  style: {
4569
4916
  height: '100%',
4570
4917
  position: 'absolute',
4571
4918
  width: '100%'
4572
4919
  }
4573
- }), divElement);
4920
+ }), divElement), topStageZIndex !== undefined && reactDom.createPortal(React__default["default"].createElement("div", {
4921
+ ref: topContainerRef,
4922
+ style: {
4923
+ height: '100%',
4924
+ position: 'absolute',
4925
+ width: '100%'
4926
+ }
4927
+ }), topDivElement));
4574
4928
  };
4575
4929
 
4576
4930
  /* eslint-disable no-restricted-syntax */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mint-ui/map",
3
- "version": "1.2.0-test.62",
3
+ "version": "1.2.0-test.63",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "browser": "./dist/index.umd.js",