@pisell/materials 1.0.1062 → 1.0.1064

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 (111) 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 +7 -7
  6. package/build/lowcode/preview.js +9 -9
  7. package/build/lowcode/render/default/view.css +1 -1
  8. package/build/lowcode/render/default/view.js +22 -22
  9. package/build/lowcode/view.css +1 -1
  10. package/build/lowcode/view.js +26 -26
  11. package/es/components/pisellFloorMapLayout/PisellFloorMapLayout.js +43 -31
  12. package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +60 -16
  13. package/es/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +8 -0
  14. package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.js +22 -12
  15. package/es/components/pisellFloorMapLayout/components/FloorMapToolbar.less +7 -5
  16. package/es/components/pisellFloorMapLayout/components/MapLayer.js +5 -2
  17. package/es/components/pisellFloorMapLayout/components/ViewControls.d.ts +4 -0
  18. package/es/components/pisellFloorMapLayout/components/ViewControls.js +29 -10
  19. package/es/components/pisellFloorMapLayout/components/ViewControls.less +36 -12
  20. package/es/components/pisellFloorMapLayout/components/ViewControlsWithZoom.d.ts +2 -0
  21. package/es/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +3 -1
  22. package/es/components/pisellFloorMapLayout/context/mergeFloorMapLayoutContext.js +2 -2
  23. package/es/components/pisellFloorMapLayout/hooks/useFloorMapEditState.d.ts +1 -0
  24. package/es/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +166 -43
  25. package/es/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.d.ts +1 -1
  26. package/es/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +90 -13
  27. package/es/components/pisellFloorMapLayout/index.d.ts +2 -0
  28. package/es/components/pisellFloorMapLayout/index.js +2 -0
  29. package/es/components/pisellFloorMapLayout/locales.d.ts +6 -0
  30. package/es/components/pisellFloorMapLayout/locales.js +9 -3
  31. package/es/components/pisellFloorMapLayout/types.d.ts +9 -2
  32. package/es/components/pisellFloorMapLayout/utils/floorMapDropUtils.d.ts +1 -0
  33. package/es/components/pisellFloorMapLayout/utils/floorMapDropUtils.js +10 -1
  34. package/es/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.d.ts +11 -0
  35. package/es/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +86 -0
  36. package/es/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +3 -2
  37. package/es/components/pisellRecordBoard/PisellRecordBoard.js +6 -3
  38. package/es/components/pisellRecordBoard/shellFrame/ToolBar/index.d.ts +1 -0
  39. package/es/components/pisellRecordBoard/shellFrame/ToolBar/index.js +21 -10
  40. package/es/components/pisellRecordBoard/shellFrame/ToolBar/recordBoardToolbar.less +23 -0
  41. package/es/components/pisellRecordBoard/shellFrame/index.d.ts +2 -0
  42. package/es/components/pisellRecordBoard/shellFrame/index.js +9 -3
  43. package/es/components/pisellRecordBoard/shellFrame/shellFrameFloorMap.less +25 -0
  44. package/es/components/pisellRecordBoard/types.d.ts +6 -0
  45. package/es/components/pisellReservationScheduleBand/PisellReservationScheduleBand.js +4 -1
  46. package/es/components/pisellReservationScheduleBand/PisellReservationScheduleBand.less +18 -1
  47. package/es/components/pisellReservationScheduleBand/types.d.ts +4 -0
  48. package/es/components/pisellTimeNavigator/PisellTimeNavigator.js +187 -29
  49. package/es/components/pisellTimeNavigator/PisellTimeNavigator.less +11 -0
  50. package/es/components/pisellTimeNavigator/components/CursorLayer.d.ts +7 -1
  51. package/es/components/pisellTimeNavigator/components/CursorLayer.js +27 -7
  52. package/es/components/pisellTimeNavigator/components/GestureLayer.d.ts +3 -1
  53. package/es/components/pisellTimeNavigator/components/GestureLayer.js +14 -5
  54. package/es/components/pisellTimeNavigator/components/ScaleLayer.d.ts +6 -1
  55. package/es/components/pisellTimeNavigator/components/ScaleLayer.js +28 -6
  56. package/es/components/pisellTimeNavigator/types.d.ts +11 -0
  57. package/es/index.d.ts +1 -1
  58. package/es/index.js +1 -1
  59. package/lib/components/pisellFloorMapLayout/PisellFloorMapLayout.js +39 -36
  60. package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.js +56 -12
  61. package/lib/components/pisellFloorMapLayout/components/FloorMapEditPanel.less +8 -0
  62. package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.js +19 -10
  63. package/lib/components/pisellFloorMapLayout/components/FloorMapToolbar.less +7 -5
  64. package/lib/components/pisellFloorMapLayout/components/MapLayer.js +3 -1
  65. package/lib/components/pisellFloorMapLayout/components/ViewControls.d.ts +4 -0
  66. package/lib/components/pisellFloorMapLayout/components/ViewControls.js +28 -6
  67. package/lib/components/pisellFloorMapLayout/components/ViewControls.less +36 -12
  68. package/lib/components/pisellFloorMapLayout/components/ViewControlsWithZoom.d.ts +2 -0
  69. package/lib/components/pisellFloorMapLayout/components/ViewControlsWithZoom.js +3 -1
  70. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEditState.d.ts +1 -0
  71. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapEditState.js +143 -29
  72. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.d.ts +1 -1
  73. package/lib/components/pisellFloorMapLayout/hooks/useFloorMapTransformMetrics.js +86 -13
  74. package/lib/components/pisellFloorMapLayout/index.d.ts +2 -0
  75. package/lib/components/pisellFloorMapLayout/index.js +6 -0
  76. package/lib/components/pisellFloorMapLayout/locales.d.ts +6 -0
  77. package/lib/components/pisellFloorMapLayout/locales.js +9 -3
  78. package/lib/components/pisellFloorMapLayout/types.d.ts +9 -2
  79. package/lib/components/pisellFloorMapLayout/utils/floorMapDropUtils.d.ts +1 -0
  80. package/lib/components/pisellFloorMapLayout/utils/floorMapDropUtils.js +7 -1
  81. package/lib/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.d.ts +11 -0
  82. package/lib/components/pisellFloorMapLayout/utils/floorMapElementKindUtils.js +69 -0
  83. package/lib/components/pisellFloorMapLayout/utils/floorMapFallbackRender.js +2 -1
  84. package/lib/components/pisellRecordBoard/PisellRecordBoard.js +5 -1
  85. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/index.d.ts +1 -0
  86. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/index.js +13 -5
  87. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/recordBoardToolbar.less +23 -0
  88. package/lib/components/pisellRecordBoard/shellFrame/index.d.ts +2 -0
  89. package/lib/components/pisellRecordBoard/shellFrame/index.js +11 -4
  90. package/lib/components/pisellRecordBoard/shellFrame/shellFrameFloorMap.less +25 -0
  91. package/lib/components/pisellRecordBoard/types.d.ts +6 -0
  92. package/lib/components/pisellReservationScheduleBand/PisellReservationScheduleBand.js +2 -1
  93. package/lib/components/pisellReservationScheduleBand/PisellReservationScheduleBand.less +18 -1
  94. package/lib/components/pisellReservationScheduleBand/types.d.ts +4 -0
  95. package/lib/components/pisellTimeNavigator/PisellTimeNavigator.js +176 -8
  96. package/lib/components/pisellTimeNavigator/PisellTimeNavigator.less +11 -0
  97. package/lib/components/pisellTimeNavigator/components/CursorLayer.d.ts +7 -1
  98. package/lib/components/pisellTimeNavigator/components/CursorLayer.js +24 -3
  99. package/lib/components/pisellTimeNavigator/components/GestureLayer.d.ts +3 -1
  100. package/lib/components/pisellTimeNavigator/components/GestureLayer.js +16 -5
  101. package/lib/components/pisellTimeNavigator/components/ScaleLayer.d.ts +6 -1
  102. package/lib/components/pisellTimeNavigator/components/ScaleLayer.js +24 -3
  103. package/lib/components/pisellTimeNavigator/types.d.ts +11 -0
  104. package/lib/index.d.ts +1 -1
  105. package/lib/index.js +8 -0
  106. package/lowcode/floor-map-image-element/meta.ts +113 -0
  107. package/lowcode/floor-map-layout-provider/meta.ts +1 -1
  108. package/lowcode/pisell-floor-map-layout/meta.ts +37 -1
  109. package/lowcode/render-figma-style-round-table-card/meta.ts +1 -1
  110. package/lowcode/render-figma-style-table-card/meta.ts +1 -1
  111. package/package.json +3 -3
