@pisell/materials 1.8.54 → 1.8.55

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 (139) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +3 -3
  5. package/build/lowcode/render/default/view.css +1 -1
  6. package/build/lowcode/render/default/view.js +35 -35
  7. package/build/lowcode/view.css +1 -1
  8. package/build/lowcode/view.js +35 -35
  9. package/es/components/buttonGroupPreview/index.js +8 -4
  10. package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.js +207 -49
  11. package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.less +33 -2
  12. package/es/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +50 -2
  13. package/es/components/pisellFloorMapLayout/components/EdgeLayer.js +252 -0
  14. package/es/components/pisellFloorMapLayout/components/EdgeLayer.less +11 -0
  15. package/es/components/pisellFloorMapLayout/components/EditableItemLayer.js +179 -29
  16. package/es/components/pisellFloorMapLayout/components/EditableItemLayer.less +0 -28
  17. package/es/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.js +131 -0
  18. package/es/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.less +65 -0
  19. package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +5 -4
  20. package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +12 -1
  21. package/es/components/pisellFloorMapLayout/components/FloorMapEditQuickActions.js +8 -1
  22. package/es/components/pisellFloorMapLayout/components/FloorMapOverview.js +16 -8
  23. package/es/components/pisellFloorMapLayout/components/FloorMapOverview.less +69 -17
  24. package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.js +290 -147
  25. package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.less +210 -11
  26. package/es/components/pisellFloorMapLayout/components/FloorMapToolbarViewAllModal.js +81 -0
  27. package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.d.ts +8 -0
  28. package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.js +21 -0
  29. package/es/components/pisellFloorMapLayout/components/FloorMapZoneElement.less +74 -0
  30. package/es/components/pisellFloorMapLayout/components/ItemLayer.less +3 -1
  31. package/es/components/pisellFloorMapLayout/components/NodePortMarkers.js +70 -0
  32. package/es/components/pisellFloorMapLayout/components/NodePortMarkers.less +33 -0
  33. package/es/components/pisellFloorMapLayout/components/ViewControls.js +13 -5
  34. package/es/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +2 -0
  35. package/es/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +2 -1
  36. package/es/components/pisellFloorMapLayout/floorMapLayoutConstants.js +1 -1
  37. package/es/components/pisellFloorMapLayout/hooks/useFloorMapEdgeEditing.js +340 -0
  38. package/es/components/pisellFloorMapLayout/hooks/useFloorMapEdgeViewModel.js +102 -0
  39. package/es/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +244 -84
  40. package/es/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +54 -0
  41. package/es/components/pisellFloorMapLayout/hooks/useShopFloorPlanSubscription.js +7 -4
  42. package/es/components/pisellFloorMapLayout/index.d.ts +5 -1
  43. package/es/components/pisellFloorMapLayout/locales-ja.js +14 -2
  44. package/es/components/pisellFloorMapLayout/locales-pt.js +14 -2
  45. package/es/components/pisellFloorMapLayout/locales.js +161 -8
  46. package/es/components/pisellFloorMapLayout/types.d.ts +86 -4
  47. package/es/components/pisellFloorMapLayout/types.js +5 -1
  48. package/es/components/pisellFloorMapLayout/utils/alignSnap.js +170 -0
  49. package/es/components/pisellFloorMapLayout/utils/batchScenePlacementLayout.js +86 -0
  50. package/es/components/pisellFloorMapLayout/utils/edgeRouting.js +942 -0
  51. package/es/components/pisellFloorMapLayout/utils/floorMapCanvasDisplay.d.ts +7 -0
  52. package/es/components/pisellFloorMapLayout/utils/floorMapCanvasStage.js +23 -1
  53. package/es/components/pisellFloorMapLayout/utils/floorMapConfigMerge.js +11 -2
  54. package/es/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +20 -3
  55. package/es/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +11 -5
  56. package/es/components/pisellFloorMapLayout/utils/floorMapOverviewLayout.js +5 -3
  57. package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.d.ts +20 -0
  58. package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.js +62 -0
  59. package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.d.ts +83 -0
  60. package/es/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.js +29 -0
  61. package/es/components/pisellFloorMapLayout/utils/floorMapToolbarPalette.js +51 -0
  62. package/es/components/productCard/cartSkuCard/components/BookingItem/index.js +14 -0
  63. package/es/components/productCard/cartSkuCard/components/BookingItem/index.less +32 -0
  64. package/es/components/productCard/cartSkuCard/components/timeRange/index.js +1 -2
  65. package/es/components/productCard/cartSkuCard/index.js +17 -11
  66. package/es/components/productCard/lineItem/BookingLineItem.js +6 -4
  67. package/es/components/productCard/lineItem/components/Resources/index.js +45 -0
  68. package/es/components/productCard/lineItem/components/TimeRange/index.js +64 -0
  69. package/es/components/productCard/lineItem/index.js +2 -1
  70. package/es/components/productCard/lineItem/index.less +21 -10
  71. package/es/index.d.ts +6 -2
  72. package/es/index.js +6 -2
  73. package/es/pisell-materials.tw.css +3 -0
  74. package/lib/components/buttonGroupPreview/index.js +8 -4
  75. package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.js +206 -48
  76. package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.less +33 -2
  77. package/lib/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +50 -2
  78. package/lib/components/pisellFloorMapLayout/components/EdgeLayer.js +255 -0
  79. package/lib/components/pisellFloorMapLayout/components/EdgeLayer.less +11 -0
  80. package/lib/components/pisellFloorMapLayout/components/EditableItemLayer.js +179 -29
  81. package/lib/components/pisellFloorMapLayout/components/EditableItemLayer.less +0 -28
  82. package/lib/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.js +134 -0
  83. package/lib/components/pisellFloorMapLayout/components/FloorMapEdgeEditPanel.less +65 -0
  84. package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +4 -3
  85. package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +12 -1
  86. package/lib/components/pisellFloorMapLayout/components/FloorMapEditQuickActions.js +8 -1
  87. package/lib/components/pisellFloorMapLayout/components/FloorMapOverview.js +16 -8
  88. package/lib/components/pisellFloorMapLayout/components/FloorMapOverview.less +69 -17
  89. package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.js +287 -144
  90. package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.less +210 -11
  91. package/lib/components/pisellFloorMapLayout/components/FloorMapToolbarViewAllModal.js +84 -0
  92. package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.d.ts +8 -0
  93. package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.js +23 -0
  94. package/lib/components/pisellFloorMapLayout/components/FloorMapZoneElement.less +74 -0
  95. package/lib/components/pisellFloorMapLayout/components/ItemLayer.less +3 -1
  96. package/lib/components/pisellFloorMapLayout/components/NodePortMarkers.js +73 -0
  97. package/lib/components/pisellFloorMapLayout/components/NodePortMarkers.less +33 -0
  98. package/lib/components/pisellFloorMapLayout/components/ViewControls.js +12 -4
  99. package/lib/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +2 -0
  100. package/lib/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +2 -1
  101. package/lib/components/pisellFloorMapLayout/floorMapLayoutConstants.js +1 -1
  102. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEdgeEditing.js +341 -0
  103. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEdgeViewModel.js +103 -0
  104. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +242 -82
  105. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +54 -0
  106. package/lib/components/pisellFloorMapLayout/hooks/useShopFloorPlanSubscription.js +7 -4
  107. package/lib/components/pisellFloorMapLayout/index.d.ts +5 -1
  108. package/lib/components/pisellFloorMapLayout/locales-ja.js +14 -2
  109. package/lib/components/pisellFloorMapLayout/locales-pt.js +14 -2
  110. package/lib/components/pisellFloorMapLayout/locales.js +161 -8
  111. package/lib/components/pisellFloorMapLayout/types.d.ts +86 -4
  112. package/lib/components/pisellFloorMapLayout/types.js +5 -0
  113. package/lib/components/pisellFloorMapLayout/utils/alignSnap.js +170 -0
  114. package/lib/components/pisellFloorMapLayout/utils/batchScenePlacementLayout.js +87 -0
  115. package/lib/components/pisellFloorMapLayout/utils/edgeRouting.js +956 -0
  116. package/lib/components/pisellFloorMapLayout/utils/floorMapCanvasDisplay.d.ts +7 -0
  117. package/lib/components/pisellFloorMapLayout/utils/floorMapCanvasStage.js +23 -0
  118. package/lib/components/pisellFloorMapLayout/utils/floorMapConfigMerge.js +11 -2
  119. package/lib/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +21 -2
  120. package/lib/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +11 -5
  121. package/lib/components/pisellFloorMapLayout/utils/floorMapOverviewLayout.js +5 -3
  122. package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.d.ts +20 -0
  123. package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerDisplay.js +64 -0
  124. package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.d.ts +83 -0
  125. package/lib/components/pisellFloorMapLayout/utils/floorMapResourcePickerTypes.js +29 -0
  126. package/lib/components/pisellFloorMapLayout/utils/floorMapToolbarPalette.js +54 -0
  127. package/lib/components/productCard/cartSkuCard/components/BookingItem/index.js +17 -0
  128. package/lib/components/productCard/cartSkuCard/components/BookingItem/index.less +32 -0
  129. package/lib/components/productCard/cartSkuCard/components/timeRange/index.js +1 -2
  130. package/lib/components/productCard/cartSkuCard/index.js +17 -11
  131. package/lib/components/productCard/lineItem/BookingLineItem.js +6 -4
  132. package/lib/components/productCard/lineItem/components/Resources/index.js +47 -0
  133. package/lib/components/productCard/lineItem/components/TimeRange/index.js +67 -0
  134. package/lib/components/productCard/lineItem/index.js +2 -1
  135. package/lib/components/productCard/lineItem/index.less +21 -10
  136. package/lib/index.d.ts +6 -2
  137. package/lib/index.js +11 -0
  138. package/lib/pisell-materials.tw.css +3 -0
  139. package/package.json +4 -1
