@pisell/materials 1.8.34 → 1.8.36

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 (86) 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/index.js +1 -1
  5. package/build/lowcode/meta.js +2 -2
  6. package/build/lowcode/preview.js +1 -1
  7. package/build/lowcode/render/default/view.css +1 -1
  8. package/build/lowcode/render/default/view.js +35 -35
  9. package/build/lowcode/view.css +1 -1
  10. package/build/lowcode/view.js +35 -35
  11. package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.js +25 -10
  12. package/es/components/pisellFloorMapLayout/appearance/floorMapAppearance.d.ts +4 -0
  13. package/es/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +22 -0
  14. package/es/components/pisellFloorMapLayout/components/EditableItemLayer.js +3 -2
  15. package/es/components/pisellFloorMapLayout/components/ItemLayer.js +7 -4
  16. package/es/components/pisellFloorMapLayout/components/ItemLayer.less +10 -0
  17. package/es/components/pisellFloorMapLayout/components/ViewControls.js +6 -5
  18. package/es/components/pisellFloorMapLayout/components/ViewControls.less +29 -2
  19. package/es/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +1 -0
  20. package/es/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +3 -1
  21. package/es/components/pisellFloorMapLayout/types.d.ts +21 -2
  22. package/es/components/pisellRecordBoard/index.d.ts +1 -1
  23. package/es/components/pisellRecordBoard/shellFrame/Calendar/BookingCalendar.js +280 -230
  24. package/es/components/pisellRecordBoard/shellFrame/Calendar/const/bookingCalendarConstants.js +18 -1
  25. package/es/components/pisellRecordBoard/shellFrame/Calendar/hooks/useBookingCalendarDayOverlayLayout.js +74 -0
  26. package/es/components/pisellRecordBoard/shellFrame/Calendar/modal/BookingCalendarBlockPanel.js +61 -0
  27. package/es/components/pisellRecordBoard/shellFrame/Calendar/modal/BookingCalendarOverflowListLayer.js +26 -0
  28. package/es/components/pisellRecordBoard/shellFrame/Calendar/utils/bookingCalendarDateUtils.js +11 -1
  29. package/es/components/pisellRecordBoard/shellFrame/Calendar/utils/bookingCalendarSelectionUtils.js +17 -0
  30. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarDaySelectionBar.js +12 -8
  31. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarDayView.js +3 -12
  32. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarResourceView.js +612 -0
  33. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/day/useBookingCalendarDayHourRemaining.js +33 -0
  34. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/day/useBookingCalendarDaySelection.js +37 -0
  35. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/resource/useBookingCalendarResourceCellToggle.js +18 -0
  36. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/resource/useBookingCalendarResourceDayHeaderRemaining.js +33 -0
  37. package/es/components/pisellRecordBoard/shellFrame/Calendar/view/useBookingCalendarGoToDayFromCell.js +29 -0
  38. package/es/components/pisellRecordBoard/types.d.ts +38 -6
  39. package/es/components/pisellReservationSchedule/PisellReservationSchedule.js +19 -3
  40. package/es/components/pisellReservationSchedule/PisellReservationSchedule.less +23 -0
  41. package/es/index.d.ts +2 -2
  42. package/es/locales/en-US.js +6 -5
  43. package/es/locales/ja.js +1 -0
  44. package/es/locales/pt.js +1 -0
  45. package/es/locales/zh-CN.js +1 -0
  46. package/es/locales/zh-TW.js +1 -0
  47. package/es/pisell-materials.tw.css +2413 -2
  48. package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.js +25 -10
  49. package/lib/components/pisellFloorMapLayout/appearance/floorMapAppearance.d.ts +4 -0
  50. package/lib/components/pisellFloorMapLayout/appearance/floorMapAppearance.js +22 -0
  51. package/lib/components/pisellFloorMapLayout/components/EditableItemLayer.js +3 -2
  52. package/lib/components/pisellFloorMapLayout/components/ItemLayer.js +7 -4
  53. package/lib/components/pisellFloorMapLayout/components/ItemLayer.less +10 -0
  54. package/lib/components/pisellFloorMapLayout/components/ViewControls.js +6 -5
  55. package/lib/components/pisellFloorMapLayout/components/ViewControls.less +29 -2
  56. package/lib/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +1 -0
  57. package/lib/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +3 -1
  58. package/lib/components/pisellFloorMapLayout/types.d.ts +21 -2
  59. package/lib/components/pisellRecordBoard/index.d.ts +1 -1
  60. package/lib/components/pisellRecordBoard/shellFrame/Calendar/BookingCalendar.js +277 -227
  61. package/lib/components/pisellRecordBoard/shellFrame/Calendar/const/bookingCalendarConstants.js +18 -0
  62. package/lib/components/pisellRecordBoard/shellFrame/Calendar/hooks/useBookingCalendarDayOverlayLayout.js +75 -0
  63. package/lib/components/pisellRecordBoard/shellFrame/Calendar/modal/BookingCalendarBlockPanel.js +63 -0
  64. package/lib/components/pisellRecordBoard/shellFrame/Calendar/modal/BookingCalendarOverflowListLayer.js +28 -0
  65. package/lib/components/pisellRecordBoard/shellFrame/Calendar/utils/bookingCalendarDateUtils.js +11 -1
  66. package/lib/components/pisellRecordBoard/shellFrame/Calendar/utils/bookingCalendarSelectionUtils.js +17 -0
  67. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarDaySelectionBar.js +12 -8
  68. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarDayView.js +3 -12
  69. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/BookingCalendarResourceView.js +614 -0
  70. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/day/useBookingCalendarDayHourRemaining.js +34 -0
  71. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/day/useBookingCalendarDaySelection.js +38 -0
  72. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/resource/useBookingCalendarResourceCellToggle.js +19 -0
  73. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/resource/useBookingCalendarResourceDayHeaderRemaining.js +34 -0
  74. package/lib/components/pisellRecordBoard/shellFrame/Calendar/view/useBookingCalendarGoToDayFromCell.js +30 -0
  75. package/lib/components/pisellRecordBoard/types.d.ts +38 -6
  76. package/lib/components/pisellReservationSchedule/PisellReservationSchedule.js +19 -3
  77. package/lib/components/pisellReservationSchedule/PisellReservationSchedule.less +23 -0
  78. package/lib/index.d.ts +2 -2
  79. package/lib/locales/en-US.js +6 -5
  80. package/lib/locales/ja.js +1 -0
  81. package/lib/locales/pt.js +1 -0
  82. package/lib/locales/zh-CN.js +1 -0
  83. package/lib/locales/zh-TW.js +1 -0
  84. package/lib/pisell-materials.tw.css +2413 -2
  85. package/lowcode/pisell-record-board-calendar-view/meta.ts +8 -0
  86. package/package.json +1 -1