@@ -135,8 +135,27 @@ function PisellFloorMapLayoutInner(props, ref) {
135
135
  placeSceneElementFromPaletteDrop,
136
136
  editPanelParams,
137
137
  placeOverlayClass,
138
- isLayoutDirty
138
+ isLayoutDirty,
139
+ toggleDraftCanvasShowGrid
139
140
  } = edit;
141
+ const effectiveMapLayer = (0, import_react.useMemo)(() => {
142
+ if (!isFloorMapView || !config || !currentCanvasId) {
143
+ return mapLayer;
144
+ }
145
+ const canvas = config.canvases.find((c) => c.id === currentCanvasId);
146
+ return { ...mapLayer ?? {}, ...(canvas == null ? void 0 : canvas.mapLayer) ?? {} };
147
+ }, [isFloorMapView, config, currentCanvasId, mapLayer]);
148
+ const transformWrapperKey = (0, import_react.useMemo)(() => {
149
+ if (!isFloorMapView) return "fmap-layout";
150
+ const bp = (effectiveMapLayer == null ? void 0 : effectiveMapLayer.boundingPadding) ?? "d";
151
+ const z = zoom.defaultScale ?? 1;
152
+ return `fmap-${currentCanvasId ?? "na"}-bp${bp}-z${z}`;
153
+ }, [
154
+ isFloorMapView,
155
+ currentCanvasId,
156
+ effectiveMapLayer == null ? void 0 : effectiveMapLayer.boundingPadding,
157
+ zoom.defaultScale
158
+ ]);
140
159
  const canvasesForTabs = (0, import_react.useMemo)(
141
160
  () => config ? (0, import_mergeCanvasesForTabs.mergeCanvasesForTabs)(config) : [],
142
161
  [config]
@@ -156,7 +175,10 @@ function PisellFloorMapLayoutInner(props, ref) {
156
175
  return import_utils.locales.getText("pisell-floor-map-layout.loading");
157
176
  }, [engineLocale]);