@@ -14,8 +14,13 @@ const require_FloorMapEditTopBar = require("./components/FloorMapEditTopBar.js")
14
14
  const require_mergeCanvasesForTabs = require("./utils/mergeCanvasesForTabs.js");
15
15
  const require_FloorMapOverview = require("./components/FloorMapOverview.js");
16
16
  const require_FloorMapEditPanel = require("./components/FloorMapEditPanel.js");
17
- const require_ViewControlsWithZoom = require("./components/ViewControlsWithZoom.js");
18
17
  const require_layoutMeasurements = require("./utils/layoutMeasurements.js");
18
+ const require_FloorMapEdgeEditPanel = require("./components/FloorMapEdgeEditPanel.js");
19
+ const require_EdgeLayer = require("./components/EdgeLayer.js");
20
+ const require_NodePortMarkers = require("./components/NodePortMarkers.js");
21
+ const require_useFloorMapEdgeViewModel = require("./hooks/useFloorMapEdgeViewModel.js");
22
+ const require_useFloorMapEdgeEditing = require("./hooks/useFloorMapEdgeEditing.js");
23
+ const require_ViewControlsWithZoom = require("./components/ViewControlsWithZoom.js");
19
24
  const require_useFloorMapEditState = require("./hooks/useFloorMapEditState.js");
20
25
  const require_useFloorMapTransformMetrics = require("./hooks/useFloorMapTransformMetrics.js");
21
26
  const require_floorMapFallbackRender = require("./utils/floorMapFallbackRender.js");
@@ -42,8 +47,8 @@ require("./PisellFloorMapLayout.less");
42
47
  * 负责:上下文与 props 合并、编辑态/阅读态分支、Transform 视口、图元层与工具栏联动。
43
48
  */
