@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
@@ -15,6 +15,7 @@ import { gapToPx } from "./utils/layoutMeasurements.js";
15
15
  import { useFloorMapEditState } from "./hooks/useFloorMapEditState.js";
16
16
  import { useFloorMapTransformMetrics } from "./hooks/useFloorMapTransformMetrics.js";
17
17
  import { renderFloorMapFallbackPlaceholder, renderFloorMapRenderError } from "./utils/floorMapFallbackRender.js";
18
+ import { getFloorMapAppearanceTokens } from "./appearance/floorMapAppearance.js";
18
19
  import { useFloorMapPaletteTouchDrag } from "./hooks/useFloorMapPaletteTouchDrag.js";
19
20
  import { mergeCanvasesForTabs } from "./utils/mergeCanvasesForTabs.js";
20
21
  import { useFloorMapLayoutContext } from "./context/FloorMapLayoutContext.js";
@@ -36,8 +37,8 @@ import "./PisellFloorMapLayout.less";
36
37
  * 负责:上下文与 props 合并、编辑态/阅读态分支、Transform 视口、图元层与工具栏联动。
37
38
  */
38
39
  function PisellFloorMapLayoutInner(props, ref) {
39
- var _engineCtx$engine, _config$sceneElements;
40
- 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 } = mergeFloorMapLayoutPropsFromContext(props, useFloorMapLayoutContext());
40
+ var _ref, _currentCanvas$mapLay2, _currentCanvas$mapLay3, _engineCtx$engine, _config$sceneElements;
41
+ 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 } = mergeFloorMapLayoutPropsFromContext(props, useFloorMapLayoutContext());
41
42
  const { token } = theme.useToken();
42
43
  const isFloorMapView = Boolean(floorMapConfigProp);
43
44
  const contentOffsetRef = useRef({
@@ -62,6 +63,18 @@ function PisellFloorMapLayoutInner(props, ref) {
62
63
  showDataSourceRecordFormBlock
63
64
  });
64
65
  /**
66
+ * 当前选中的画布配置:用于提取当前画布级 mapLayer 显式配置。
67
+ */
68
+ const currentCanvas = useMemo(() => {
69
+ var _config$canvases$find;
70
+ if (!isFloorMapView || !config || !currentCanvasId) return null;
71
+ return (_config$canvases$find = config.canvases.find((canvas) => canvas.id === currentCanvasId)) !== null && _config$canvases$find !== void 0 ? _config$canvases$find : null;
72
+ }, [
73
+ isFloorMapView,
74
+ config,
75
+ currentCanvasId
76
+ ]);
77
+ /**
65
78
  * 「取消编辑」组合:先丢弃 draft(同步把 draftConfig replace 回上游 props 的值),
66
79
  * 再调用业务侧 onExitEdit 退出编辑模式。
67
80
  *
@@ -75,16 +88,16 @@ function PisellFloorMapLayoutInner(props, ref) {
75
88
  }, [discardDraft, onExitEdit]);
76
89
  /** 当前画布下的 mapLayer:全局 `mapLayer` 与画布级配置合并,供 MapLayer / 吸附等读取 */
77
90
  const effectiveMapLayer = useMemo(() => {
78
- var _canvas$mapLayer;
79
- if (!isFloorMapView || !config || !currentCanvasId) return mapLayer;
80
- const canvas = config.canvases.find((c) => c.id === currentCanvasId);
81
- return _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 : {});
91
+ var _currentCanvas$mapLay;
92
+ if (!isFloorMapView || !currentCanvas) return mapLayer;
93
+ return _objectSpread2(_objectSpread2({}, mapLayer !== null && mapLayer !== void 0 ? mapLayer : {}), (_currentCanvas$mapLay = currentCanvas.mapLayer) !== null && _currentCanvas$mapLay !== void 0 ? _currentCanvas$mapLay : {});
82
94
  }, [
83
95
  isFloorMapView,
84
- config,
85
- currentCanvasId,
96
+ currentCanvas,
86
97
  mapLayer
87
98
  ]);