158
177
  const cellSize = cellSizeProp ?? import_layoutMeasurements.DEFAULT_CELL_SIZE;
159
- const itemGap = (0, import_react.useMemo)(() => (0, import_layoutMeasurements.gapToPx)(mapLayer == null ? void 0 : mapLayer.gap), [mapLayer == null ? void 0 : mapLayer.gap]);
178
+ const itemGap = (0, import_react.useMemo)(
179
+ () => (0, import_layoutMeasurements.gapToPx)(effectiveMapLayer == null ? void 0 : effectiveMapLayer.gap),
180
+ [effectiveMapLayer == null ? void 0 : effectiveMapLayer.gap]
181
+ );
160
182
  const effectiveItemUnit = isFloorMapView ? "pixel" : itemUnit;
161
183
  const metrics = (0, import_useFloorMapTransformMetrics.useFloorMapTransformMetrics)({
162
184
  items,
@@ -168,8 +190,8 @@ function PisellFloorMapLayoutInner(props, ref) {
168
190
  zoom,
169
191
  transformRef,
170
192
  contentOffsetRef,
171
- boundingPadding: mapLayer == null ? void 0 : mapLayer.boundingPadding,
172
- frameResetKey: isFloorMapView ? currentCanvasId ?? "" : void 0
193
+ boundingPadding: effectiveMapLayer == null ? void 0 : effectiveMapLayer.boundingPadding,
194
+ frameResetKey: isFloorMapView ? transformWrapperKey : void 0
173
195
  });
174
196
  const {
175
197
  containerRef,
@@ -198,28 +220,10 @@ function PisellFloorMapLayoutInner(props, ref) {
198
220
  if (!isFloorMapView || mode !== "edit") return controls;
199
221
  return {
200
222
  ...controls,
201
- showFullscreen: false,
202
- showFitBounds: false
223
+ showFullscreen: false
203
224
  };
204
225
  }, [isFloorMapView, mode, controls]);
205
- const topBarExtraActions = (0, import_react.useMemo)(() => {
206
- if (!isFloorMapView || mode !== "edit") return null;
207
- if (controls.showFitBounds !== true) return null;
208
- return /* @__PURE__ */ import_react.default.createElement(
209
- "button",
210
- {
211
- type: "button",
212
- className: (0, import_classnames.default)(
213
- `${PREFIX}-edit-top-bar-btn`,
214
- `${PREFIX}-edit-top-bar-btn-ghost`
215
- ),
216
- onClick: () => fitBounds(),
217
- "aria-label": "区域定位",
218
- title: "区域定位"
219
- },
220
- "⊞"
221
- );
222
- }, [isFloorMapView, mode, controls.showFitBounds, fitBounds]);
226
+ const topBarExtraActions = null;
223
227
  const [mapPaletteDragActive, setMapPaletteDragActive] = (0, import_react.useState)(false);
224
228
  (0, import_react.useEffect)(() => {
225
229
  const clear = () => setMapPaletteDragActive(false);
@@ -243,7 +247,8 @@ function PisellFloorMapLayoutInner(props, ref) {
243
247
  type: "scene",
244
248
  elementKind: payload.elementKind,
245
249
  dataSourceKey: payload.dataSourceKey,
246
- recordId: payload.recordId
250
+ recordId: payload.recordId,
251
+ recordIds: payload.recordIds
247
252
  });
248
253
  },
249
254
  [isFloorMapView, mode, placeSceneElementFromPaletteDrop]
@@ -255,7 +260,8 @@ function PisellFloorMapLayoutInner(props, ref) {
255
260
  type: "scene",
256
261
  elementKind: payload.elementKind,
257
262
  dataSourceKey: payload.dataSourceKey,
258
- recordId: payload.recordId
263
+ recordId: payload.recordId,
264
+ recordIds: payload.recordIds
259
265
  });
260
266
  },
261
267
  [isFloorMapView, mode, placeSceneElementFromPaletteDrop]