@@ -16,6 +16,7 @@ const require_layoutMeasurements = require("./utils/layoutMeasurements.js");
16
16
  const require_useFloorMapEditState = require("./hooks/useFloorMapEditState.js");
17
17
  const require_useFloorMapTransformMetrics = require("./hooks/useFloorMapTransformMetrics.js");
18
18
  const require_floorMapFallbackRender = require("./utils/floorMapFallbackRender.js");
19
+ const require_floorMapAppearance = require("./appearance/floorMapAppearance.js");
19
20
  const require_useFloorMapPaletteTouchDrag = require("./hooks/useFloorMapPaletteTouchDrag.js");
20
21
  const require_mergeCanvasesForTabs = require("./utils/mergeCanvasesForTabs.js");
21
22
  const require_FloorMapLayoutContext = require("./context/FloorMapLayoutContext.js");
@@ -39,8 +40,8 @@ require("./PisellFloorMapLayout.less");
39
40
  * 负责:上下文与 props 合并、编辑态/阅读态分支、Transform 视口、图元层与工具栏联动。
40
41
  */
41
42
  function PisellFloorMapLayoutInner(props, ref) {
42
- var _engineCtx$engine, _config$sceneElements;
43
- 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, showDataSourceRecordFormBlock, floorMapViewportOverlay, viewportOverlayPlacement = "top-start", viewportOverlayClassName, canvasTabsBarTrailing, viewportDockTrailing, viewportPersist = true, viewportPersistNamespace } = require_mergeFloorMapLayoutContext.mergeFloorMapLayoutPropsFromContext(props, require_FloorMapLayoutContext.useFloorMapLayoutContext());
43
+ var _ref, _currentCanvas$mapLay2, _currentCanvas$mapLay3, _engineCtx$engine, _config$sceneElements;
44
+ 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, canvasTabsBarTrailing, viewportDockToolButtons, viewportDockTrailing, viewportPersist = true, viewportPersistNamespace } = require_mergeFloorMapLayoutContext.mergeFloorMapLayoutPropsFromContext(props, require_FloorMapLayoutContext.useFloorMapLayoutContext());
44
45
  const { token } = antd.theme.useToken();
45
46
  const isFloorMapView = Boolean(floorMapConfigProp);