44
49
  function PisellFloorMapLayoutInner(props, ref) {
45
- var _ref, _currentCanvas$mapLay2, _currentCanvas$mapLay3, _mapLayer$backgroundC, _engineCtx$engine, _mapLayer$boundingPad, _config$sceneElements;
46
- const { className, style, items: itemsProp, renderItem, rowKey, renderItemByKind, getMergedItemWrapperStyle, mapLayer, cellSize: cellSizeProp, itemUnit = "cell", zoom = {}, pan = {}, controls = {}, enableHover = true, readModeSelectedItemId, onItemClick, onItemHover, onItemLeave, mode = "read", floorMapConfig: floorMapConfigProp, dataSources, onSave, onExitEdit, onDataSourceRecordSave, dataSourceLabels, dataSourceFormColumns, dataSourceRecordForm, loading, saveError, onElementRenderError, toolbarShowSave = true, floorMapFullscreenMode, appearanceMode = "light", showDataSourceRecordFormBlock, floorMapViewportOverlay, viewportOverlayPlacement = "top-start", viewportOverlayClassName, editTopBarPhoneLayout = false, canvasTabsBarTrailing, viewportDockToolButtons, viewportDockTrailing, viewportPersist = true, viewportPersistNamespace } = require_mergeFloorMapLayoutContext.mergeFloorMapLayoutPropsFromContext(props, require_FloorMapLayoutContext.useFloorMapLayoutContext());
50
+ var _ref, _currentCanvas$mapLay2, _currentCanvas$mapLay3, _mapLayer$backgroundC, _engineCtx$engine, _mapLayer$boundingPad, _config$edges, _config$edges2, _config$sceneElements;
51
+ const { className, style, items: itemsProp, renderItem, rowKey, renderItemByKind, getMergedItemWrapperStyle, enableEdges = false, mapLayer, cellSize: cellSizeProp, itemUnit = "cell", zoom = {}, pan = {}, controls = {}, enableHover = true, readModeSelectedItemId, onItemClick, onItemHover, onItemLeave, mode = "read", floorMapConfig: floorMapConfigProp, dataSources, onSave, onExitEdit, onDataSourceRecordSave, dataSourceLabels, dataSourceFormColumns, dataSourceRecordForm, loading, saveError, onElementRenderError, toolbarShowSave = true, renderResourcePickerModal, paletteSidebarVisibleLimit, floorMapFullscreenMode, appearanceMode = "light", showDataSourceRecordFormBlock, floorMapViewportOverlay, viewportOverlayPlacement = "top-start", viewportOverlayClassName, editTopBarPhoneLayout = false, canvasTabsBarTrailing, viewportDockToolButtons, viewportDockTrailing, viewportPersist = true, viewportPersistNamespace } = require_mergeFloorMapLayoutContext.mergeFloorMapLayoutPropsFromContext(props, require_FloorMapLayoutContext.useFloorMapLayoutContext());
47
52
  const { token } = antd.theme.useToken();
48
53
  const isFloorMapView = Boolean(floorMapConfigProp);
49
54
  const contentOffsetRef = (0, react.useRef)({
@@ -52,7 +57,8 @@ function PisellFloorMapLayoutInner(props, ref) {
52
57
  });
53
58
  const mapDropLayerRef = (0, react.useRef)(null);
54
59
  const transformRef = (0, react.useRef)(null);
55
- const { config, currentCanvasId, setCurrentCanvasId, selectedId, setSelectedId, placeMode, setPlaceMode, items, saving, savingRecord, handleAddCanvas, handleRemoveCanvas, handleRenameCanvas, handleUpdateItem, handleCanvasPlaceClick, handleSave, placeSceneElementFromPaletteDrop, editPanelParams, placeOverlayClass, isLayoutDirty, toggleDraftCanvasShowGrid, toggleSelectedLayoutLock, duplicateSelectedElement, deleteSelectedElement, undoDraft, redoDraft, canUndo, canRedo, discardDraft } = require_useFloorMapEditState.useFloorMapEditState({
60
+ const focusViewportOnBoundsRef = (0, react.useRef)(null);
61
+ const { config, currentCanvasId, setCurrentCanvasId, selectedId, setSelectedId, placeMode, setPlaceMode, items, saving, savingRecord, handleAddCanvas, handleRemoveCanvas, handleRenameCanvas, handleUpdateItem, handleCanvasPlaceClick, handleSave, placeSceneElementFromPaletteDrop, bulkPlacePaletteItems, editPanelParams, placeOverlayClass, isLayoutDirty, toggleDraftCanvasShowGrid, toggleSelectedLayoutLock, duplicateSelectedElement, deleteSelectedElement, undoDraft, redoDraft, canUndo, canRedo, discardDraft, commitDraft } = require_useFloorMapEditState.useFloorMapEditState({
56
62
  floorMapConfigProp,
57
63
  isFloorMapView,
58
64
  itemsProp,
@@ -65,8 +71,10 @@ function PisellFloorMapLayoutInner(props, ref) {
65
71
  dataSourceLabels,
66
72
  layoutPrefix: require_floorMapLayoutConstants.FLOOR_MAP_LAYOUT_CLASS_PREFIX,
67
73
  contentOffsetRef,
68
- showDataSourceRecordFormBlock
74
+ showDataSourceRecordFormBlock,
75
+ focusViewportOnBoundsRef
69
76
  });
77
+ const mapContentRef = (0, react.useRef)(null);
70
78
  /**
71
79
  * 当前选中的画布配置:用于提取当前画布级 mapLayer 显式配置。
72
80
  */
@@ -149,25 +157,26 @@ function PisellFloorMapLayoutInner(props, ref) {
149
157
  const engineLocale = (engineCtx === null || engineCtx === void 0 || (_engineCtx$engine = engineCtx.engine) === null || _engineCtx$engine === void 0 || (_engineCtx$engine = _engineCtx$engine.props) === null || _engineCtx$engine === void 0 ? void 0 : _engineCtx$engine.locale) || "zh-CN";
150
158
  const hasCanvasTabsBarTrailing = canvasTabsBarTrailing != null && canvasTabsBarTrailing !== false;
151
159
  const enabledCanvasCount = (0, react.useMemo)(() => canvasesForTabsBase.filter((c) => c.enabled).length, [canvasesForTabsBase]);
152
- /** 仅阅读态、启用画布 > 1 时,在 Tab 列表最前插入「All」伪 tab */
160
+ /** 仅阅读态、启用画布 > 1 时,在 Tab 列表末尾插入「Overview」伪 tab */
153
161
  const showOverviewTab = isFloorMapView && mode === "read" && enabledCanvasCount > 1;
154
162
  const overviewTabLabel = (0, react.useMemo)(() => {
155
163
  require_floorMapCanvasDisplay.initFloorMapLayoutLocales(engineLocale);
156
164
  return _pisell_utils.locales.getText("pisell-floor-map-layout.canvas-tabs.overview");
157
165
  }, [engineLocale]);
158
166
  /**
159
- * 给 CanvasTabs 渲染用的最终列表:阅读态多画布时在列表最前插入「All」伪 tab。
160
- * order 取当前最小 order - 1,保证排序后位于第一个;其它字段留空。
167
+ * 给 CanvasTabs 渲染用的最终列表:阅读态多画布时在列表末尾插入「Overview」伪 tab。
168
+ * order 取当前最大 order + 1,保证排序后位于最后一个。
161
169
  */
162
170
  const canvasesForTabs = (0, react.useMemo)(() => {
163
171
  if (!showOverviewTab) return canvasesForTabsBase;
164
- const minOrder = canvasesForTabsBase.reduce((min, c) => c.order < min ? c.order : min, Number.POSITIVE_INFINITY);
165
- return [{
172
+ const maxOrder = canvasesForTabsBase.reduce((max, c) => c.order > max ? c.order : max, Number.NEGATIVE_INFINITY);
173
+ const overviewTab = {
166
174
  id: require_floorMapLayoutConstants.FLOOR_MAP_OVERVIEW_TAB_ID,
167
175
  name: overviewTabLabel,
168
- order: Number.isFinite(minOrder) ? minOrder - 1 : -1,
176
+ order: Number.isFinite(maxOrder) ? maxOrder + 1 : 0,
169
177
  enabled: true
170
- }, ...canvasesForTabsBase];
178
+ };
179
+ return [...canvasesForTabsBase, overviewTab];
171
180
  }, [
172
181
  canvasesForTabsBase,
173
182
  showOverviewTab,
@@ -260,7 +269,7 @@ function PisellFloorMapLayoutInner(props, ref) {
260
269
  globalMapLayer: mapLayer,
261
270
  cellSize,
262
271
  itemUnit: effectiveItemUnit,
263
- areaGap: 32
272
+ areaGap: 40
264
273
  });
265
274
  }, [
266
275
  isFloorMapView,
@@ -308,7 +317,7 @@ function PisellFloorMapLayoutInner(props, ref) {
308
317
  shape: "rect"
309
318
  }];
310
319
  }, [overviewLayout]);
311
- const { containerRef, mapAreaRef, mapAreaSize, contentWidth, contentHeight, contentOffsetX, contentOffsetY, initialPositionX, initialPositionY, zoomConfig, scale, setScale, isFullscreen, toggleFullscreen, fitBounds, isAtFitBounds, notifyTransformed, persistCurrentViewport, attachTransformContext, isInteractingWithElement, setIsInteractingWithElement, viewportLocked, toggleViewportLocked } = require_useFloorMapTransformMetrics.useFloorMapTransformMetrics({
320
+ const { containerRef, mapAreaRef, mapAreaSize, contentWidth, contentHeight, contentOffsetX, contentOffsetY, initialPositionX, initialPositionY, zoomConfig, scale, setScale, isFullscreen, toggleFullscreen, fitBounds, focusContentBounds, isAtFitBounds, notifyTransformed, persistCurrentViewport, attachTransformContext, isInteractingWithElement, setIsInteractingWithElement, viewportLocked, toggleViewportLocked } = require_useFloorMapTransformMetrics.useFloorMapTransformMetrics({
312
321
  items: isOverview && overviewLayout ? overviewMetricsItems : items,
313
322
  cellSize,
314
323
  itemGap: isOverview ? 0 : itemGap,
@@ -322,20 +331,81 @@ function PisellFloorMapLayoutInner(props, ref) {
322
331
  frameResetKey: isFloorMapView ? transformWrapperKey : void 0,
323
332
  viewportPersistKey
324
333
  });
325
- /** 手机:选中图元种类后一键落在当前视口中心(与点击画布落点坐标换算一致) */
326
- const handlePlaceActiveAtViewportCenter = (0, react.useCallback)(() => {
327
- if (!placeMode || placeMode.type !== "scene") return;
334
+ (0, react.useEffect)(() => {
335
+ focusViewportOnBoundsRef.current = (bounds) => {
336
+ requestAnimationFrame(() => {
337
+ requestAnimationFrame(() => {
338
+ focusContentBounds(bounds);
339
+ });
340
+ });
341
+ };
342
+ return () => {
343
+ focusViewportOnBoundsRef.current = null;
344
+ };
345
+ }, [focusContentBounds]);
346
+ /**
347
+ * 是否启用连线(edge)渲染与编辑能力。
348
+ * - 必须显式 `enableEdges={true}` 才打开;
349
+ * - pisell-reservation 等通用业务画布默认关闭,避免选中图元出现锚点圆点或拖出连线。
350
+ */
351
+ const showEdgeLayer = enableEdges && isFloorMapView && !isOverview && config != null;
352
+ /** 连线层显隐(仅影响 EdgeLayer 绘制;编辑锚点仍随 `showEdgeLayer`) */
353
+ const [edgesLayerVisible, setEdgesLayerVisible] = (0, react.useState)(true);
354
+ const showEdgesOnCanvas = showEdgeLayer && edgesLayerVisible;
355
+ const toggleEdgesLayerVisible = (0, react.useCallback)(() => {
356
+ setEdgesLayerVisible((v) => !v);
357
+ }, []);
358
+ const readEdgeVm = require_useFloorMapEdgeViewModel.useFloorMapEdgeViewModel({
359
+ edges: showEdgeLayer && mode === "read" ? (_config$edges = config === null || config === void 0 ? void 0 : config.edges) !== null && _config$edges !== void 0 ? _config$edges : [] : [],
360
+ items: showEdgeLayer ? items : [],
361
+ cellSize,
362
+ itemUnit: effectiveItemUnit,
363
+ itemGap
364
+ });
365
+ const edgeEdit = require_useFloorMapEdgeEditing.useFloorMapEdgeEditing({
366
+ enabled: showEdgeLayer && mode === "edit",
367
+ config,
368
+ items,
369
+ mergedItems: items,
370
+ cellSize,
371
+ itemUnit: effectiveItemUnit,
372
+ itemGap,
373
+ contentOffsetRef,
374
+ selectedId,
375
+ setSelectedId,
376
+ commitDraft,
377
+ mapContentRef,
378
+ scale
379
+ });
380
+ const edgeRoutes = mode === "edit" && showEdgeLayer ? edgeEdit.routes : readEdgeVm.routes;
381
+ const edgeRectsById = mode === "edit" && showEdgeLayer ? edgeEdit.rectsById : readEdgeVm.rectsById;
382
+ const displayEdges = mode === "edit" && showEdgeLayer ? edgeEdit.edges : (_config$edges2 = config === null || config === void 0 ? void 0 : config.edges) !== null && _config$edges2 !== void 0 ? _config$edges2 : [];
383
+ const getViewportCenterContentCoords = (0, react.useCallback)(() => {
328
384
  const w = mapAreaSize.width;
329
385
  const h = mapAreaSize.height;
330
- if (w <= 0 || h <= 0) return;
386
+ if (w <= 0 || h <= 0) return null;
331
387
  const { x: ox, y: oy } = contentOffsetRef.current;
332
- placeSceneElementFromPaletteDrop(Math.round(w / 2 - ox), Math.round(h / 2 - oy), placeMode);
388
+ return {
389
+ x: Math.round(w / 2 - ox),
390
+ y: Math.round(h / 2 - oy)
391
+ };
392
+ }, [mapAreaSize.width, mapAreaSize.height]);
393
+ /** 手机:选中图元种类后一键落在当前视口中心(与点击画布落点坐标换算一致) */
394
+ const handlePlaceActiveAtViewportCenter = (0, react.useCallback)(() => {
395
+ if (!placeMode || placeMode.type !== "scene") return;
396
+ const center = getViewportCenterContentCoords();
397
+ if (!center) return;
398
+ placeSceneElementFromPaletteDrop(center.x, center.y, placeMode);
333
399
  }, [
334
400
  placeMode,
335
- mapAreaSize.width,
336
- mapAreaSize.height,
401
+ getViewportCenterContentCoords,
337
402
  placeSceneElementFromPaletteDrop
338
403
  ]);
404
+ /** 侧栏「查看更多」:按数量批量落在画布右侧空白区(方阵网格 + gap) */
405
+ const handleBulkAddPaletteToCanvas = (0, react.useCallback)((items) => {
406
+ if (!items.length) return;
407
+ bulkPlacePaletteItems(items);
408
+ }, [bulkPlacePaletteItems]);
339
409
  /** 编辑态全屏策略:toggle 全屏与编辑态强绑定;locked 始终全屏顶栏;disabled 无全屏 */
340
410
  const fsMode = floorMapFullscreenMode !== null && floorMapFullscreenMode !== void 0 ? floorMapFullscreenMode : "toggle";
341
411
  const useFullTopChrome = isFloorMapView && mode === "edit" && (fsMode === "locked" || fsMode === "toggle" && isFullscreen);
@@ -372,16 +442,18 @@ function PisellFloorMapLayoutInner(props, ref) {
372
442
  * 并默认带出「视口锁定」按钮(与是否将视口保存到本地解耦;无持久化 key 时仅内存态,默认未锁定)。
373
443
  */
374
444
  const viewControlsConfig = (0, react.useMemo)(() => {
375
- var _controls$showFullscr, _controls$showViewpor;
445
+ var _controls$showFullscr, _controls$showViewpor, _controls$showEdgesTo;
376
446
  if (!isFloorMapView) return controls;
377
447
  return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, controls), {}, {
378
448
  showFullscreen: (_controls$showFullscr = controls.showFullscreen) !== null && _controls$showFullscr !== void 0 ? _controls$showFullscr : Boolean(dockToggleFullscreen),
379
- showViewportLock: (_controls$showViewpor = controls.showViewportLock) !== null && _controls$showViewpor !== void 0 ? _controls$showViewpor : true
449
+ showViewportLock: (_controls$showViewpor = controls.showViewportLock) !== null && _controls$showViewpor !== void 0 ? _controls$showViewpor : true,
450
+ showEdgesToggle: showEdgeLayer ? (_controls$showEdgesTo = controls.showEdgesToggle) !== null && _controls$showEdgesTo !== void 0 ? _controls$showEdgesTo : true : controls.showEdgesToggle
380
451
  });
381
452
  }, [
382
453
  isFloorMapView,
383
454
  controls,
384
- dockToggleFullscreen
455
+ dockToggleFullscreen,
456
+ showEdgeLayer
385
457
  ]);
386
458
  const topBarExtraActions = null;
387
459
  /** 从侧栏/调色板拖入画布时,地图区高亮态(用于 dragleave/over 判定) */
@@ -547,8 +619,17 @@ function PisellFloorMapLayoutInner(props, ref) {
547
619
  return (_transformRef$current3 = transformRef.current) === null || _transformRef$current3 === void 0 ? void 0 : _transformRef$current3.resetTransform();
548
620
  },
549
621
  fitBounds,
550
- saveLayout: () => handleSave()
551
- }), [fitBounds, handleSave]);
622
+ saveLayout: () => handleSave(),
623
+ applySceneSnapshot: (next) => {
624
+ if (mode !== "edit") return;
625
+ commitDraft(() => next);
626
+ }
627
+ }), [
628
+ fitBounds,
629
+ handleSave,
630
+ mode,
631
+ commitDraft
632
+ ]);
552
633
  const showSidebar = isFloorMapView && mode === "edit" && config && dataSources;
553
634
  /** 右侧属性面板打开时给画布区留空,避免落点被挡在面板下 */
554
635
  const editPanelVisible = isFloorMapView && mode === "edit" && Boolean(editPanelParams) && Boolean(config) && Boolean(dataSources);
@@ -687,8 +768,8 @@ function PisellFloorMapLayoutInner(props, ref) {
687
768
  sceneElements: (_config$sceneElements = config.sceneElements) !== null && _config$sceneElements !== void 0 ? _config$sceneElements : [],
688
769
  renderPreviewItem: (item) => effectiveRenderItem(item, 0),
689
770
  placementPreviewSize: {
690
- width: 180,
691
- height: 120
771
+ width: require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.width,
772
+ height: require_floorMapElementKindUtils.FLOOR_MAP_RESOURCE_PLACE_DEFAULT.height
692
773
  },
693
774
  decorationPreviewSize: 48,
694
775
  onSave: onSave && config.canvasUi.canEdit && !useFullTopChrome && toolbarShowSave !== false ? handleSave : void 0,
@@ -699,7 +780,16 @@ function PisellFloorMapLayoutInner(props, ref) {
699
780
  consumeToolbarClickIfTouchDrag: paletteTouchDrag.consumeToolbarClickIfTouchDrag,
700
781
  phoneLayout: editTopBarPhoneLayout,
701
782
  defaultCollapsed: editTopBarPhoneLayout,
702
- onRequestPlaceAtCanvasCenter: editTopBarPhoneLayout ? handlePlaceActiveAtViewportCenter : void 0
783
+ paletteSidebarVisibleLimit,
784
+ onRequestPlaceAtCanvasCenter: editTopBarPhoneLayout ? handlePlaceActiveAtViewportCenter : void 0,
785
+ onBulkAddPaletteToCanvas: handleBulkAddPaletteToCanvas,
786
+ onDirectPlacePaletteItem: (item) => bulkPlacePaletteItems([item]),
787
+ onResourcePickerConfirmPlace: (scene) => {
788
+ const center = getViewportCenterContentCoords();
789
+ if (!center) return false;
790
+ return placeSceneElementFromPaletteDrop(center.x, center.y, scene);
791
+ },
792
+ renderResourcePickerModal
703
793
  }), /* @__PURE__ */ react.default.createElement("div", {
704
794
  ref: mapAreaRef,
705
795
  className: (0, classnames.default)(showSidebar && `pisell-floor-map-layout-map-area`, editTopBarPhoneLayout && showSidebar && `pisell-floor-map-layout-map-area--phone-fill`, editPanelVisible && !editTopBarPhoneLayout && `pisell-floor-map-layout-map-area--edit-panel-inset`),
@@ -769,7 +859,7 @@ function PisellFloorMapLayoutInner(props, ref) {
769
859
  onPinchingStop: persistCurrentViewport,
770
860
  onWheelStop: persistCurrentViewport
771
861
  }), (ctx) => {
772
- var _effectiveMapLayer$sn;
862
+ var _effectiveMapLayer$sn, _edgeEdit$drawing;
773
863
  /**
774
864
  * 不直接 transformRef.current = ctx:
775
865
  * attachTransformContext 内部会比对 ctx 实例并在每次 wrapper 重挂载时
@@ -820,14 +910,37 @@ function PisellFloorMapLayoutInner(props, ref) {
820
910
  getMergedItemWrapperStyle,
821
911
  readModeSelectedItemId
822
912
  })
823
- ) : /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(require_MapLayer.default, {
913
+ ) : /* @__PURE__ */ react.default.createElement("div", {
914
+ ref: mapContentRef,
915
+ className: `${require_floorMapLayoutConstants.FLOOR_MAP_LAYOUT_CLASS_PREFIX}-map-content`,
916
+ style: {
917
+ position: "relative",
918
+ width: contentWidth,
919
+ height: contentHeight
920
+ }
921
+ }, /* @__PURE__ */ react.default.createElement(require_MapLayer.default, {
824
922
  config: effectiveMapLayer,
825
923
  contentWidth,
826
924
  contentHeight,
827
925
  cellSize,
828
926
  preferCanvasGrid: true,
829
927
  pointerEventsNone: isFloorMapView && mode === "edit"
830
- }), isFloorMapView && mode === "edit" ? /* @__PURE__ */ react.default.createElement(require_EditableItemLayer.default, {
928
+ }), showEdgesOnCanvas ? /* @__PURE__ */ react.default.createElement(require_EdgeLayer.EdgeLayer, {
929
+ width: contentWidth,
930
+ height: contentHeight,
931
+ contentOffsetX,
932
+ contentOffsetY,
933
+ edges: displayEdges,
934
+ routes: edgeRoutes,
935
+ rectsById: edgeRectsById,
936
+ appearance: appearanceTokens,
937
+ mode,
938
+ selectedEdgeId: mode === "edit" ? edgeEdit.selectedEdgeId : null,
939
+ ghostPathD: mode === "edit" ? edgeEdit.ghostPathD : null,
940
+ onEdgeClick: mode === "edit" ? (edgeId) => edgeEdit.handleEdgeClick(edgeId) : void 0,
941
+ viewportScale: scale,
942
+ onSegmentDragStart: mode === "edit" ? edgeEdit.startDraggingSegment : void 0
943
+ }) : null, isFloorMapView && mode === "edit" ? /* @__PURE__ */ react.default.createElement(require_EditableItemLayer.default, {
831
944
  items,
832
945
  renderItem: effectiveRenderItem,
833
946
  rowKey,
@@ -839,11 +952,24 @@ function PisellFloorMapLayoutInner(props, ref) {
839
952
  contentOffsetX,
840
953
  contentOffsetY,
841
954
  selectedId,
842
- onSelect: setSelectedId,
955
+ onSelect: edgeEdit.selectNode,
843
956
  onUpdateItem: handleUpdateItem,
844
957
  snapStep: (_effectiveMapLayer$sn = effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.snapStep) !== null && _effectiveMapLayer$sn !== void 0 ? _effectiveMapLayer$sn : 0,
845
958
  scale,
846
959
  onInteractionChange: setIsInteractingWithElement,
960
+ onLiveRectChange: (itemId, rect) => {
961
+ if (!itemId || !rect) {
962
+ edgeEdit.setPendingRectsById({});
963
+ return;
964
+ }
965
+ edgeEdit.setPendingRectsById({ [itemId]: {
966
+ left: rect.left,
967
+ top: rect.top,
968
+ width: rect.width,
969
+ height: rect.height
970
+ } });
971
+ },
972
+ alignGuideStroke: appearanceTokens.alignGuideStroke,
847
973
  getMergedItemWrapperStyle,
848
974
  editQuickBar
849
975
  }) : /* @__PURE__ */ react.default.createElement(require_ItemLayer.default, {
@@ -866,7 +992,24 @@ function PisellFloorMapLayoutInner(props, ref) {
866
992
  getMergedItemWrapperStyle,
867
993
  onInteractionChange: setIsInteractingWithElement,
868
994
  readModeSelectedItemId
869
- }), isFloorMapView && mode === "edit" && (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && /* @__PURE__ */ react.default.createElement("div", {
995
+ }), isFloorMapView && mode === "edit" && showEdgeLayer && selectedId && edgeEdit.selectedNodeRect ? /* @__PURE__ */ react.default.createElement(require_NodePortMarkers.NodePortMarkers, {
996
+ rect: edgeEdit.selectedNodeRect,
997
+ contentOffsetX,
998
+ contentOffsetY,
999
+ viewportScale: scale,
1000
+ highlightAnchors: ((_edgeEdit$drawing = edgeEdit.drawing) === null || _edgeEdit$drawing === void 0 ? void 0 : _edgeEdit$drawing.fromInstanceId) === selectedId ? [edgeEdit.drawing.fromAnchor] : [],
1001
+ onAnchorPointerDown: (anchor) => {
1002
+ if (selectedId) edgeEdit.startDrawingFromAnchor(selectedId, anchor);
1003
+ }
1004
+ }) : null, isFloorMapView && mode === "edit" && showEdgeLayer && edgeEdit.drawing && edgeEdit.drawingTargetPreview ? /* @__PURE__ */ react.default.createElement(require_NodePortMarkers.NodePortMarkers, {
1005
+ className: `${require_floorMapLayoutConstants.FLOOR_MAP_LAYOUT_CLASS_PREFIX}-port-markers--draw-target`,
1006
+ rect: edgeEdit.drawingTargetPreview.rect,
1007
+ contentOffsetX,
1008
+ contentOffsetY,
1009
+ viewportScale: scale,
1010
+ previewOnly: true,
1011
+ highlightAnchors: [edgeEdit.drawingTargetPreview.anchor]
1012
+ }) : null, isFloorMapView && mode === "edit" && (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && /* @__PURE__ */ react.default.createElement("div", {
870
1013
  className: placeOverlayClass,
871
1014
  style: {
872
1015
  width: contentWidth,
@@ -884,7 +1027,11 @@ function PisellFloorMapLayoutInner(props, ref) {
884
1027
  ev.preventDefault();
885
1028
  ev.stopPropagation();
886
1029
  },
887
- onDrop: handlePaletteDropOnCanvas
1030
+ onDrop: handlePaletteDropOnCanvas,
1031
+ onClick: () => {
1032
+ if ((placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene") return;
1033
+ edgeEdit.handleMapBackgroundClick();
1034
+ }
888
1035
  }))), /* @__PURE__ */ react.default.createElement(require_ViewControlsWithZoom.ViewControlsWithZoom, {
889
1036
  config: viewControlsConfig,
890
1037
  scale,
@@ -894,6 +1041,8 @@ function PisellFloorMapLayoutInner(props, ref) {
894
1041
  toggleFullscreen: dockToggleFullscreen,
895
1042
  mapGridVisible: isOverview ? false : Boolean(effectiveMapLayer === null || effectiveMapLayer === void 0 ? void 0 : effectiveMapLayer.showGrid),
896
1043
  onToggleMapGrid: isFloorMapView && !isOverview ? toggleDraftCanvasShowGrid : void 0,
1044
+ edgesLayerVisible,
1045
+ onToggleEdgesLayer: showEdgeLayer ? toggleEdgesLayerVisible : void 0,
897
1046
  viewportLocked,
898
1047
  onToggleViewportLock: isFloorMapView ? toggleViewportLocked : void 0,
899
1048
  dockChrome: isFloorMapView,
@@ -905,21 +1054,22 @@ function PisellFloorMapLayoutInner(props, ref) {
905
1054
  dataSources,
906
1055
  currentCanvasId,
907
1056
  mode
908
- }) : floorMapViewportOverlay) : null, isFloorMapView && mode === "edit" && editPanelParams && config && dataSources && !editTopBarPhoneLayout && /* @__PURE__ */ react.default.createElement("div", {
1057
+ }) : floorMapViewportOverlay) : null, isFloorMapView && mode === "edit" && config && dataSources && !editTopBarPhoneLayout && (edgeEdit.selectedEdge || editPanelParams) && /* @__PURE__ */ react.default.createElement("div", {
909
1058
  className: (0, classnames.default)(`pisell-floor-map-layout-edit-panel-wrap`, mapAreaSize.height > 0 && `pisell-floor-map-layout-edit-panel-wrap-constrained`),
910
- style: mapAreaSize.height > 0 ? {
911
- height: mapAreaSize.height - 32,
912
- maxHeight: mapAreaSize.height - 32,
913
- overflow: "hidden",
914
- top: 16,
915
- transform: "none"
916
- } : void 0
917
- }, /* @__PURE__ */ react.default.createElement(require_FloorMapEditPanel.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, editPanelParams), {}, {
1059
+ style: mapAreaSize.height > 0 ? { overflow: "hidden" } : void 0
1060
+ }, edgeEdit.selectedEdge ? /* @__PURE__ */ react.default.createElement(require_FloorMapEdgeEditPanel.FloorMapEdgeEditPanel, {
1061
+ edge: edgeEdit.selectedEdge,
1062
+ config,
1063
+ onUpdate: (patch) => edgeEdit.updateEdge(edgeEdit.selectedEdge.id, patch),
1064
+ onClose: () => edgeEdit.selectEdge(null),
1065
+ onDelete: config.canvasUi.canEdit ? () => edgeEdit.deleteEdge(edgeEdit.selectedEdge.id) : void 0,
1066
+ layoutDraftDirty: isLayoutDirty
1067
+ }) : editPanelParams ? /* @__PURE__ */ react.default.createElement(require_FloorMapEditPanel.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, editPanelParams), {}, {
918
1068
  config,
919
1069
  dataSources,
920
1070
  savingRecord
921
- }))));
922
- })))), editTopBarPhoneLayout && editPanelParams && config && dataSources && /* @__PURE__ */ react.default.createElement(antd.Drawer, {
1071
+ })) : null));
1072
+ })))), editTopBarPhoneLayout && config && dataSources && (edgeEdit.selectedEdge || editPanelParams) && /* @__PURE__ */ react.default.createElement(antd.Drawer, {
923
1073
  placement: "right",
924
1074
  open: phoneEditDrawerOpen,
925
1075
  onClose: handlePhoneEditDrawerClose,
@@ -937,12 +1087,20 @@ function PisellFloorMapLayoutInner(props, ref) {
937
1087
  height: "100%"
938
1088
  } },
939
1089
  getContainer: typeof document !== "undefined" ? () => document.body : void 0
940
- }, /* @__PURE__ */ react.default.createElement("div", { className: (0, classnames.default)(`pisell-floor-map-layout-edit-panel-wrap`, `pisell-floor-map-layout-edit-panel-wrap--phone-drawer`) }, /* @__PURE__ */ react.default.createElement(require_FloorMapEditPanel.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, editPanelParams), {}, {
1090
+ }, /* @__PURE__ */ react.default.createElement("div", { className: (0, classnames.default)(`pisell-floor-map-layout-edit-panel-wrap`, `pisell-floor-map-layout-edit-panel-wrap--phone-drawer`) }, edgeEdit.selectedEdge ? /* @__PURE__ */ react.default.createElement(require_FloorMapEdgeEditPanel.FloorMapEdgeEditPanel, {
1091
+ edge: edgeEdit.selectedEdge,
1092
+ config,
1093
+ onUpdate: (patch) => edgeEdit.updateEdge(edgeEdit.selectedEdge.id, patch),
1094
+ onClose: () => edgeEdit.selectEdge(null),
1095
+ onDelete: config.canvasUi.canEdit ? () => edgeEdit.deleteEdge(edgeEdit.selectedEdge.id) : void 0,
1096
+ layoutDraftDirty: isLayoutDirty,
1097
+ className: `pisell-floor-map-layout-edit-panel--phone-drawer`
1098
+ }) : editPanelParams ? /* @__PURE__ */ react.default.createElement(require_FloorMapEditPanel.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, editPanelParams), {}, {
941
1099
  config,
942
1100
  dataSources,
943
1101
  savingRecord,
944
1102
  className: `pisell-floor-map-layout-edit-panel--phone-drawer`
945
- })))));
1103
+ })) : null)));
946
1104
  }