@@ -490,7 +496,7 @@ function PisellFloorMapLayoutInner(props, ref) {
490
496
  /* @__PURE__ */ import_react.default.createElement(
491
497
  import_react_zoom_pan_pinch.TransformWrapper,
492
498
  {
493
- key: isFloorMapView ? `fmap-${currentCanvasId ?? "na"}-bp${(mapLayer == null ? void 0 : mapLayer.boundingPadding) ?? "d"}-z${zoomConfig.initialScale}` : "fmap-layout",
499
+ key: transformWrapperKey,
494
500
  centerOnInit: false,
495
501
  initialScale: zoomConfig.initialScale,
496
502
  initialPositionX,
@@ -530,18 +536,13 @@ function PisellFloorMapLayoutInner(props, ref) {
530
536
  minHeight: contentHeight,
531
537
  position: "relative",
532
538
  overflow: "visible",
533
- backgroundColor: "#F2F4F7",
534
- backgroundImage: [
535
- "linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px)",
536
- "linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)"
537
- ].join(", "),
538
- backgroundSize: "50px 50px"
539
+ backgroundColor: "#F2F4F7"
539
540
  }
540
541
  },
541
542
  /* @__PURE__ */ import_react.default.createElement(
542
543
  import_MapLayer.default,
543
544
  {
544
- config: mapLayer,
545
+ config: effectiveMapLayer,
545
546
  contentWidth,
546
547
  contentHeight,
547
548
  cellSize,
@@ -565,7 +566,7 @@ function PisellFloorMapLayoutInner(props, ref) {
565
566
  selectedId,
566
567
  onSelect: setSelectedId,
567
568
  onUpdateItem: handleUpdateItem,
568
- snapStep: (mapLayer == null ? void 0 : mapLayer.snapStep) ?? 0,
569
+ snapStep: (effectiveMapLayer == null ? void 0 : effectiveMapLayer.snapStep) ?? 0,
569
570
  scale,
570
571
  onInteractionChange: setIsInteractingWithElement,
571
572
  getMergedItemWrapperStyle
@@ -620,7 +621,9 @@ function PisellFloorMapLayoutInner(props, ref) {
620
621
  scale,
621
622
  isFullscreen,
622
623
  fitBounds,
623
- toggleFullscreen: editToggleFullscreen
624
+ toggleFullscreen: editToggleFullscreen,
625
+ mapGridVisible: Boolean(effectiveMapLayer == null ? void 0 : effectiveMapLayer.showGrid),
626
+ onToggleMapGrid: isFloorMapView ? toggleDraftCanvasShowGrid : void 0
624
627
  }
625
628
  ), isFloorMapView && mode === "edit" && editPanelParams && config && dataSources && /* @__PURE__ */ import_react.default.createElement(
626
629
  "div",
@@ -121,16 +121,40 @@ function FloorMapEditPanel(props) {
121
121
  popDesc: import_utils.locales.getText(`${I18N_EP}.pop-desc`),
122
122
  btnDelete: import_utils.locales.getText(`${I18N_EP}.btn-delete`),
123
123
  btnCancel: import_utils.locales.getText(`${I18N_EP}.btn-cancel`),
124
- btnOkDelete: import_utils.locales.getText(`${I18N_EP}.btn-ok-delete`)
124
+ btnOkDelete: import_utils.locales.getText(`${I18N_EP}.btn-ok-delete`),
125
+ labelElementKind: import_utils.locales.getText(`${I18N_EP}.label-element-kind`),
126
+ hintKindBindingCleared: import_utils.locales.getText(
127
+ `${I18N_EP}.hint-kind-binding-cleared`
128
+ )
125
129
  }),
126
130
  [engineLocale]
127
131
  );
132
+ const swappableKinds = (0, import_react.useMemo)(
133
+ () => (0, import_floorMapElementKindUtils.getSwappableElementKindsInSameCategory)(config, sceneElement.elementKind),
134
+ [config, sceneElement.elementKind]
135
+ );
136
+ const handleElementKindChange = (0, import_react.useCallback)(
137
+ (nextKind) => {
138
+ if (nextKind === sceneElement.elementKind) return;
139
+ const hadBinding = Boolean(sceneElement.dataBinding);
140
+ const patch = (0, import_floorMapElementKindUtils.patchSceneElementForKindSwitch)(
141
+ config,
142
+ sceneElement,
143
+ nextKind
144
+ );
145
+ if (hadBinding && patch.dataBinding === void 0) {
146
+ import_antd.message.info(ep.hintKindBindingCleared);
147
+ }
148
+ onUpdate(patch);
149
+ },
150
+ [config, sceneElement, onUpdate, ep.hintKindBindingCleared]
151
+ );
128
152
  const canvasOptions = config.canvases.filter((c) => c.enabled).sort((a, b) => a.order - b.order);
129
153
  const kindConfig = (0, import_floorMapElementKindUtils.getElementKindConfig)(config, sceneElement.elementKind);
130
154
  const bindingPolicy = (0, import_floorMapElementKindUtils.resolveDataBindingPolicy)(kindConfig);
131
155
  const allKeys = Object.keys(dataSources);
132
156
  const allowedKeys = ((_c = kindConfig == null ? void 0 : kindConfig.allowedDataSourceKeys) == null ? void 0 : _c.length) ? kindConfig.allowedDataSourceKeys.filter((k) => allKeys.includes(k)) : allKeys;
133
- const isImageKind = sceneElement.elementKind === import_types.FLOOR_MAP_IMAGE_ELEMENT_KIND;
157
+ const isImageKind = (0, import_floorMapElementKindUtils.isFloorMapImageElementKind)(sceneElement.elementKind);
134
158
  const layoutLocked = Boolean(sceneElement.layoutTransformLocked);
135
159
  const initialValues = import_react.default.useMemo(() => {
136
160
  const dw = isImageKind ? 400 : 180;
@@ -250,6 +274,9 @@ function FloorMapEditPanel(props) {
250
274
  });
251
275
  };
252
276
  const panelScrollRef = (0, import_react.useRef)(null);
277
+ const getSelectPopupContainer = (0, import_react.useCallback)((node) => {
278
+ return node.parentElement ?? panelScrollRef.current ?? document.body;
279
+ }, []);
253
280
  const dragScrollRef = (0, import_react.useRef)({
254
281
  active: false,
255
282
  pointerId: -1,
@@ -315,11 +342,11 @@ function FloorMapEditPanel(props) {
315
342
  onPointerUp: endPanelDragScroll,
316
343
  onPointerCancel: endPanelDragScroll
317
344
  },
318
- /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-header` }, /* @__PURE__ */ import_react.default.createElement("span", null, ep.elementProps), /* @__PURE__ */ import_react.default.createElement(
345
+ /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-header` }, /* @__PURE__ */ import_react.default.createElement("span", { className: `${PREFIX}-edit-panel-header-title` }, ep.elementProps), /* @__PURE__ */ import_react.default.createElement(
319
346
  import_antd.Button,
320
347
  {
321
348
  type: "text",
322
- size: "small",
349
+ size: "large",
323
350
  className: `${PREFIX}-edit-panel-close`,
324
351
  icon: /* @__PURE__ */ import_react.default.createElement(import_icons.CloseOutlined, null),
325
352
  "aria-label": ep.closeAria,
@@ -327,12 +354,26 @@ function FloorMapEditPanel(props) {
327
354
  }
328
355
  )),
329
356
  (formHasUnappliedChanges || layoutDraftDirty) && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-hints`, role: "status" }, formHasUnappliedChanges ? /* @__PURE__ */ import_react.default.createElement("p", { className: `${PREFIX}-edit-panel-hint warn` }, ep.hintApply) : null, layoutDraftDirty ? /* @__PURE__ */ import_react.default.createElement("p", { className: `${PREFIX}-edit-panel-hint muted` }, ep.hintSave) : null),
357
+ swappableKinds.length > 1 ? /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-kind-row` }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-bind-label` }, ep.labelElementKind), /* @__PURE__ */ import_react.default.createElement(
358
+ import_antd.Select,
359
+ {
360
+ size: "large",
361
+ value: sceneElement.elementKind,
362
+ options: swappableKinds.map((k) => ({
363
+ value: k.value,
364
+ label: k.label
365
+ })),
366
+ onChange: handleElementKindChange,
367
+ getPopupContainer: getSelectPopupContainer,
368
+ style: { width: "100%", marginBottom: 12 }
369
+ }
370
+ )) : null,
330
371
  /* @__PURE__ */ import_react.default.createElement(
331
372
  import_antd.Form,
332
373
  {
333
374
  form,
334
375
  layout: "vertical",
335
- size: "small",
376
+ size: "large",
336
377
  onFinish: handleFinish,
337
378
  initialValues,
338
379
  onValuesChange: () => {
@@ -344,7 +385,7 @@ function FloorMapEditPanel(props) {
344
385
  import_antd.Button,
345
386
  {
346
387
  type: "text",
347
- size: "small",
388
+ size: "large",
348
389
  className: `${PREFIX}-edit-panel-layout-lock-btn`,
349
390
  icon: layoutLocked ? /* @__PURE__ */ import_react.default.createElement(import_icons.LockOutlined, null) : /* @__PURE__ */ import_react.default.createElement(import_icons.UnlockOutlined, null),
350
391
  "aria-pressed": layoutLocked,
@@ -412,15 +453,16 @@ function FloorMapEditPanel(props) {
412
453
  value: c.id,
413
454
  label: (0, import_floorMapCanvasDisplay.getFloorMapCanvasDisplayName)(c, engineLocale)
414
455
  })),
415
- allowClear: false
456
+ allowClear: false,
457
+ getPopupContainer: getSelectPopupContainer
416
458
  }
417
459
  )),
418
- /* @__PURE__ */ import_react.default.createElement(import_antd.Form.Item, null, /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { type: "primary", htmlType: "submit", size: "small" }, ep.apply))
460
+ /* @__PURE__ */ import_react.default.createElement(import_antd.Form.Item, null, /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { type: "primary", htmlType: "submit", size: "large" }, ep.apply))
419
461
  ),
420
462
  showDataBindingSection && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record` }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-title` }, ep.dataBinding), /* @__PURE__ */ import_react.default.createElement("p", { className: `${PREFIX}-edit-panel-record-draft-note` }, ep.dataBindingNote), allowedKeys.length >= 1 ? /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-bind` }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-bind-label` }, ep.labelDataSource), /* @__PURE__ */ import_react.default.createElement(
421
463
  import_antd.Select,
422
464
  {
423
- size: "small",
465
+ size: "large",
424
466
  style: { width: "100%" },
425
467
  placeholder: ep.phDataSource,
426
468
  value: binding == null ? void 0 : binding.dataSourceKey,
@@ -441,17 +483,19 @@ function FloorMapEditPanel(props) {
441
483
  }
442
484
  });
443
485
  },
444
- allowClear: bindingPolicy === "optional"
486
+ allowClear: bindingPolicy === "optional",
487
+ getPopupContainer: getSelectPopupContainer
445
488
  }
446
489
  )) : null, allowedKeys.length >= 1 && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-bind` }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-edit-panel-record-bind-label` }, ep.labelPickRow), /* @__PURE__ */ import_react.default.createElement(
447
490
  import_antd.Select,
448
491
  {
449
- size: "small",
492
+ size: "large",
450
493
  placeholder: dataRecordBindOptions.length ? ep.phPickRow : ep.phNoRows,
451
494
  style: { width: "100%" },
452
495
  value: hasBoundDataRecord ? binding == null ? void 0 : binding.recordId : void 0,
453
496
  allowClear: bindingPolicy === "optional",
454
497
  options: dataRecordBindOptions,
498
+ getPopupContainer: getSelectPopupContainer,
455
499
  onChange: (newId) => {
456
500
  const key = (binding == null ? void 0 : binding.dataSourceKey) ?? allowedKeys[0];
457
501
  if (!key) return;
@@ -497,7 +541,7 @@ function FloorMapEditPanel(props) {
497
541
  cancelText: ep.btnCancel,
498
542
  okButtonProps: { danger: true }
499
543
  },
500
- /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { type: "default", danger: true, block: true, size: "small" }, ep.btnDelete)
544
+ /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { type: "default", danger: true, block: true, size: "large" }, ep.btnDelete)
501
545
  )) : null
502
546
  );
503
547
  }
@@ -15,7 +15,15 @@
15
15
  justify-content: space-between;
16
16
  gap: 8px;
17
17
  margin-bottom: 12px;
18
+ }
19
+
20
+ /** 与下方分组标题(如「数据绑定」「数据源记录」)统一的标题样式 */
21
+
22
+ &-header-title {
23
+ font-size: 14px;
18
24
  font-weight: 500;
25
+ color: #262626;
26
+ line-height: 1.4;
19
27
  }
20
28
 
21
29
  &-close {
@@ -147,11 +147,17 @@ function FloorMapToolbar(props) {
147
147
  onPlaceModeChange({
148
148
  ...mode,
149
149
  dataSourceKey: key,
150
- recordId: void 0
150
+ recordId: void 0,
151
+ recordIds: void 0
151
152
  });
152
153
  };
153
- const handleRecordChange = (mode, recordId) => {
154
- onPlaceModeChange({ ...mode, recordId: recordId || void 0 });
154
+ const handleRecordsChange = (mode, ids) => {
155
+ const list = (ids == null ? void 0 : ids.filter(Boolean)) ?? [];
156
+ onPlaceModeChange({
157
+ ...mode,
158
+ recordIds: list.length > 0 ? list : void 0,
159
+ recordId: void 0
160
+ });
155
161
  };
156
162
  const cancelPlaceMode = () => onPlaceModeChange(null);
157
163
  const renderKindCard = (k) => {
@@ -179,7 +185,7 @@ function FloorMapToolbar(props) {
179
185
  elementKind: k.value,
180
186
  ...(placeMode == null ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === k.value ? {
181
187
  dataSourceKey: placeMode.dataSourceKey,
182
- recordId: placeMode.recordId
188
+ ...placeMode.recordIds && placeMode.recordIds.length > 0 ? { recordIds: placeMode.recordIds } : placeMode.recordId ? { recordId: placeMode.recordId } : {}
183
189
  } : {}
184
190
  };
185
191
  return /* @__PURE__ */ import_react.default.createElement("div", { key: k.value, className: `${PREFIX}-toolbar-preview-card-wrap` }, /* @__PURE__ */ import_react.default.createElement(
@@ -246,7 +252,7 @@ function FloorMapToolbar(props) {
246
252
  if ((placeMode == null ? void 0 : placeMode.type) === "scene")
247
253
  handleDsChange(placeMode, v);
248
254
  },
249
- size: "small",
255
+ size: "large",
250
256
  style: { width: "100%" }
251
257
  }
252
258
  ), (() => {
@@ -263,23 +269,26 @@ function FloorMapToolbar(props) {
263
269
  if (unplaced.length === 0) {
264
270
  return /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-toolbar-record-pick-hint` }, "当前数据源无未绑定记录,或列表为空;可直接在画布落点占位。");