46
47
  const contentOffsetRef = (0, react.useRef)({
@@ -65,6 +66,18 @@ function PisellFloorMapLayoutInner(props, ref) {
65
66
  showDataSourceRecordFormBlock
66
67
  });
67
68
  /**
69
+ * 当前选中的画布配置:用于提取当前画布级 mapLayer 显式配置。
70
+ */
71
+ const currentCanvas = (0, react.useMemo)(() => {
72
+ var _config$canvases$find;
73
+ if (!isFloorMapView || !config || !currentCanvasId) return null;
74
+ return (_config$canvases$find = config.canvases.find((canvas) => canvas.id === currentCanvasId)) !== null && _config$canvases$find !== void 0 ? _config$canvases$find : null;
75
+ }, [
76
+ isFloorMapView,
77
+ config,
78
+ currentCanvasId
79
+ ]);
80
+ /**
68
81
  * 「取消编辑」组合:先丢弃 draft(同步把 draftConfig replace 回上游 props 的值),
69
82
  * 再调用业务侧 onExitEdit 退出编辑模式。
70
83
  *
@@ -78,16 +91,16 @@ function PisellFloorMapLayoutInner(props, ref) {
78
91
  }, [discardDraft, onExitEdit]);
79
92
  /** 当前画布下的 mapLayer:全局 `mapLayer` 与画布级配置合并,供 MapLayer / 吸附等读取 */
80
93
  const effectiveMapLayer = (0, react.useMemo)(() => {
81
- var _canvas$mapLayer;
82
- if (!isFloorMapView || !config || !currentCanvasId) return mapLayer;
83
- const canvas = config.canvases.find((c) => c.id === currentCanvasId);
84
- return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, mapLayer !== null && mapLayer !== void 0 ? mapLayer : {}), (_canvas$mapLayer = canvas === null || canvas === void 0 ? void 0 : canvas.mapLayer) !== null && _canvas$mapLayer !== void 0 ? _canvas$mapLayer : {});
94
+ var _currentCanvas$mapLay;
95
+ if (!isFloorMapView || !currentCanvas) return mapLayer;
96
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, mapLayer !== null && mapLayer !== void 0 ? mapLayer : {}), (_currentCanvas$mapLay = currentCanvas.mapLayer) !== null && _currentCanvas$mapLay !== void 0 ? _currentCanvas$mapLay : {});
85
97
  }, [
86
98
  isFloorMapView,
87
- config,
88
- currentCanvasId,
99
+ currentCanvas,
89
100
  mapLayer
90
101
  ]);
102
+ const appearanceTokens = (0, react.useMemo)(() => require_floorMapAppearance.getFloorMapAppearanceTokens(appearanceMode), [appearanceMode]);
103
+ const canvasBackgroundColor = (_ref = (_currentCanvas$mapLay2 = currentCanvas === null || currentCanvas === void 0 || (_currentCanvas$mapLay3 = currentCanvas.mapLayer) === null || _currentCanvas$mapLay3 === void 0 ? void 0 : _currentCanvas$mapLay3.backgroundColor) !== null && _currentCanvas$mapLay2 !== void 0 ? _currentCanvas$mapLay2 : mapLayer === null || mapLayer === void 0 ? void 0 : mapLayer.backgroundColor) !== null && _ref !== void 0 ? _ref : appearanceTokens.fallbackCanvasBackgroundColor;
91
104
  /**
92
105
  * 必须与下方 TransformWrapper 的 `key` 完全一致。
93
106
  * 远程/合并配置落地后 boundingPadding 等会变 → Wrapper 重挂载 → 若 autoFit 仍按旧「仅 canvasId」帧认为已 done,首屏会停在初始 transform;切换画布才因 id 变化再次 fit。
@@ -605,7 +618,7 @@ function PisellFloorMapLayoutInner(props, ref) {
605
618
  wrapperStyle: {
606
619
  width: "100%",
607
620
  height: "100%",
608
- backgroundColor: "#F2F4F7",
621
+ backgroundColor: canvasBackgroundColor,
609
622
  overflow: "visible"
610
623
  },
611
624
  contentStyle: {
@@ -615,7 +628,7 @@ function PisellFloorMapLayoutInner(props, ref) {
615
628
  minHeight: contentHeight,
616
629
  position: "relative",
617
630
  overflow: "visible",
618
- backgroundColor: "#F2F4F7"
631
+ backgroundColor: canvasBackgroundColor
619
632
  }
620
633
  }, /* @__PURE__ */ react.default.createElement(require_MapLayer.default, {
621
634
  config: effectiveMapLayer,
@@ -646,6 +659,7 @@ function PisellFloorMapLayoutInner(props, ref) {
646
659
  }) : /* @__PURE__ */ react.default.createElement(require_ItemLayer.default, {
647
660
  items,
648
661
  renderItem: effectiveRenderItem,
662
+ viewportScale: scale,
649
663
  rowKey,
650
664
  cellSize,
651
665
  itemUnit: effectiveItemUnit,
@@ -693,6 +707,7 @@ function PisellFloorMapLayoutInner(props, ref) {
693
707
  viewportLocked,
694
708
  onToggleViewportLock: isFloorMapView ? toggleViewportLocked : void 0,
695
709
  dockChrome: isFloorMapView,
710
+ dockExpandedToolButtons: viewportDockToolButtons,
696
711
  dockExpandedTrailing: viewportDockTrailing,
697
712
  autoCollapseDockMs: 1e4
698
713
  }), isFloorMapView && floorMapViewportOverlay != null ? /* @__PURE__ */ react.default.createElement("div", { className: (0, classnames.default)(`${require_floorMapLayoutConstants.FLOOR_MAP_LAYOUT_CLASS_PREFIX}-viewport-overlay`, { [`${require_floorMapLayoutConstants.FLOOR_MAP_LAYOUT_CLASS_PREFIX}-viewport-overlay--bottom-start`]: viewportOverlayPlacement === "bottom-start" }, viewportOverlayClassName) }, typeof floorMapViewportOverlay === "function" ? floorMapViewportOverlay({
@@ -0,0 +1,4 @@
1
+ //#region src/components/pisellFloorMapLayout/appearance/floorMapAppearance.d.ts
2
+ type FloorMapAppearanceMode = 'light' | 'dark';
3
+ //#endregion
4
+ export { FloorMapAppearanceMode };
@@ -0,0 +1,22 @@
1
+ const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
2
+ //#region src/components/pisellFloorMapLayout/appearance/floorMapAppearance.ts
3
+ const FLOOR_MAP_APPEARANCE_TOKENS = {
4
+ light: {
5
+ mode: "light",
6
+ fallbackCanvasBackgroundColor: "#F2F4F7"
7
+ },
8
+ dark: {
9
+ mode: "dark",
10
+ fallbackCanvasBackgroundColor: "#31353d"
11
+ }
12
+ };
13
+ /**
14
+ * 按外观模式返回 floorMap 画布背景 token。
15
+ * 当前仅承载通用画布背景兜底色,不包含业务壳层颜色;
16
+ * 渲染层应先尊重显式 `mapLayer.backgroundColor`,再回退到这里的 token。
17
+ */
18
+ function getFloorMapAppearanceTokens(mode) {
19
+ return require_objectSpread2._objectSpread2({}, FLOOR_MAP_APPEARANCE_TOKENS[mode]);
20
+ }
21
+ //#endregion
22
+ exports.getFloorMapAppearanceTokens = getFloorMapAppearanceTokens;
@@ -241,7 +241,7 @@ function EditableItemLayer(props) {
241
241
  }, shapeStyle), wrapperStyle), {}, { zIndex: isSelected ? SELECTED_ITEM_STACK_Z + ((_item$zIndex2 = item.zIndex) !== null && _item$zIndex2 !== void 0 ? _item$zIndex2 : 0) : baseZ }),
242
242
  onPointerDown: (e) => handlePointerDown(e, item, index),
243
243
  onClick: (e) => handleItemClick(e, item)
244
- }, /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-editable-item-inner` }, renderItem(item, index)), isSelected && !isSceneLayoutTransformLocked(merged) && /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, [
244
+ }, /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-editable-item-inner` }, renderItem(item, index, { viewportScale: scale })), isSelected && !isSceneLayoutTransformLocked(merged) && /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, [
245
245
  "nw",
246
246
  "n",
247
247
  "ne",
@@ -273,7 +273,8 @@ function EditableItemLayer(props) {
273
273
  handleItemClick,
274
274
  handleResizePointerDown,
275
275
  getMergedItemWrapperStyle,
276
- editQuickBar
276
+ editQuickBar,
277
+ scale
277
278
  ]);