99
+ const appearanceTokens = useMemo(() => getFloorMapAppearanceTokens(appearanceMode), [appearanceMode]);
100
+ 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;
88
101
  /**
89
102
  * 必须与下方 TransformWrapper 的 `key` 完全一致。
90
103
  * 远程/合并配置落地后 boundingPadding 等会变 → Wrapper 重挂载 → 若 autoFit 仍按旧「仅 canvasId」帧认为已 done,首屏会停在初始 transform;切换画布才因 id 变化再次 fit。
@@ -602,7 +615,7 @@ function PisellFloorMapLayoutInner(props, ref) {
602
615
  wrapperStyle: {
603
616
  width: "100%",
604
617
  height: "100%",
605
- backgroundColor: "#F2F4F7",
618
+ backgroundColor: canvasBackgroundColor,
606
619
  overflow: "visible"
607
620
  },
608
621
  contentStyle: {
@@ -612,7 +625,7 @@ function PisellFloorMapLayoutInner(props, ref) {
612
625
  minHeight: contentHeight,
613
626
  position: "relative",
614
627
  overflow: "visible",
615
- backgroundColor: "#F2F4F7"
628
+ backgroundColor: canvasBackgroundColor
616
629
  }
617
630
  }, /* @__PURE__ */ React.createElement(MapLayer, {
618
631
  config: effectiveMapLayer,
@@ -643,6 +656,7 @@ function PisellFloorMapLayoutInner(props, ref) {
643
656
  }) : /* @__PURE__ */ React.createElement(ItemLayer, {
644
657
  items,
645
658
  renderItem: effectiveRenderItem,
659
+ viewportScale: scale,
646
660
  rowKey,
647
661
  cellSize,
648
662
  itemUnit: effectiveItemUnit,
@@ -690,6 +704,7 @@ function PisellFloorMapLayoutInner(props, ref) {
690
704
  viewportLocked,
691
705
  onToggleViewportLock: isFloorMapView ? toggleViewportLocked : void 0,
692
706
  dockChrome: isFloorMapView,
707
+ dockExpandedToolButtons: viewportDockToolButtons,
693
708
  dockExpandedTrailing: viewportDockTrailing,
694
709
  autoCollapseDockMs: 1e4
695
710
  }), isFloorMapView && floorMapViewportOverlay != null ? /* @__PURE__ */ React.createElement("div", { className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-viewport-overlay`, { [`${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
+ import { _objectSpread2 } from "../../../_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 _objectSpread2({}, FLOOR_MAP_APPEARANCE_TOKENS[mode]);
20
+ }
21
+ //#endregion
22
+ export { getFloorMapAppearanceTokens };
@@ -238,7 +238,7 @@ function EditableItemLayer(props) {
238
238
  }, shapeStyle), wrapperStyle), {}, { zIndex: isSelected ? SELECTED_ITEM_STACK_Z + ((_item$zIndex2 = item.zIndex) !== null && _item$zIndex2 !== void 0 ? _item$zIndex2 : 0) : baseZ }),
239
239
  onPointerDown: (e) => handlePointerDown(e, item, index),
240
240
  onClick: (e) => handleItemClick(e, item)
241
- }, /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}-editable-item-inner` }, renderItem(item, index)), isSelected && !isSceneLayoutTransformLocked(merged) && /* @__PURE__ */ React.createElement(React.Fragment, null, [
241
+ }, /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}-editable-item-inner` }, renderItem(item, index, { viewportScale: scale })), isSelected && !isSceneLayoutTransformLocked(merged) && /* @__PURE__ */ React.createElement(React.Fragment, null, [
242
242
  "nw",
243
243
  "n",
244
244
  "ne",
@@ -270,7 +270,8 @@ function EditableItemLayer(props) {
270
270
  handleItemClick,
271
271
  handleResizePointerDown,
272
272
  getMergedItemWrapperStyle,
273
- editQuickBar
273
+ editQuickBar,
274
+ scale
274
275
  ]);
275
276
  return /* @__PURE__ */ React.createElement("div", {
276
277
  ref: contentRef,
@@ -31,7 +31,7 @@ function getShapeStyle(shape = "rect") {
31
31
  }
32
32
  }
33
33
  function ItemLayer(props) {
34
- 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;
34
+ 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;
35
35
  /** 触控/指针在房间卡滚动区内按下时禁用画布 pan,松手恢复 */
36
36
  const notifyRoomScrollSurfaceActive = useCallback(() => {
37
37
  if (!onInteractionChange) return;
@@ -84,10 +84,12 @@ function ItemLayer(props) {
84
84
  const itemNodes = useMemo(() => {
85
85
  const isPixel = itemUnit === "pixel";
86
86
  const g = itemGap;
87
- return [...items].sort((a, b) => {
87
+ const sorted = [...items].sort((a, b) => {
88
88
  var _a$zIndex, _b$zIndex;
89
89
  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);
90
- }).map((item, index) => {
90
+ });
91
+ const renderOpts = viewportScale != null && Number.isFinite(viewportScale) && viewportScale > 0 ? { viewportScale } : void 0;
92
+ return sorted.map((item, index) => {
91
93
  var _item$zIndex, _item$zIndex2;
92
94
  let left;
93
95
  let top;
@@ -132,11 +134,12 @@ function ItemLayer(props) {
132
134
  onMouseLeave: (e) => onItemLeave === null || onItemLeave === void 0 ? void 0 : onItemLeave(item, index, e),
133
135
  onPointerDownCapture: handleItemPointerDownCapture,
134
136
  onTouchStartCapture: handleItemTouchStartCapture
135
- }, renderItem(item, index));
137
+ }, renderItem(item, index, renderOpts));
136
138
  });
137
139
  }, [
138
140
  items,
139
141
  renderItem,
142
+ viewportScale,
140
143
  rowKey,
141
144
  cellSize,
142
145
  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
+ }
@@ -13,7 +13,7 @@ const PREFIX = "pisell-floor-map-layout";
13
13
  const I18N_VC = "pisell-floor-map-layout.view-controls";
14
14
  function ViewControls(props) {
15
15
  var _config$horizontalAli;
16
- const { api, config = {}, scale = 1, isFullscreen = false, fitBoundsActive = false, className, mapGridVisible = false, onToggleMapGrid, viewportLocked = false, onToggleViewportLock, dockChrome = false, dockExpandedTrailing, autoCollapseDockMs = 1e4 } = props;
16
+ const { api, config = {}, scale = 1, isFullscreen = false, fitBoundsActive = false, className, mapGridVisible = false, onToggleMapGrid, viewportLocked = false, onToggleViewportLock, dockChrome = false, dockExpandedToolButtons, dockExpandedTrailing, autoCollapseDockMs = 1e4 } = props;
17
17
  const showZoom = config.showZoom !== false;
18
18
  const showReset = config.showReset === true;
19
19
  const showFitBounds = config.showFitBounds === true;
@@ -27,9 +27,10 @@ function ViewControls(props) {
27
27
  const horizontalAlign = (_config$horizontalAli = config.horizontalAlign) !== null && _config$horizontalAli !== void 0 ? _config$horizontalAli : "start";
28
28
  const scalePercent = Math.round(scale * 100);
29
29
  const showTools = showReset || showFitBounds || showFullscreen || showGridToggle || showViewportLock;
30
+ const hasDockToolButtons = dockExpandedToolButtons != null && dockExpandedToolButtons !== false;
30
31
  const hasTrailingSlot = dockExpandedTrailing != null && dockExpandedTrailing !== false;
31
- const dockHasExpandable = dockChrome && (showTools || hasTrailingSlot);
32
- const showBar = showZoom || showTools || dockChrome && hasTrailingSlot;
32
+ const dockHasExpandable = dockChrome && (showTools || hasDockToolButtons || hasTrailingSlot);
33
+ const showBar = showZoom || showTools || dockChrome && (hasDockToolButtons || hasTrailingSlot);
33
34
  /**
34
35
  * Dock:展开条是否拉宽(与 CSS max-width 过渡联动)。
35
36
  * dockChrome 下 slide 内嵌合并 toggle 按钮,slide 始终 mounted;
@@ -156,13 +157,13 @@ function ViewControls(props) {
156
157
  disabled: viewportLocked,
157
158
  "aria-disabled": viewportLocked,
158
159
  "aria-label": locales.getText(`${I18N_VC}.zoom-in-aria`)
159
- }, /* @__PURE__ */ React.createElement(PlusOutlined, null))) : null, showZoom && (dockExpandedBarHasToolButtons || hasTrailingSlot) ? /* @__PURE__ */ React.createElement("div", {
160
+ }, /* @__PURE__ */ React.createElement(PlusOutlined, null))) : null, showZoom && (dockExpandedBarHasToolButtons || hasDockToolButtons || hasTrailingSlot) ? /* @__PURE__ */ React.createElement("div", {
160
161
  className: `${PREFIX}-view-controls-bar-divider`,
161
162
  "aria-hidden": true
162
163
  }) : null, dockExpandedBarHasToolButtons ? renderToolButtons({
163
164
  omitViewportLock: true,
164
165
  omitFitBounds: true
165
- }) : null, hasTrailingSlot ? /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}-view-controls-dock-trailing` }, dockExpandedTrailing) : null);
166
+ }) : null, hasDockToolButtons ? dockExpandedToolButtons : null, hasTrailingSlot ? /* @__PURE__ */ React.createElement("div", { className: `${PREFIX}-view-controls-dock-trailing` }, dockExpandedTrailing) : null);
166
167
  if (!showBar) return null;
167
168
  /**
168
169
  * 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
 
@@ -31,6 +31,7 @@ function ViewControlsWithZoom(props) {
31
31
  viewportLocked: props.viewportLocked,
32
32
  onToggleViewportLock: props.onToggleViewportLock,
33
33
  dockChrome: props.dockChrome,
34
+ dockExpandedToolButtons: props.dockExpandedToolButtons,
34
35
  dockExpandedTrailing: props.dockExpandedTrailing,
35
36
  autoCollapseDockMs: props.autoCollapseDockMs
36
37
  });
@@ -4,7 +4,7 @@ import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.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 _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";