265
271
  }
272
+ const recordValue = (mode == null ? void 0 : mode.recordIds) && mode.recordIds.length > 0 ? mode.recordIds : (mode == null ? void 0 : mode.recordId) ? [mode.recordId] : void 0;
266
273
  return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(
267
274
  import_antd.Select,
268
275
  {
269
- placeholder: "选择要展示的记录(可选)",
276
+ mode: "multiple",
277
+ placeholder: "选择要展示的记录(可选,可多选)",
270
278
  allowClear: true,
271
- value: mode == null ? void 0 : mode.recordId,
279
+ maxTagCount: "responsive",
280
+ value: recordValue,
272
281
  options: unplaced.map((r) => ({
273
282
  value: r.id,
274
283
  label: formatDataRecordOptionLabel(r)
275
284
  })),
276
285
  onChange: (v) => {
277
- if (mode) handleRecordChange(mode, v);
286
+ if (mode) handleRecordsChange(mode, v);
278
287
  },
279
- size: "small",
288
+ size: "large",
280
289
  style: { width: "100%", marginTop: 4 }
281
290
  }
282
- ), /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-toolbar-record-pick-hint` }, "选中后在画布点击完成落位;留空则先占位,稍后在侧栏绑定。"));
291
+ ), /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-toolbar-record-pick-hint` }, "可选多条,在画布点击一次将按阶梯偏移落多条;留空则先占位,稍后在侧栏绑定。"));
283
292
  })()), allowedKeys.length === 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-toolbar-record-hint` }, "无可用数据源"), /* @__PURE__ */ import_react.default.createElement(
284
293
  "button",
285
294
  {
@@ -2,7 +2,7 @@
2
2
  .pisell-floor-map-layout-toolbar {
3
3
  &.pisell-floor-map-layout-toolbar-sidebar {
4
4
  position: relative;
5
- width: 220px;
5
+ width: 248px;
6
6
  flex-shrink: 0;
7
7
  display: flex;
8
8
  flex-direction: column;
@@ -131,8 +131,9 @@
131
131
  display: block;
132
132
  width: 100%;
133
133
  margin-top: 8px;
134
- padding: 8px 12px;
135
- font-size: 13px;
134
+ padding: 10px 16px;
135
+ font-size: 15px;
136
+ min-height: 40px;
136
137
  color: #333;
137
138
  background: #f5f5f5;
138
139
  border: 1px solid #d9d9d9;
@@ -152,8 +153,9 @@
152
153
 
153
154
  &.cancel-inline {
154
155
  margin-top: 0;
155
- padding: 4px 8px;
156
- font-size: 12px;
156
+ padding: 8px 12px;
157
+ font-size: 14px;
158
+ min-height: 40px;
157
159
  color: #8c8c8c;
158
160
  }
159
161
 
@@ -85,12 +85,14 @@ function MapLayer(props) {
85
85
  gap: gapCss,
86
86
  ...pointerEventsNone ? { pointerEvents: "none" } : {}
87
87
  };
88
+ const snapStep = Math.max(1, Number(config.snapStep ?? 1) || 1);
89
+ const gridSize = Math.max(50, Math.round(cellSize * snapStep));
88
90
  const gridStyle = showGrid ? {
89
91
  backgroundImage: `