278
279
  return /* @__PURE__ */ react.default.createElement("div", {
279
280
  ref: contentRef,
@@ -34,7 +34,7 @@ function getShapeStyle(shape = "rect") {
34
34
  }
35
35
  }
36
36
  function ItemLayer(props) {
37
- const { items, renderItem, rowKey, cellSize, itemUnit = "cell", itemGap = 0, contentWidth, contentHeight, contentOffsetX = 0, contentOffsetY = 0, enableHover = true, itemHoverOutline = true, onItemClick, onItemHover, onItemLeave, getMergedItemWrapperStyle, onInteractionChange, readModeSelectedItemId, className } = props;
37
+ const { items, renderItem, viewportScale, rowKey, cellSize, itemUnit = "cell", itemGap = 0, contentWidth, contentHeight, contentOffsetX = 0, contentOffsetY = 0, enableHover = true, itemHoverOutline = true, onItemClick, onItemHover, onItemLeave, getMergedItemWrapperStyle, onInteractionChange, readModeSelectedItemId, className } = props;
38
38
  /** 触控/指针在房间卡滚动区内按下时禁用画布 pan,松手恢复 */
39
39
  const notifyRoomScrollSurfaceActive = (0, react.useCallback)(() => {
40
40
  if (!onInteractionChange) return;
@@ -87,10 +87,12 @@ function ItemLayer(props) {
87
87
  const itemNodes = (0, react.useMemo)(() => {
88
88
  const isPixel = itemUnit === "pixel";
89
89
  const g = itemGap;
90
- return [...items].sort((a, b) => {
90
+ const sorted = [...items].sort((a, b) => {
91
91
  var _a$zIndex, _b$zIndex;
92
92
  return ((_a$zIndex = a.zIndex) !== null && _a$zIndex !== void 0 ? _a$zIndex : 0) - ((_b$zIndex = b.zIndex) !== null && _b$zIndex !== void 0 ? _b$zIndex : 0);
93
- }).map((item, index) => {
93
+ });
94
+ const renderOpts = viewportScale != null && Number.isFinite(viewportScale) && viewportScale > 0 ? { viewportScale } : void 0;
95
+ return sorted.map((item, index) => {
94
96
  var _item$zIndex, _item$zIndex2;
95
97
  let left;
96
98
  let top;
@@ -135,11 +137,12 @@ function ItemLayer(props) {
135
137
  onMouseLeave: (e) => onItemLeave === null || onItemLeave === void 0 ? void 0 : onItemLeave(item, index, e),
136
138
  onPointerDownCapture: handleItemPointerDownCapture,
137
139
  onTouchStartCapture: handleItemTouchStartCapture
138
- }, renderItem(item, index));
140
+ }, renderItem(item, index, renderOpts));
139
141
  });
140
142
  }, [
141
143
  items,
142
144
  renderItem,
145
+ viewportScale,
143
146
  rowKey,
144
147
  cellSize,
145
148
  itemUnit,
@@ -27,3 +27,13 @@
27
27
  box-shadow: 0 0 0 1px rgba(22, 119, 255, 0.25);
28
28
  }
29
29
  }
30
+
31
+ /**
32
+ * 房台小卡(tooltip-time)需要允许 tooltip 浮层越出格子边界。
33
+ * 仅在 item 内包含该类卡片时放开 overflow,避免影响其它图元定位/裁剪。
34
+ */
35
+ .pisell-floor-map-layout-item:has(.pisell-res-floor-room-card[data-tooltip-time='on']),
36
+ .pisell-floor-map-layout-item:has(.pisell-res-floor-room-card[data-reserved-halo='on']) {
37
+ overflow: visible;
38
+ z-index: 1;
39
+ }
@@ -16,7 +16,7 @@ const PREFIX = "pisell-floor-map-layout";
16
16
  const I18N_VC = "pisell-floor-map-layout.view-controls";
17
17
  function ViewControls(props) {
18
18
  var _config$horizontalAli;
19
- const { api, config = {}, scale = 1, isFullscreen = false, fitBoundsActive = false, className, mapGridVisible = false, onToggleMapGrid, viewportLocked = false, onToggleViewportLock, dockChrome = false, dockExpandedTrailing, autoCollapseDockMs = 1e4 } = props;
19
+ const { api, config = {}, scale = 1, isFullscreen = false, fitBoundsActive = false, className, mapGridVisible = false, onToggleMapGrid, viewportLocked = false, onToggleViewportLock, dockChrome = false, dockExpandedToolButtons, dockExpandedTrailing, autoCollapseDockMs = 1e4 } = props;
20
20
  const showZoom = config.showZoom !== false;
21
21
  const showReset = config.showReset === true;
22
22
  const showFitBounds = config.showFitBounds === true;
@@ -30,9 +30,10 @@ function ViewControls(props) {
30
30
  const horizontalAlign = (_config$horizontalAli = config.horizontalAlign) !== null && _config$horizontalAli !== void 0 ? _config$horizontalAli : "start";
31
31
  const scalePercent = Math.round(scale * 100);
32
32
  const showTools = showReset || showFitBounds || showFullscreen || showGridToggle || showViewportLock;
33
+ const hasDockToolButtons = dockExpandedToolButtons != null && dockExpandedToolButtons !== false;
33
34
  const hasTrailingSlot = dockExpandedTrailing != null && dockExpandedTrailing !== false;
34
- const dockHasExpandable = dockChrome && (showTools || hasTrailingSlot);
35
- const showBar = showZoom || showTools || dockChrome && hasTrailingSlot;
35
+ const dockHasExpandable = dockChrome && (showTools || hasDockToolButtons || hasTrailingSlot);
36
+ const showBar = showZoom || showTools || dockChrome && (hasDockToolButtons || hasTrailingSlot);
36
37
  /**
37
38
  * Dock:展开条是否拉宽(与 CSS max-width 过渡联动)。
38
39
  * dockChrome 下 slide 内嵌合并 toggle 按钮,slide 始终 mounted;
@@ -159,13 +160,13 @@ function ViewControls(props) {
159
160
  disabled: viewportLocked,
160
161
  "aria-disabled": viewportLocked,
161
162
  "aria-label": _pisell_utils.locales.getText(`${I18N_VC}.zoom-in-aria`)
162
- }, /* @__PURE__ */ react.default.createElement(_ant_design_icons.PlusOutlined, null))) : null, showZoom && (dockExpandedBarHasToolButtons || hasTrailingSlot) ? /* @__PURE__ */ react.default.createElement("div", {
163
+ }, /* @__PURE__ */ react.default.createElement(_ant_design_icons.PlusOutlined, null))) : null, showZoom && (dockExpandedBarHasToolButtons || hasDockToolButtons || hasTrailingSlot) ? /* @__PURE__ */ react.default.createElement("div", {
163
164
  className: `${PREFIX}-view-controls-bar-divider`,
164
165
  "aria-hidden": true
165
166
  }) : null, dockExpandedBarHasToolButtons ? renderToolButtons({
166
167
  omitViewportLock: true,
167
168
  omitFitBounds: true
168
- }) : null, hasTrailingSlot ? /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-view-controls-dock-trailing` }, dockExpandedTrailing) : null);
169
+ }) : null, hasDockToolButtons ? dockExpandedToolButtons : null, hasTrailingSlot ? /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-view-controls-dock-trailing` }, dockExpandedTrailing) : null);
169
170
  if (!showBar) return null;