947
1105
  /** 空间布局根组件:阅读/编辑、列表与平面图双模式,ref 见 {@link PisellFloorMapLayoutRef} */
948
1106
  const PisellFloorMapLayout = react.default.forwardRef(PisellFloorMapLayoutInner);
@@ -63,12 +63,35 @@ body.pisell-floor-map-layout-fullscreen-host {
63
63
  z-index: 5;
64
64
  }
65
65
 
66
+ /**
67
+ * 右侧编辑面板(图元 / 连线共用):上下锚定,底部留出 ViewControls Dock,
68
+ * 避免面板白底盖住右下缩放等操作栏。
69
+ */
66
70
  &-edit-panel-wrap {
67
71
  position: absolute;
68
- top: 50%;
72
+ top: 16px;
69
73
  right: 16px;
70
- transform: translateY(-50%);
74
+ bottom: calc(16px + var(--fmap-viewport-dock-bottom-clearance, 78px));
75
+ transform: none;
71
76
  z-index: 10;
77
+ display: flex;
78
+ flex-direction: column;
79
+ align-items: stretch;
80
+ min-height: 0;
81
+ max-width: min(280px, calc(100% - 32px));
82
+
83
+ > .pisell-floor-map-layout-edit-panel,
84
+ > .pisell-floor-map-layout-edge-edit-panel {
85
+ flex: 1 1 auto;
86
+ min-height: 0;
87
+ max-height: 100%;
88
+ height: auto;
89
+ box-sizing: border-box;
90
+ }
91
+ }
92
+
93
+ &-edit-panel-wrap-constrained {
94
+ overflow: hidden;
72
95
  }