90
92
  linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px),
91
93
  linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)
92
94
  `,
93
- backgroundSize: `${cellSize}px ${cellSize}px`
95
+ backgroundSize: `${gridSize}px ${gridSize}px`
94
96
  } : {};
95
97
  return /* @__PURE__ */ import_react.default.createElement(
96
98
  "div",
@@ -21,6 +21,10 @@ export interface ViewControlsProps {
21
21
  /** 当前是否处于全屏 */
22
22
  isFullscreen?: boolean;
23
23
  className?: string;
24
+ /** 与 config.showGridToggle 联用:当前画布是否显示网格 */
25
+ mapGridVisible?: boolean;
26
+ /** 切换当前画布 draft 的 mapLayer.showGrid */
27
+ onToggleMapGrid?: () => void;
24
28
  }
25
29
  export declare function ViewControls(props: ViewControlsProps): JSX.Element;
26
30
  export default ViewControls;
@@ -39,12 +39,22 @@ var import_icons = require("@ant-design/icons");
39
39
  var import_ViewControls = require("./ViewControls.less");
40
40
  var PREFIX = "pisell-floor-map-layout";
41
41
  function ViewControls(props) {
42
- const { api, config = {}, scale = 1, isFullscreen = false, className } = props;
42
+ const {
43
+ api,
44
+ config = {},
45
+ scale = 1,
46
+ isFullscreen = false,
47
+ className,
48
+ mapGridVisible = false,
49
+ onToggleMapGrid
50
+ } = props;
43
51
  const showZoom = config.showZoom !== false;
44
52
  const showReset = config.showReset === true;
45
53
  const showFitBounds = config.showFitBounds === true;
46
54
  const showFullscreen = config.showFullscreen === true;
55
+ const showGridToggle = config.showGridToggle === true && typeof onToggleMapGrid === "function";
47
56
  const scalePercent = Math.round(scale * 100);
57
+ const showToolsCapsule = showReset || showFitBounds || showFullscreen || showGridToggle;
48
58
  return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_classnames.default)(`${PREFIX}-view-controls`, className) }, showZoom && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-view-controls-zoom-stepper` }, /* @__PURE__ */ import_react.default.createElement(
49
59
  "button",
50
60
  {
@@ -63,11 +73,11 @@ function ViewControls(props) {
63
73
  "aria-label": "放大"
64
74
  },
65
75
  /* @__PURE__ */ import_react.default.createElement(import_icons.PlusOutlined, null)
66
- )), showReset && /* @__PURE__ */ import_react.default.createElement(
76
+ )), showToolsCapsule && /* @__PURE__ */ import_react.default.createElement("div", { className: `${PREFIX}-view-controls-tools-capsule` }, showReset && /* @__PURE__ */ import_react.default.createElement(
67
77
  "button",
68
78
  {
69
79
  type: "button",
70
- className: `${PREFIX}-view-controls-btn`,
80
+ className: `${PREFIX}-view-controls-tool-btn`,
71
81
  onClick: () => api.resetTransform(),
72
82
  "aria-label": "复位"
73
83
  },
@@ -76,21 +86,33 @@ function ViewControls(props) {
76
86
  "button",
77
87
  {
78
88
  type: "button",
79
- className: `${PREFIX}-view-controls-btn`,
89
+ className: `${PREFIX}-view-controls-tool-btn`,
80
90
  onClick: () => api.fitBounds(),
81
91
  "aria-label": "区域定位"
82
92
  },
83
93
  "⊞"
94
+ ), showGridToggle && /* @__PURE__ */ import_react.default.createElement(
95
+ "button",
96
+ {
97
+ type: "button",
98
+ className: (0, import_classnames.default)(`${PREFIX}-view-controls-tool-btn`, {
99
+ [`${PREFIX}-view-controls-tool-btn--active`]: mapGridVisible
100
+ }),
101
+ onClick: () => onToggleMapGrid(),
102
+ "aria-pressed": mapGridVisible,
103
+ "aria-label": mapGridVisible ? "隐藏网格" : "显示网格"
104
+ },
105
+ /* @__PURE__ */ import_react.default.createElement(import_icons.BorderInnerOutlined, null)
84
106
  ), showFullscreen && api.toggleFullscreen && /* @__PURE__ */ import_react.default.createElement(
85
107
  "button",
86
108
  {
87
109
  type: "button",
88
- className: `${PREFIX}-view-controls-btn`,
110
+ className: `${PREFIX}-view-controls-tool-btn`,
89
111
  onClick: () => api.toggleFullscreen(),
90
112
  "aria-label": isFullscreen ? "退出全屏" : "全屏"
91
113
  },
92
114
  isFullscreen ? /* @__PURE__ */ import_react.default.createElement(import_icons.FullscreenExitOutlined, null) : /* @__PURE__ */ import_react.default.createElement(import_icons.FullscreenOutlined, null)
93
- ));
115
+ )));
94
116
  }