170
171
  /**
171
172
  * dockChrome 屏右缘常驻按钮:「锁 / 全览」。两者都是单击操作,与展开条解耦。
@@ -233,7 +233,21 @@
233
233
  align-items: center;
234
234
  }
235
235
 
236
- .pisell-floor-map-layout-view-controls-bar--dock > .pisell-floor-map-layout-view-controls-tool-btn {
236
+ .pisell-floor-map-layout-view-controls-bar--dock > .pisell-floor-map-layout-view-controls-tool-btn,
237
+ .pisell-floor-map-layout-view-controls-dock-trailing > .pisell-floor-map-layout-view-controls-tool-btn {
238
+ flex-shrink: 0;
239
+ box-sizing: border-box;
240
+ display: inline-flex;
241
+ align-items: center;
242
+ justify-content: center;
243
+ padding: 0;
244
+ margin: 0;
245
+ border: none;
246
+ background: transparent;
247
+ cursor: pointer;
248
+ color: #101828;
249
+ appearance: none;
250
+ vertical-align: middle;
237
251
  width: @dock-btn-size;
238
252
  min-width: @dock-btn-size;
239
253
  max-width: @dock-btn-size;
@@ -244,6 +258,18 @@
244
258
  font-size: @dock-icon-px;
245
259
  line-height: 0;
246
260
 
261
+ &:hover {
262
+ background: #f2f4f7;
263
+ color: #101828;
264
+ }
265
+
266
+ &:disabled,
267
+ &[aria-disabled='true'] {
268
+ background: transparent;
269
+ color: #d0d5dd;
270
+ cursor: not-allowed;
271
+ }
272
+
247
273
  .anticon,
248
274
  .pisell-lowcode-icon,
249
275
  span[role='img'] {
@@ -267,7 +293,8 @@
267
293
  * 展开条内激活态:与外侧折叠 pill(锁定 / 全览)同一套色,选择器挂在 bar--dock 上提高优先级,
268
294
  * 避免与其它 hover / 尺寸规则叠在一起时展开条观感发灰、与 pill 不一致。
269
295
  */