73
96
 
74
97
  &-edit-panel-wrap--phone-drawer {
@@ -136,6 +159,14 @@ body.pisell-floor-map-layout-fullscreen-host {
136
159
 
137
160
  /** 视口内悬浮层:不随 Transform 缩放平移,与 ViewControls 同级 */
138
161
 
162
+ /**
163
+ * 右下 ViewControls Dock(14px + 56px chrome + 8px 间距),供右侧编辑面板底部留白。
164
+ * 数值与 {@link FLOOR_MAP_VIEWPORT_DOCK_BOTTOM_CLEARANCE} 保持一致。
165
+ */
166
+ &-floor-map-view {
167
+ --fmap-viewport-dock-bottom-clearance: 78px;
168
+ }
169
+
139
170
  &-viewport-overlay {
140
171
  position: absolute;
141
172
  left: 12px;
@@ -3,11 +3,59 @@ const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0
3
3
  const FLOOR_MAP_APPEARANCE_TOKENS = {
4
4
  light: {
5
5
  mode: "light",
6
- fallbackCanvasBackgroundColor: "#F2F4F7"
6
+ fallbackCanvasBackgroundColor: "#F2F4F7",
7
+ edgeStatusStyles: {
8
+ online: {
9
+ stroke: "#12B76A",
10
+ dashed: false
11
+ },
12
+ offline: {
13
+ stroke: "#98A2B3",
14
+ dashed: true
15
+ },
16
+ warning: {
17
+ stroke: "#F79009",
18
+ dashed: false
19
+ },
20
+ unknown: {
21
+ stroke: "#667085",
22
+ dashed: false
23
+ }
24
+ },
25
+ edgeSelectedStroke: "#1570EF",
26
+ edgeGhostStroke: "#84CAFF",
27
+ edgePortLabelBackground: "#FFFFFF",
28
+ edgePortLabelText: "#344054",
29
+ edgePortLabelBorder: "#D0D5DD",
30
+ alignGuideStroke: "#1570EF"
7
31
  },
8
32
  dark: {
9
33
  mode: "dark",
10
- fallbackCanvasBackgroundColor: "#31353d"
34
+ fallbackCanvasBackgroundColor: "#31353d",
35
+ edgeStatusStyles: {
36
+ online: {
37
+ stroke: "#32D583",
38
+ dashed: false
39
+ },
40
+ offline: {
41
+ stroke: "#667085",
42
+ dashed: true
43
+ },
44
+ warning: {
45
+ stroke: "#FDB022",
46
+ dashed: false
47
+ },
48
+ unknown: {
49
+ stroke: "#98A2B3",
50
+ dashed: false
51
+ }
52
+ },
53
+ edgeSelectedStroke: "#53B1FD",
54
+ edgeGhostStroke: "#2E90FA",
55
+ edgePortLabelBackground: "#1D2939",
56
+ edgePortLabelText: "#F2F4F7",
57
+ edgePortLabelBorder: "#475467",
58
+ alignGuideStroke: "#53B1FD"
11
59
  }
12
60
  };
13
61
  /**