95
117
  var ViewControls_default = ViewControls;
96
118
  // Annotate the CommonJS export names for ESM import in node:
@@ -10,6 +10,7 @@
10
10
  gap: 6px;
11
11
 
12
12
  /* Stepper:胶囊形 [减] 数值% [加] */
13
+
13
14
  &-zoom-stepper {
14
15
  display: flex;
15
16
  align-items: center;
@@ -52,26 +53,49 @@
52
53
  color: #101828;
53
54
  }
54
55
 
55
- &-btn {
56
- width: 32px;
57
- height: 32px;
56
+ /* 复位 / 区域定位 / 全屏 / 网格:与 Stepper 同系胶囊条 */
57
+
58
+ &-tools-capsule {
59
+ display: flex;
60
+ align-items: center;
61
+ flex-wrap: wrap;
62
+ gap: 4px;
63
+ min-height: 56px;
64
+ padding: 2px 6px;
65
+ background: #fff;
66
+ border: 1px solid #98a2b3;
67
+ border-radius: 100px;
68
+ box-shadow: 0 12px 16px -4px rgba(16, 24, 40, 0.08), 0 4px 6px -2px rgba(16, 24, 40, 0.03);
69
+ }
70
+
71
+ &-tool-btn {
72
+ width: 52px;
73
+ height: 52px;
58
74
  display: flex;
59
75
  align-items: center;
60
76
  justify-content: center;
61
77
  padding: 0;
62
- border: 1px solid rgba(0, 0, 0, 0.1);
63
- border-radius: 4px;
64
- background: #fff;
78
+ border: none;
79
+ border-radius: 50%;
80
+ background: transparent;
65
81
  cursor: pointer;
66
- font-size: 18px;
82
+ color: #101828;
83
+ font-size: 20px;
67
84
  line-height: 1;
68
- color: rgba(0, 0, 0, 0.65);
69
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
70
85
 
71
86
  &:hover {
72
- color: #1890ff;
73
- border-color: #1890ff;
74
- background: #e6f7ff;
87
+ background: #f2f4f7;
88
+ color: #101828;
89
+ }
90
+ }
91
+
92
+ &-tool-btn--active {
93
+ background: #fff4ed;
94
+ color: #ff692e;
95
+
96
+ &:hover {
97
+ background: #ffe8d9;
98
+ color: #ff692e;
75
99
  }
76
100
  }
77
101
  }
@@ -7,5 +7,7 @@ export interface ViewControlsWithZoomProps {
7
7
  fitBounds: () => void;
8
8
  /** 未传时不展示全屏按钮(如编辑态 floorMapFullscreenMode 为 disabled) */
9
9
  toggleFullscreen?: () => void;
10
+ mapGridVisible?: boolean;
11
+ onToggleMapGrid?: () => void;
10
12
  }
11
13
  export declare function ViewControlsWithZoom(props: ViewControlsWithZoomProps): JSX.Element;
@@ -53,7 +53,9 @@ function ViewControlsWithZoom(props) {
53
53
  api,
54
54
  config: props.config,
55
55
  scale: props.scale,
56
- isFullscreen: props.isFullscreen
56
+ isFullscreen: props.isFullscreen,
57
+ mapGridVisible: props.mapGridVisible,
58
+ onToggleMapGrid: props.onToggleMapGrid
57
59
  }
58
60
  );
59
61
  }
@@ -59,4 +59,5 @@ export declare function useFloorMapEditState<T extends FloorMapItemBase>(params:
59
59
  } | null;
60
60
  placeOverlayClass: string;
61
61
  isLayoutDirty: boolean;
62
+ toggleDraftCanvasShowGrid: () => void;
62
63
  };