270
- .pisell-floor-map-layout-view-controls-bar--dock > .pisell-floor-map-layout-view-controls-tool-btn--active {
296
+ .pisell-floor-map-layout-view-controls-bar--dock > .pisell-floor-map-layout-view-controls-tool-btn--active,
297
+ .pisell-floor-map-layout-view-controls-dock-trailing > .pisell-floor-map-layout-view-controls-tool-btn--active {
271
298
  .vc-tool-btn-active-colors();
272
299
  }
273
300
 
@@ -33,6 +33,7 @@ function ViewControlsWithZoom(props) {
33
33
  viewportLocked: props.viewportLocked,
34
34
  onToggleViewportLock: props.onToggleViewportLock,
35
35
  dockChrome: props.dockChrome,
36
+ dockExpandedToolButtons: props.dockExpandedToolButtons,
36
37
  dockExpandedTrailing: props.dockExpandedTrailing,
37
38
  autoCollapseDockMs: props.autoCollapseDockMs
38
39
  });
@@ -4,7 +4,7 @@ const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0
4
4
  * 将 `FloorMapLayoutContext` 与 Layout props 合并:各字段 props ?? ctx,props 显式值优先。
5
5
  */
6
6
  function mergeFloorMapLayoutPropsFromContext(props, ctx) {
7
- var _props$floorMapConfig, _props$dataSources, _props$onSave, _props$onDataSourceRe, _props$dataSourceLabe, _props$dataSourceForm, _props$dataSourceReco, _props$loading, _props$saveError, _props$onElementRende, _props$toolbarShowSav, _props$floorMapFullsc, _props$showDataSource, _props$viewportDockTr;
7
+ var _props$floorMapConfig, _props$dataSources, _props$onSave, _props$onDataSourceRe, _props$dataSourceLabe, _props$dataSourceForm, _props$dataSourceReco, _props$loading, _props$saveError, _props$onElementRende, _props$toolbarShowSav, _props$floorMapFullsc, _props$appearanceMode, _props$showDataSource, _props$viewportDockTo, _props$viewportDockTr;
8
8
  if (ctx == null) return props;
9
9
  return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, props), {}, {
10
10
  floorMapConfig: (_props$floorMapConfig = props.floorMapConfig) !== null && _props$floorMapConfig !== void 0 ? _props$floorMapConfig : ctx.floorMapConfig,
@@ -19,7 +19,9 @@ function mergeFloorMapLayoutPropsFromContext(props, ctx) {
19
19
  onElementRenderError: (_props$onElementRende = props.onElementRenderError) !== null && _props$onElementRende !== void 0 ? _props$onElementRende : ctx.onElementRenderError,
20
20
  toolbarShowSave: (_props$toolbarShowSav = props.toolbarShowSave) !== null && _props$toolbarShowSav !== void 0 ? _props$toolbarShowSav : ctx.toolbarShowSave,
21
21
  floorMapFullscreenMode: (_props$floorMapFullsc = props.floorMapFullscreenMode) !== null && _props$floorMapFullsc !== void 0 ? _props$floorMapFullsc : ctx.floorMapFullscreenMode,
22
+ appearanceMode: (_props$appearanceMode = props.appearanceMode) !== null && _props$appearanceMode !== void 0 ? _props$appearanceMode : ctx.appearanceMode,
22
23
  showDataSourceRecordFormBlock: (_props$showDataSource = props.showDataSourceRecordFormBlock) !== null && _props$showDataSource !== void 0 ? _props$showDataSource : ctx.showDataSourceRecordFormBlock,
24
+ viewportDockToolButtons: (_props$viewportDockTo = props.viewportDockToolButtons) !== null && _props$viewportDockTo !== void 0 ? _props$viewportDockTo : ctx.viewportDockToolButtons,
23
25
  viewportDockTrailing: (_props$viewportDockTr = props.viewportDockTrailing) !== null && _props$viewportDockTr !== void 0 ? _props$viewportDockTr : ctx.viewportDockTrailing
24
26
  });
25
27
  }
@@ -1,3 +1,4 @@
1
+ import { FloorMapAppearanceMode } from "./appearance/floorMapAppearance.js";
1
2
  import { CSSProperties, MouseEvent, ReactNode } from "react";
2
3
 
3
4
  //#region src/components/pisellFloorMapLayout/types.d.ts
@@ -51,7 +52,10 @@ interface FloorMapItemBase {
51
52
  interface FloorMapLayerConfig {
52
53
  /** 背景类型 */
53
54
  backgroundType?: FloorMapBackgroundType;
54
- /** 纯色背景时的颜色(backgroundType 为 color 时有效) */
55
+ /**
56
+ * 纯色背景时的显式颜色(backgroundType 为 color 时有效)。
57
+ * 一旦配置,应优先于 `appearanceMode` 提供的画布背景兜底色。
58
+ */
55
59
  backgroundColor?: string;
56
60
  /** 图片背景 URL(backgroundType 为 image 时有效) */
57
61
  backgroundImage?: string;
@@ -318,6 +322,11 @@ interface FloorMapViewConfig {
318
322
  /** 阅读态 renderItem 可选第三参数 */
319
323
  interface FloorMapRenderOptions {
320
324
  textSlotValues?: Record<string, string>;
325
+ /**
326
+ * 平面图画布当前缩放(如 TransformWrapper 的 scale)。
327
+ * 用于房间内卡片等需按「视觉短边」降级密度时与布局像素相乘。
328
+ */
329
+ viewportScale?: number;
321
330
  }
322
331
  /** 数据源记录表单列配置(用于编辑面板中的「数据源记录」区块) */
323
332
  interface DataSourceFormColumn {
@@ -376,7 +385,7 @@ type FloorMapFullscreenMode = 'toggle' | 'locked' | 'disabled';
376
385
  * 平面图 Layout 注入上下文:数据、保存、侧栏表单与状态等(不包含 renderItem/mapLayer 等展示向 props)。
377
386
  * 由 `FloorMapLayoutProvider` / RecordBoard `floorMapLayoutContext` 提供,与 `PisellFloorMapLayout` props 按 `??` 合并,props 优先。
378
387
  */
379
- type FloorMapLayoutContextValue = Partial<Pick<PisellFloorMapLayoutProps<FloorMapItemBase>, 'floorMapConfig' | 'dataSources' | 'onSave' | 'onDataSourceRecordSave' | 'dataSourceLabels' | 'dataSourceFormColumns' | 'dataSourceRecordForm' | 'loading' | 'saveError' | 'onElementRenderError' | 'toolbarShowSave' | 'floorMapFullscreenMode' | 'showDataSourceRecordFormBlock' | 'viewportDockTrailing'>>;
388
+ type FloorMapLayoutContextValue = Partial<Pick<PisellFloorMapLayoutProps<FloorMapItemBase>, 'floorMapConfig' | 'dataSources' | 'onSave' | 'onDataSourceRecordSave' | 'dataSourceLabels' | 'dataSourceFormColumns' | 'dataSourceRecordForm' | 'loading' | 'saveError' | 'onElementRenderError' | 'toolbarShowSave' | 'floorMapFullscreenMode' | 'appearanceMode' | 'showDataSourceRecordFormBlock' | 'viewportDockToolButtons' | 'viewportDockTrailing'>>;
380
389
  /**
381
390
  * PisellFloorMapLayout 组件 Props
382
391
  * @template T - 资源项类型,需继承 FloorMapItemBase 或兼容 id/x/y
@@ -486,6 +495,12 @@ interface PisellFloorMapLayoutProps<T extends FloorMapItemBase = FloorMapItemBas
486
495
  onItemLeave?: (item: T, index: number, event: MouseEvent<HTMLElement>) => void;
487
496
  /** 编辑态全屏按钮与顶栏形态,见 {@link FloorMapFullscreenMode} */
488
497
  floorMapFullscreenMode?: FloorMapFullscreenMode;
498
+ /**
499
+ * FloorMap 外观模式;当前仅提供画布背景兜底色。
500
+ * 若当前画布或根级 `mapLayer.backgroundColor` 显式传入颜色,应优先使用显式背景色。
501
+ * @default 'light'
502
+ */
503
+ appearanceMode?: FloorMapAppearanceMode;
489
504
  /**
490
505
  * 模式:read 仅展示,edit 可编辑;与 floorMapConfig 同时使用时生效
491
506
  */
@@ -540,6 +555,10 @@ interface PisellFloorMapLayoutProps<T extends FloorMapItemBase = FloorMapItemBas
540
555
  * 传入且阅读态仅单画布时仍会显示顶栏以便放置该插槽;全屏入口在左下 Dock(`viewportDockTrailing` 亦放 Dock,不占顶栏)。
541
556
  */
542
557
  canvasTabsBarTrailing?: ReactNode;
558
+ /**
559
+ * 视口左下角 Dock 展开区内、与缩放/网格等工具按钮平级的业务按钮插槽。
560
+ */
561
+ viewportDockToolButtons?: ReactNode;
543
562
  /**
544
563
  * 视口左下角 Dock 展开区业务插槽(与缩放/全屏同条),不占用顶栏 Tab 行;平面图模式推荐放「编辑画布」等。
545
564
  */
@@ -1,4 +1,4 @@
1
- import { DEFAULT_RESOURCE_WALL_LAYOUT_PERSIST, RecordBoardBlockedTimeMergedRange, RecordBoardBlockedTimePanelPayload, RecordBoardBodyView, RecordBoardBookingMoveDraft, RecordBoardCalendarBlockedTimePayload, RecordBoardCalendarBookingLike, RecordBoardCalendarBookingRenderArgs, RecordBoardCalendarDayOverlayBooking, RecordBoardCalendarProps, RecordBoardCalendarResource, RecordBoardCalendarResourceRenderArgs, RecordBoardCalendarSelectedFreeSlot, RecordBoardCalendarTimelineHeaderGroup, RecordBoardCalendarTimelineHeaderRenderContext, RecordBoardChildComponentProps, RecordBoardColumnFilterConfig, RecordBoardColumnType, RecordBoardContextValue, RecordBoardFieldType, RecordBoardFloorMapProps, RecordBoardGetOptions, RecordBoardGridProps, RecordBoardLayoutType, RecordBoardOptionItem, RecordBoardProps, RecordBoardResourceWallCardModel, RecordBoardResourceWallLayoutPersist, RecordBoardResourceWallProps, RecordBoardToolBarProps } from "./types.js";
1
+ import { DEFAULT_RESOURCE_WALL_LAYOUT_PERSIST, RecordBoardBlockedTimeMergedRange, RecordBoardBlockedTimePanelPayload, RecordBoardBodyView, RecordBoardBookingMoveDraft, RecordBoardCalendarBlockedTimePayload, RecordBoardCalendarBookingLike, RecordBoardCalendarBookingRenderArgs, RecordBoardCalendarDayOverlayBooking, RecordBoardCalendarProps, RecordBoardCalendarResource, RecordBoardCalendarResourceRenderArgs, RecordBoardCalendarSelectedFreeSlot, RecordBoardCalendarTimelineHeaderGroup, RecordBoardCalendarTimelineHeaderRenderContext, RecordBoardChildComponentProps, RecordBoardColumnFilterConfig, RecordBoardColumnType, RecordBoardContextValue, RecordBoardCreateBookingDayGroup, RecordBoardCreateBookingFromSelectionPayload, RecordBoardFieldType, RecordBoardFloorMapProps, RecordBoardGetOptions, RecordBoardGridProps, RecordBoardLayoutType, RecordBoardOptionItem, RecordBoardProps, RecordBoardResourceWallCardModel, RecordBoardResourceWallLayoutPersist, RecordBoardResourceWallProps, RecordBoardToolBarProps } from "./types.js";
2
2
  import { RecordBoardGridView } from "./layouts/GridLayout/Grid.js";
3
3
  import { GridLayout } from "./layouts/GridLayout/index.js";
4
4
  import { RecordBoardCardList } from "./layouts/CardLayout/CardList.js";