@flowgram.ai/free-container-plugin 0.2.27 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -19,11 +19,7 @@ var NodeIntoContainerType = /* @__PURE__ */ ((NodeIntoContainerType2) => {
19
19
  // src/node-into-container/service.ts
20
20
  import { throttle } from "lodash";
21
21
  import { inject, injectable } from "inversify";
22
- import {
23
- Rectangle,
24
- DisposableCollection,
25
- Emitter
26
- } from "@flowgram.ai/utils";
22
+ import { DisposableCollection, Emitter } from "@flowgram.ai/utils";
27
23
  import {
28
24
  WorkflowDocument,
29
25
  WorkflowDragService,
@@ -32,8 +28,102 @@ import {
32
28
  WorkflowSelectService
33
29
  } from "@flowgram.ai/free-layout-core";
34
30
  import { HistoryService } from "@flowgram.ai/free-history-plugin";
35
- import { FlowNodeRenderData, FlowNodeBaseType } from "@flowgram.ai/document";
31
+ import { FlowNodeRenderData, FlowNodeBaseType as FlowNodeBaseType2 } from "@flowgram.ai/document";
36
32
  import { PlaygroundConfigEntity, TransformData } from "@flowgram.ai/core";
33
+
34
+ // src/utils/next-frame.ts
35
+ var nextFrame = async () => {
36
+ await new Promise((resolve) => requestAnimationFrame(resolve));
37
+ };
38
+
39
+ // src/utils/is-container.ts
40
+ var isContainer = (node) => node?.getNodeMeta().isContainer ?? false;
41
+
42
+ // src/utils/get-container-transforms.ts
43
+ var getContainerTransforms = (allNodes) => allNodes.filter((node) => {
44
+ if (node.originParent) {
45
+ return node.getNodeMeta().selectable && node.originParent.getNodeMeta().selectable;
46
+ }
47
+ return node.getNodeMeta().selectable;
48
+ }).filter((node) => isContainer(node)).sort((a, b) => {
49
+ const aIndex = a.renderData.stackIndex;
50
+ const bIndex = b.renderData.stackIndex;
51
+ return bIndex - aIndex;
52
+ }).map((node) => node.transform);
53
+
54
+ // src/utils/get-collision-transform.ts
55
+ import { Rectangle } from "@flowgram.ai/utils";
56
+
57
+ // src/utils/is-rect-intersects.ts
58
+ var isRectIntersects = (rectA, rectB) => {
59
+ const hasHorizontalOverlap = rectA.right > rectB.left && rectA.left < rectB.right;
60
+ const hasVerticalOverlap = rectA.bottom > rectB.top && rectA.top < rectB.bottom;
61
+ return hasHorizontalOverlap && hasVerticalOverlap;
62
+ };
63
+
64
+ // src/utils/is-point-in-rect.ts
65
+ var isPointInRect = (point, rect) => point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom;
66
+
67
+ // src/utils/get-collision-transform.ts
68
+ var getCollisionTransform = (params) => {
69
+ const { targetRect, targetPoint, transforms, withPadding = false, document } = params;
70
+ const collisionTransform = transforms.find((transform) => {
71
+ const { bounds, entity } = transform;
72
+ const padding = withPadding ? document.layout.getPadding(entity) : { left: 0, right: 0 };
73
+ const transformRect = new Rectangle(
74
+ bounds.x + padding.left + padding.right,
75
+ bounds.y,
76
+ bounds.width,
77
+ bounds.height
78
+ );
79
+ if (targetRect) {
80
+ return isRectIntersects(targetRect, transformRect);
81
+ }
82
+ if (targetPoint) {
83
+ return isPointInRect(targetPoint, transformRect);
84
+ }
85
+ return false;
86
+ });
87
+ return collisionTransform;
88
+ };
89
+
90
+ // src/utils/adjust-sub-node-position.ts
91
+ import { FlowNodeBaseType } from "@flowgram.ai/document";
92
+ var adjustSubNodePosition = (params) => {
93
+ const { targetNode, containerNode, containerPadding } = params;
94
+ if (containerNode.flowNodeType === FlowNodeBaseType.ROOT) {
95
+ return targetNode.transform.position;
96
+ }
97
+ const nodeWorldTransform = targetNode.transform.transform.worldTransform;
98
+ const containerWorldTransform = containerNode.transform.transform.worldTransform;
99
+ const nodePosition = {
100
+ x: nodeWorldTransform.tx,
101
+ y: nodeWorldTransform.ty
102
+ };
103
+ const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
104
+ if (isParentEmpty) {
105
+ return {
106
+ x: 0,
107
+ y: containerPadding.top
108
+ };
109
+ } else {
110
+ return {
111
+ x: nodePosition.x - containerWorldTransform.tx,
112
+ y: nodePosition.y - containerWorldTransform.ty
113
+ };
114
+ }
115
+ };
116
+
117
+ // src/utils/index.ts
118
+ var ContainerUtils = {
119
+ nextFrame,
120
+ isContainer,
121
+ adjustSubNodePosition,
122
+ getContainerTransforms,
123
+ getCollisionTransform
124
+ };
125
+
126
+ // src/node-into-container/service.ts
37
127
  var NodeIntoContainerService = class {
38
128
  constructor() {
39
129
  this.emitter = new Emitter();
@@ -57,14 +147,14 @@ var NodeIntoContainerService = class {
57
147
  const parentNode = node.parent;
58
148
  const containerNode = parentNode?.parent;
59
149
  const nodeJSON = this.document.toNodeJSON(node);
60
- if (!parentNode || !containerNode || !this.isContainer(parentNode) || !nodeJSON.meta?.position) {
150
+ if (!parentNode || !containerNode || !ContainerUtils.isContainer(parentNode) || !nodeJSON.meta?.position) {
61
151
  return;
62
152
  }
63
153
  const parentTransform = parentNode.getData(TransformData);
64
154
  this.operationService.moveNode(node, {
65
155
  parent: containerNode
66
156
  });
67
- await this.nextFrame();
157
+ await ContainerUtils.nextFrame();
68
158
  parentTransform.fireChange();
69
159
  this.operationService.updateNodePosition(node, {
70
160
  x: parentTransform.position.x + nodeJSON.meta.position.x,
@@ -81,7 +171,7 @@ var NodeIntoContainerService = class {
81
171
  canMoveOutContainer(node) {
82
172
  const parentNode = node.parent;
83
173
  const containerNode = parentNode?.parent;
84
- if (!parentNode || !containerNode || !this.isContainer(parentNode)) {
174
+ if (!parentNode || !containerNode || !ContainerUtils.isContainer(parentNode)) {
85
175
  return false;
86
176
  }
87
177
  const canDrop = this.dragService.canDropToNode({
@@ -104,7 +194,7 @@ var NodeIntoContainerService = class {
104
194
  if (dragNode.parent === sourceParent) {
105
195
  return;
106
196
  }
107
- if (dragNode.parent?.flowNodeType === FlowNodeBaseType.GROUP || sourceParent?.flowNodeType === FlowNodeBaseType.GROUP) {
197
+ if (dragNode.parent?.flowNodeType === FlowNodeBaseType2.GROUP || sourceParent?.flowNodeType === FlowNodeBaseType2.GROUP) {
108
198
  return;
109
199
  }
110
200
  await this.removeNodeLines(dragNode);
@@ -118,7 +208,7 @@ var NodeIntoContainerService = class {
118
208
  }
119
209
  line.dispose();
120
210
  });
121
- await this.nextFrame();
211
+ await ContainerUtils.nextFrame();
122
212
  }
123
213
  /** 初始化状态 */
124
214
  initState() {
@@ -146,7 +236,7 @@ var NodeIntoContainerService = class {
146
236
  }
147
237
  this.historyService.startTransaction();
148
238
  this.state.isDraggingNode = true;
149
- this.state.transforms = this.getContainerTransforms();
239
+ this.state.transforms = ContainerUtils.getContainerTransforms(this.document.getAllNodes());
150
240
  this.state.dragNode = this.selectService.selectedNodes[0];
151
241
  this.state.dropNode = void 0;
152
242
  this.state.sourceParent = this.state.dragNode?.parent;
@@ -184,31 +274,9 @@ var NodeIntoContainerService = class {
184
274
  this.moveOutContainer({ node: dragNode });
185
275
  this.state.isSkipEvent = true;
186
276
  event.dragger.stop(event.dragEvent.clientX, event.dragEvent.clientY);
187
- await this.nextFrame();
277
+ await ContainerUtils.nextFrame();
188
278
  this.dragService.startDragSelectedNodes(event.triggerEvent);
189
279
  }
190
- /** 获取重叠位置 */
191
- getCollisionTransform(params) {
192
- const { targetRect, targetPoint, transforms, withPadding = false } = params;
193
- const collisionTransform = transforms.find((transform) => {
194
- const { bounds, entity } = transform;
195
- const padding = withPadding ? this.document.layout.getPadding(entity) : { left: 0, right: 0 };
196
- const transformRect = new Rectangle(
197
- bounds.x + padding.left + padding.right,
198
- bounds.y,
199
- bounds.width,
200
- bounds.height
201
- );
202
- if (targetRect) {
203
- return this.isRectIntersects(targetRect, transformRect);
204
- }
205
- if (targetPoint) {
206
- return this.isPointInRect(targetPoint, transformRect);
207
- }
208
- return false;
209
- });
210
- return collisionTransform;
211
- }
212
280
  /** 设置放置节点高亮 */
213
281
  setDropNode(dropNode) {
214
282
  if (this.state.dropNode === dropNode) {
@@ -231,19 +299,6 @@ var NodeIntoContainerService = class {
231
299
  renderDom.classList.add("selected");
232
300
  }
233
301
  }
234
- /** 获取容器节点transforms */
235
- getContainerTransforms() {
236
- return this.document.getAllNodes().filter((node) => {
237
- if (node.originParent) {
238
- return node.getNodeMeta().selectable && node.originParent.getNodeMeta().selectable;
239
- }
240
- return node.getNodeMeta().selectable;
241
- }).filter((node) => this.isContainer(node)).sort((a, b) => {
242
- const aIndex = a.renderData.stackIndex;
243
- const bIndex = b.renderData.stackIndex;
244
- return bIndex - aIndex;
245
- }).map((node) => node.transform);
246
- }
247
302
  /** 放置节点到容器 */
248
303
  async dropNodeToContainer() {
249
304
  const { dropNode, dragNode, isDraggingNode } = this.state;
@@ -265,9 +320,10 @@ var NodeIntoContainerService = class {
265
320
  const availableTransforms = transforms.filter(
266
321
  (transform) => transform.entity.id !== dragNode.id
267
322
  );
268
- const collisionTransform = this.getCollisionTransform({
323
+ const collisionTransform = ContainerUtils.getCollisionTransform({
269
324
  targetPoint: mousePos,
270
- transforms: availableTransforms
325
+ transforms: availableTransforms,
326
+ document: this.document
271
327
  });
272
328
  const dropNode = collisionTransform?.entity;
273
329
  const canDrop = this.canDropToContainer({
@@ -286,7 +342,7 @@ var NodeIntoContainerService = class {
286
342
  if (!dropNode || !isDropContainer || this.isParent(dragNode, dropNode)) {
287
343
  return false;
288
344
  }
289
- if (dragNode.flowNodeType === FlowNodeBaseType.GROUP && dropNode.flowNodeType !== FlowNodeBaseType.GROUP) {
345
+ if (dragNode.flowNodeType === FlowNodeBaseType2.GROUP && dropNode.flowNodeType !== FlowNodeBaseType2.GROUP) {
290
346
  return false;
291
347
  }
292
348
  const canDrop = this.dragService.canDropToNode({
@@ -318,8 +374,14 @@ var NodeIntoContainerService = class {
318
374
  this.operationService.moveNode(node, {
319
375
  parent: containerNode
320
376
  });
321
- this.operationService.updateNodePosition(node, this.adjustSubNodePosition(node, containerNode));
322
- await this.nextFrame();
377
+ const containerPadding = this.document.layout.getPadding(containerNode);
378
+ const position = ContainerUtils.adjustSubNodePosition({
379
+ targetNode: node,
380
+ containerNode,
381
+ containerPadding
382
+ });
383
+ this.operationService.updateNodePosition(node, position);
384
+ await ContainerUtils.nextFrame();
323
385
  this.emitter.fire({
324
386
  type: "in" /* In */,
325
387
  node,
@@ -327,49 +389,6 @@ var NodeIntoContainerService = class {
327
389
  targetContainer: containerNode
328
390
  });
329
391
  }
330
- /**
331
- * 如果存在容器节点,且传入鼠标坐标,需要用容器的坐标减去传入的鼠标坐标
332
- */
333
- adjustSubNodePosition(targetNode, containerNode) {
334
- if (containerNode.flowNodeType === FlowNodeBaseType.ROOT) {
335
- return targetNode.transform.position;
336
- }
337
- const nodeWorldTransform = targetNode.transform.transform.worldTransform;
338
- const containerWorldTransform = containerNode.transform.transform.worldTransform;
339
- const nodePosition = {
340
- x: nodeWorldTransform.tx,
341
- y: nodeWorldTransform.ty
342
- };
343
- const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
344
- const containerPadding = this.document.layout.getPadding(containerNode);
345
- if (isParentEmpty) {
346
- return {
347
- x: 0,
348
- y: containerPadding.top
349
- };
350
- } else {
351
- return {
352
- x: nodePosition.x - containerWorldTransform.tx,
353
- y: nodePosition.y - containerWorldTransform.ty
354
- };
355
- }
356
- }
357
- isContainer(node) {
358
- return node?.getNodeMeta().isContainer ?? false;
359
- }
360
- /** 判断点是否在矩形内 */
361
- isPointInRect(point, rect) {
362
- return point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom;
363
- }
364
- /** 判断两个矩形是否相交 */
365
- isRectIntersects(rectA, rectB) {
366
- const hasHorizontalOverlap = rectA.right > rectB.left && rectA.left < rectB.right;
367
- const hasVerticalOverlap = rectA.bottom > rectB.top && rectA.top < rectB.bottom;
368
- return hasHorizontalOverlap && hasVerticalOverlap;
369
- }
370
- async nextFrame() {
371
- await new Promise((resolve) => requestAnimationFrame(resolve));
372
- }
373
392
  };
374
393
  __decorateClass([
375
394
  inject(WorkflowDragService)
@@ -421,12 +440,12 @@ import {
421
440
  useCurrentEntity,
422
441
  WorkflowNodePortsData
423
442
  } from "@flowgram.ai/free-layout-core";
424
- import { FlowNodeTransformData as FlowNodeTransformData2 } from "@flowgram.ai/document";
443
+ import { FlowNodeTransformData } from "@flowgram.ai/document";
425
444
  var useNodeSize = () => {
426
445
  const node = useCurrentEntity();
427
446
  const nodeMeta = node.getNodeMeta();
428
- const { size = { width: 300, height: 200 }, isContainer } = nodeMeta;
429
- const transform = node.getData(FlowNodeTransformData2);
447
+ const { size = { width: 300, height: 200 }, isContainer: isContainer2 } = nodeMeta;
448
+ const transform = node.getData(FlowNodeTransformData);
430
449
  const [width, setWidth] = useState(size.width);
431
450
  const [height, setHeight] = useState(size.height);
432
451
  const updatePorts = () => {
@@ -452,7 +471,7 @@ var useNodeSize = () => {
452
471
  useEffect(() => {
453
472
  updateSize();
454
473
  }, []);
455
- if (!isContainer) {
474
+ if (!isContainer2) {
456
475
  return;
457
476
  }
458
477
  return {
@@ -827,6 +846,7 @@ var SubCanvasRender = ({
827
846
  );
828
847
  };
829
848
  export {
849
+ ContainerUtils,
830
850
  NodeIntoContainerService,
831
851
  NodeIntoContainerType,
832
852
  SubCanvasBackground,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/node-into-container/constant.ts","../../src/node-into-container/service.ts","../../src/node-into-container/plugin.tsx","../../src/sub-canvas/hooks/use-node-size.ts","../../src/sub-canvas/hooks/use-sync-node-render-size.ts","../../src/sub-canvas/components/background/index.tsx","../../src/sub-canvas/components/background/style.ts","../../src/sub-canvas/components/border/index.tsx","../../src/sub-canvas/components/border/style.ts","../../src/sub-canvas/components/render/index.tsx","../../src/sub-canvas/components/render/style.ts","../../src/sub-canvas/components/tips/index.tsx","../../src/sub-canvas/components/tips/use-control.ts","../../src/sub-canvas/components/tips/global-store.ts","../../src/sub-canvas/components/tips/style.ts","../../src/sub-canvas/components/tips/is-mac-os.ts","../../src/sub-canvas/components/tips/icon-close.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport enum NodeIntoContainerType {\n In = 'in',\n Out = 'out',\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion -- no need */\nimport { throttle } from 'lodash';\nimport { inject, injectable } from 'inversify';\nimport {\n type PositionSchema,\n Rectangle,\n type Disposable,\n DisposableCollection,\n Emitter,\n type IPoint,\n} from '@flowgram.ai/utils';\nimport {\n type NodesDragEvent,\n WorkflowDocument,\n WorkflowDragService,\n WorkflowLinesManager,\n type WorkflowNodeEntity,\n WorkflowNodeMeta,\n WorkflowOperationBaseService,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { HistoryService } from '@flowgram.ai/free-history-plugin';\nimport { FlowNodeTransformData, FlowNodeRenderData, FlowNodeBaseType } from '@flowgram.ai/document';\nimport { PlaygroundConfigEntity, TransformData } from '@flowgram.ai/core';\n\nimport type { NodeIntoContainerEvent, NodeIntoContainerState } from './type';\nimport { NodeIntoContainerType } from './constant';\n\n@injectable()\nexport class NodeIntoContainerService {\n public state: NodeIntoContainerState;\n\n @inject(WorkflowDragService)\n private dragService: WorkflowDragService;\n\n @inject(WorkflowDocument)\n private document: WorkflowDocument;\n\n @inject(PlaygroundConfigEntity)\n private playgroundConfig: PlaygroundConfigEntity;\n\n @inject(WorkflowOperationBaseService)\n private operationService: WorkflowOperationBaseService;\n\n @inject(WorkflowLinesManager)\n private linesManager: WorkflowLinesManager;\n\n @inject(HistoryService) private historyService: HistoryService;\n\n @inject(WorkflowSelectService) private selectService: WorkflowSelectService;\n\n private emitter = new Emitter<NodeIntoContainerEvent>();\n\n private toDispose = new DisposableCollection();\n\n public readonly on = this.emitter.event;\n\n public init(): void {\n this.initState();\n this.toDispose.push(this.emitter);\n }\n\n public ready(): void {\n this.toDispose.push(this.listenDragToContainer());\n }\n\n public dispose(): void {\n this.initState();\n this.toDispose.dispose();\n }\n\n /** 将节点移出容器 */\n public async moveOutContainer(params: { node: WorkflowNodeEntity }): Promise<void> {\n const { node } = params;\n const parentNode = node.parent;\n const containerNode = parentNode?.parent;\n const nodeJSON = this.document.toNodeJSON(node);\n if (\n !parentNode ||\n !containerNode ||\n !this.isContainer(parentNode) ||\n !nodeJSON.meta?.position\n ) {\n return;\n }\n const parentTransform = parentNode.getData<TransformData>(TransformData);\n this.operationService.moveNode(node, {\n parent: containerNode,\n });\n await this.nextFrame();\n parentTransform.fireChange();\n this.operationService.updateNodePosition(node, {\n x: parentTransform.position.x + nodeJSON.meta!.position!.x,\n y: parentTransform.position.y + nodeJSON.meta!.position!.y,\n });\n this.emitter.fire({\n type: NodeIntoContainerType.Out,\n node,\n sourceContainer: parentNode,\n targetContainer: containerNode,\n });\n }\n\n /** 能否将节点移出容器 */\n public canMoveOutContainer(node: WorkflowNodeEntity): boolean {\n const parentNode = node.parent;\n const containerNode = parentNode?.parent;\n if (!parentNode || !containerNode || !this.isContainer(parentNode)) {\n return false;\n }\n const canDrop = this.dragService.canDropToNode({\n dragNodeType: node.flowNodeType,\n dragNode: node,\n dropNodeType: containerNode?.flowNodeType,\n dropNode: containerNode,\n });\n if (!canDrop.allowDrop) {\n return false;\n }\n return true;\n }\n\n /** 移除节点所有非法连线 */\n public async clearInvalidLines(params: {\n dragNode?: WorkflowNodeEntity;\n sourceParent?: WorkflowNodeEntity;\n }): Promise<void> {\n const { dragNode, sourceParent } = params;\n if (!dragNode) {\n return;\n }\n if (dragNode.parent === sourceParent) {\n // 容器节点未改变\n return;\n }\n if (\n dragNode.parent?.flowNodeType === FlowNodeBaseType.GROUP ||\n sourceParent?.flowNodeType === FlowNodeBaseType.GROUP\n ) {\n // 移入移出 group 节点无需删除节点\n return;\n }\n await this.removeNodeLines(dragNode);\n }\n\n /** 移除节点连线 */\n public async removeNodeLines(node: WorkflowNodeEntity): Promise<void> {\n const lines = this.linesManager.getAllLines();\n lines.forEach((line) => {\n if (line.from.id !== node.id && line.to?.id !== node.id) {\n return;\n }\n line.dispose();\n });\n await this.nextFrame();\n }\n\n /** 初始化状态 */\n private initState(): void {\n this.state = {\n isDraggingNode: false,\n isSkipEvent: false,\n transforms: undefined,\n dragNode: undefined,\n dropNode: undefined,\n sourceParent: undefined,\n };\n }\n\n /** 监听节点拖拽 */\n private listenDragToContainer(): Disposable {\n const draggingNode = (e: NodesDragEvent) => this.draggingNode(e);\n const throttledDraggingNode = throttle(draggingNode, 200); // 200ms触发一次计算\n return this.dragService.onNodesDrag(async (event) => {\n if (this.selectService.selectedNodes.length !== 1) {\n return;\n }\n if (event.type === 'onDragStart') {\n if (this.state.isSkipEvent) {\n // 拖出容器后重新进入\n this.state.isSkipEvent = false;\n return;\n }\n this.historyService.startTransaction(); // 开始合并历史记录\n this.state.isDraggingNode = true;\n this.state.transforms = this.getContainerTransforms();\n this.state.dragNode = this.selectService.selectedNodes[0];\n this.state.dropNode = undefined;\n this.state.sourceParent = this.state.dragNode?.parent;\n await this.dragOutContainer(event); // 检查是否需拖出容器\n }\n if (event.type === 'onDragging') {\n throttledDraggingNode(event);\n }\n if (event.type === 'onDragEnd') {\n if (this.state.isSkipEvent) {\n // 拖出容器情况下需跳过本次事件\n return;\n }\n throttledDraggingNode.cancel();\n draggingNode(event); // 直接触发一次计算,防止延迟\n await this.dropNodeToContainer(); // 放置节点\n await this.clearInvalidLines({\n dragNode: this.state.dragNode,\n sourceParent: this.state.sourceParent,\n }); // 清除非法线条\n this.setDropNode(undefined);\n this.initState(); // 重置状态\n this.historyService.endTransaction(); // 结束合并历史记录\n }\n });\n }\n\n /** 监听节点拖拽出容器 */\n private async dragOutContainer(event: NodesDragEvent): Promise<void> {\n const { dragNode } = this.state;\n const activated = event.triggerEvent.metaKey || event.triggerEvent.ctrlKey;\n if (\n !activated || // 必须按住指定按键\n !dragNode || // 必须有一个节点\n !this.canMoveOutContainer(dragNode) // 需要能被移出容器\n ) {\n return;\n }\n this.moveOutContainer({ node: dragNode });\n this.state.isSkipEvent = true;\n event.dragger.stop(event.dragEvent.clientX, event.dragEvent.clientY);\n await this.nextFrame();\n this.dragService.startDragSelectedNodes(event.triggerEvent);\n }\n\n /** 获取重叠位置 */\n private getCollisionTransform(params: {\n transforms: FlowNodeTransformData[];\n targetRect?: Rectangle;\n targetPoint?: PositionSchema;\n withPadding?: boolean;\n }): FlowNodeTransformData | undefined {\n const { targetRect, targetPoint, transforms, withPadding = false } = params;\n const collisionTransform = transforms.find((transform) => {\n const { bounds, entity } = transform;\n const padding = withPadding ? this.document.layout.getPadding(entity) : { left: 0, right: 0 };\n const transformRect = new Rectangle(\n bounds.x + padding.left + padding.right,\n bounds.y,\n bounds.width,\n bounds.height\n );\n // 检测两个正方形是否相互碰撞\n if (targetRect) {\n return this.isRectIntersects(targetRect, transformRect);\n }\n if (targetPoint) {\n return this.isPointInRect(targetPoint, transformRect);\n }\n return false;\n });\n return collisionTransform;\n }\n\n /** 设置放置节点高亮 */\n private setDropNode(dropNode?: WorkflowNodeEntity) {\n if (this.state.dropNode === dropNode) {\n return;\n }\n if (this.state.dropNode) {\n // 清除上一个节点高亮\n const renderData = this.state.dropNode.getData(FlowNodeRenderData);\n const renderDom = renderData.node?.children?.[0] as HTMLElement;\n if (renderDom) {\n renderDom.classList.remove('selected');\n }\n }\n this.state.dropNode = dropNode;\n if (!dropNode) {\n return;\n }\n // 设置当前节点高亮\n const renderData = dropNode.getData(FlowNodeRenderData);\n const renderDom = renderData.node?.children?.[0] as HTMLElement;\n if (renderDom) {\n renderDom.classList.add('selected');\n }\n }\n\n /** 获取容器节点transforms */\n private getContainerTransforms(): FlowNodeTransformData[] {\n return this.document\n .getAllNodes()\n .filter((node) => {\n if (node.originParent) {\n return node.getNodeMeta().selectable && node.originParent.getNodeMeta().selectable;\n }\n return node.getNodeMeta().selectable;\n })\n .filter((node) => this.isContainer(node))\n .sort((a, b) => {\n const aIndex = a.renderData.stackIndex;\n const bIndex = b.renderData.stackIndex;\n // 确保层级高的节点在前面\n return bIndex - aIndex;\n })\n .map((node) => node.transform);\n }\n\n /** 放置节点到容器 */\n private async dropNodeToContainer(): Promise<void> {\n const { dropNode, dragNode, isDraggingNode } = this.state;\n if (!isDraggingNode || !dragNode || !dropNode) {\n return;\n }\n return await this.moveIntoContainer({\n node: dragNode,\n containerNode: dropNode,\n });\n }\n\n /** 拖拽节点 */\n private draggingNode(nodeDragEvent: NodesDragEvent): void {\n const { dragNode, isDraggingNode, transforms = [] } = this.state;\n if (!isDraggingNode || !dragNode || !transforms?.length) {\n return this.setDropNode(undefined);\n }\n const mousePos = this.playgroundConfig.getPosFromMouseEvent(nodeDragEvent.dragEvent);\n const availableTransforms = transforms.filter(\n (transform) => transform.entity.id !== dragNode.id\n );\n const collisionTransform = this.getCollisionTransform({\n targetPoint: mousePos,\n transforms: availableTransforms,\n });\n const dropNode = collisionTransform?.entity;\n const canDrop = this.canDropToContainer({\n dragNode,\n dropNode,\n });\n if (!canDrop) {\n return this.setDropNode(undefined);\n }\n return this.setDropNode(dropNode);\n }\n\n /** 判断能否将节点拖入容器 */\n protected canDropToContainer(params: {\n dragNode: WorkflowNodeEntity;\n dropNode?: WorkflowNodeEntity;\n }): boolean {\n const { dragNode, dropNode } = params;\n const isDropContainer = dropNode?.getNodeMeta<WorkflowNodeMeta>().isContainer;\n if (!dropNode || !isDropContainer || this.isParent(dragNode, dropNode)) {\n return false;\n }\n if (\n dragNode.flowNodeType === FlowNodeBaseType.GROUP &&\n dropNode.flowNodeType !== FlowNodeBaseType.GROUP\n ) {\n // 禁止将 group 节点拖入非 group 节点(由于目前不支持多节点拖入容器,无法计算有效线条,因此进行屏蔽)\n return false;\n }\n const canDrop = this.dragService.canDropToNode({\n dragNodeType: dragNode.flowNodeType,\n dropNodeType: dropNode?.flowNodeType,\n dragNode,\n dropNode,\n });\n if (!canDrop.allowDrop) {\n return false;\n }\n return true;\n }\n\n /** 判断一个节点是否为另一个节点的父节点(向上查找直到根节点) */\n private isParent(node: WorkflowNodeEntity, parent: WorkflowNodeEntity): boolean {\n let current = node.parent;\n while (current) {\n if (current.id === parent.id) {\n return true;\n }\n current = current.parent;\n }\n return false;\n }\n\n /** 将节点移入容器 */\n private async moveIntoContainer(params: {\n node: WorkflowNodeEntity;\n containerNode: WorkflowNodeEntity;\n }): Promise<void> {\n const { node, containerNode } = params;\n const parentNode = node.parent;\n\n this.operationService.moveNode(node, {\n parent: containerNode,\n });\n\n this.operationService.updateNodePosition(node, this.adjustSubNodePosition(node, containerNode));\n\n await this.nextFrame();\n\n this.emitter.fire({\n type: NodeIntoContainerType.In,\n node,\n sourceContainer: parentNode,\n targetContainer: containerNode,\n });\n }\n\n /**\n * 如果存在容器节点,且传入鼠标坐标,需要用容器的坐标减去传入的鼠标坐标\n */\n private adjustSubNodePosition(\n targetNode: WorkflowNodeEntity,\n containerNode: WorkflowNodeEntity\n ): IPoint {\n if (containerNode.flowNodeType === FlowNodeBaseType.ROOT) {\n return targetNode.transform.position;\n }\n const nodeWorldTransform = targetNode.transform.transform.worldTransform;\n const containerWorldTransform = containerNode.transform.transform.worldTransform;\n const nodePosition = {\n x: nodeWorldTransform.tx,\n y: nodeWorldTransform.ty,\n };\n const isParentEmpty = !containerNode.children || containerNode.children.length === 0;\n const containerPadding = this.document.layout.getPadding(containerNode);\n if (isParentEmpty) {\n // 确保空容器节点不偏移\n return {\n x: 0,\n y: containerPadding.top,\n };\n } else {\n return {\n x: nodePosition.x - containerWorldTransform.tx,\n y: nodePosition.y - containerWorldTransform.ty,\n };\n }\n }\n\n private isContainer(node?: WorkflowNodeEntity): boolean {\n return node?.getNodeMeta<WorkflowNodeMeta>().isContainer ?? false;\n }\n\n /** 判断点是否在矩形内 */\n private isPointInRect(point: PositionSchema, rect: Rectangle): boolean {\n return (\n point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom\n );\n }\n\n /** 判断两个矩形是否相交 */\n private isRectIntersects(rectA: Rectangle, rectB: Rectangle): boolean {\n // 检查水平方向是否有重叠\n const hasHorizontalOverlap = rectA.right > rectB.left && rectA.left < rectB.right;\n // 检查垂直方向是否有重叠\n const hasVerticalOverlap = rectA.bottom > rectB.top && rectA.top < rectB.bottom;\n // 只有当水平和垂直方向都有重叠时,两个矩形才相交\n return hasHorizontalOverlap && hasVerticalOverlap;\n }\n\n private async nextFrame(): Promise<void> {\n await new Promise((resolve) => requestAnimationFrame(resolve));\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator } from '@flowgram.ai/core';\n\nimport type { WorkflowContainerPluginOptions } from './type';\nimport { NodeIntoContainerService } from '.';\n\nexport const createContainerNodePlugin = definePluginCreator<WorkflowContainerPluginOptions>({\n onBind: ({ bind }) => {\n bind(NodeIntoContainerService).toSelf().inSingletonScope();\n },\n onInit(ctx, options) {\n ctx.get(NodeIntoContainerService).init();\n },\n onReady(ctx, options) {\n if (options.disableNodeIntoContainer !== true) {\n ctx.get(NodeIntoContainerService).ready();\n }\n },\n onDispose(ctx) {\n ctx.get(NodeIntoContainerService).dispose();\n },\n});\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useState, useEffect } from 'react';\n\nimport {\n useCurrentEntity,\n WorkflowNodeMeta,\n WorkflowNodePortsData,\n} from '@flowgram.ai/free-layout-core';\nimport { FlowNodeTransformData } from '@flowgram.ai/document';\n\nexport interface NodeSize {\n width: number;\n height: number;\n}\n\nexport const useNodeSize = (): NodeSize | undefined => {\n const node = useCurrentEntity();\n const nodeMeta = node.getNodeMeta<WorkflowNodeMeta>();\n const { size = { width: 300, height: 200 }, isContainer } = nodeMeta;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const [width, setWidth] = useState(size.width);\n const [height, setHeight] = useState(size.height);\n\n const updatePorts = () => {\n const portsData = node.getData<WorkflowNodePortsData>(WorkflowNodePortsData);\n portsData.updateDynamicPorts();\n };\n\n const updateSize = () => {\n // 无子节点时\n if (node.blocks.length === 0) {\n setWidth(size.width);\n setHeight(size.height);\n return;\n }\n // 存在子节点时,只监听宽高变化\n setWidth(transform.bounds.width);\n setHeight(transform.bounds.height);\n };\n\n useEffect(() => {\n const dispose = transform.onDataChange(() => {\n updateSize();\n updatePorts();\n });\n return () => dispose.dispose();\n }, [transform, width, height]);\n\n useEffect(() => {\n // 初始化触发一次\n updateSize();\n }, []);\n\n if (!isContainer) {\n return;\n }\n\n return {\n width,\n height,\n };\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useLayoutEffect } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\n\nimport { NodeSize } from './use-node-size';\n\nexport const useSyncNodeRenderSize = (nodeSize?: NodeSize) => {\n const node = useCurrentEntity();\n\n useLayoutEffect(() => {\n if (!nodeSize) {\n return;\n }\n node.renderData.node.style.width = nodeSize.width + 'px';\n node.renderData.node.style.height = nodeSize.height + 'px';\n }, [nodeSize?.width, nodeSize?.height]);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { type FC } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\nimport { BackgroundConfig, BackgroundLayerOptions } from '@flowgram.ai/background-plugin';\n\nimport { SubCanvasBackgroundStyle } from './style';\n\nexport const SubCanvasBackground: FC = () => {\n const node = useCurrentEntity();\n\n // 通过 inversify 获取背景配置,如果没有配置则使用默认值\n let backgroundConfig: BackgroundLayerOptions = {};\n try {\n backgroundConfig = useService<BackgroundLayerOptions>(BackgroundConfig);\n } catch (error) {\n // 如果 BackgroundConfig 没有注册,使用默认配置\n // 静默处理,使用默认配置\n }\n\n // 获取配置值,如果没有则使用默认值\n const gridSize = backgroundConfig.gridSize ?? 20;\n const dotSize = backgroundConfig.dotSize ?? 1;\n const dotColor = backgroundConfig.dotColor ?? '#eceeef';\n const dotOpacity = backgroundConfig.dotOpacity ?? 0.5;\n const backgroundColor = backgroundConfig.backgroundColor ?? '#f2f3f5';\n // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性\n const dotFillColor =\n backgroundConfig.dotFillColor === dotColor ? '' : backgroundConfig.dotFillColor;\n\n // 生成唯一的 pattern ID\n const patternId = `sub-canvas-dot-pattern-${node.id}`;\n\n return (\n <SubCanvasBackgroundStyle\n className=\"sub-canvas-background\"\n data-flow-editor-selectable=\"true\"\n style={{ backgroundColor: backgroundColor }}\n >\n <svg width=\"100%\" height=\"100%\">\n <pattern id={patternId} width={gridSize} height={gridSize} patternUnits=\"userSpaceOnUse\">\n <circle\n cx={dotSize}\n cy={dotSize}\n r={dotSize}\n stroke={dotColor}\n fill={dotFillColor}\n fillOpacity={dotOpacity}\n />\n </pattern>\n <rect\n width=\"100%\"\n height=\"100%\"\n fill={`url(#${patternId})`}\n data-node-panel-container={node.id}\n />\n </svg>\n </SubCanvasBackgroundStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasBackgroundStyle = styled.div`\n width: 100%;\n height: 100%;\n inset: 56px 18px 18px;\n /* 背景色现在通过 style 属性动态设置 */\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { CSSProperties, ReactNode, type FC } from 'react';\n\nimport { SubCanvasBorderStyle } from './style';\n\ninterface ISubCanvasBorder {\n style?: CSSProperties;\n children?: ReactNode | ReactNode[];\n}\n\nexport const SubCanvasBorder: FC<ISubCanvasBorder> = ({ style, children }) => (\n <SubCanvasBorderStyle\n className=\"sub-canvas-border\"\n style={{\n ...style,\n }}\n >\n {children}\n </SubCanvasBorderStyle>\n);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasBorderStyle = styled.div`\n pointer-events: none;\n\n position: relative;\n\n display: flex;\n align-items: center;\n\n width: 100%;\n height: 100%;\n\n background-color: transparent;\n border: 1px solid var(--coz-stroke-plus, rgba(6, 7, 9, 15%));\n border-color: var(--coz-bg-plus, rgb(249, 249, 249));\n border-style: solid;\n border-width: 8px;\n border-radius: 8px;\n\n &::before {\n content: '';\n\n position: absolute;\n z-index: 0;\n inset: -4px;\n\n background-color: transparent;\n border-color: var(--coz-bg-plus, rgb(249, 249, 249));\n border-style: solid;\n border-width: 4px;\n border-radius: 8px;\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { CSSProperties, type FC } from 'react';\n\nimport { SubCanvasRenderStyle } from './style';\nimport { SubCanvasTips } from '../tips';\nimport { SubCanvasBorder } from '../border';\nimport { SubCanvasBackground } from '../background';\nimport { useNodeSize, useSyncNodeRenderSize } from '../../hooks';\n\ninterface ISubCanvasRender {\n offsetY?: number;\n className?: string;\n style?: CSSProperties;\n tipText?: string | React.ReactNode;\n}\n\nexport const SubCanvasRender: FC<ISubCanvasRender> = ({\n className,\n style,\n offsetY = 0,\n tipText,\n}) => {\n const nodeSize = useNodeSize();\n const nodeHeight = nodeSize?.height ?? 0;\n\n useSyncNodeRenderSize(nodeSize);\n\n return (\n <SubCanvasRenderStyle\n className={`sub-canvas-render ${className ?? ''}`}\n style={{\n height: nodeHeight + offsetY,\n ...style,\n }}\n data-flow-editor-selectable=\"true\"\n onDragStart={(e) => {\n e.stopPropagation();\n }}\n >\n <SubCanvasBorder>\n <SubCanvasBackground />\n <SubCanvasTips tipText={tipText} />\n </SubCanvasBorder>\n </SubCanvasRenderStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasRenderStyle = styled.div`\n width: 100%;\n height: 100%;\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { I18n } from '@flowgram.ai/i18n';\n\nimport { useControlTips } from './use-control';\nimport { SubCanvasTipsStyle } from './style';\nimport { isMacOS } from './is-mac-os';\nimport { IconClose } from './icon-close';\n\ninterface SubCanvasTipsProps {\n tipText?: string | React.ReactNode;\n neverRemindText?: string | React.ReactNode;\n}\n\nexport const SubCanvasTips = ({ tipText, neverRemindText }: SubCanvasTipsProps) => {\n const { visible, close, closeForever } = useControlTips();\n\n const displayContent =\n tipText || I18n.t('Hold {{key}} to drag node out', { key: isMacOS ? 'Cmd ⌘' : 'Ctrl' });\n\n if (!visible) {\n return null;\n }\n return (\n <SubCanvasTipsStyle className={'sub-canvas-tips'}>\n <div className=\"container\">\n <div className=\"content\">\n {typeof displayContent === 'string' ? (\n <p className=\"text\">{displayContent}</p>\n ) : (\n <div className=\"custom-content\">{displayContent}</div>\n )}\n <div\n className=\"space\"\n style={{\n width: 0,\n }}\n />\n </div>\n <div className=\"actions\">\n <p className=\"close-forever\" onClick={closeForever}>\n {neverRemindText || I18n.t('Never Remind')}\n </p>\n <div className=\"close\" onClick={close}>\n <IconClose />\n </div>\n </div>\n </div>\n </SubCanvasTipsStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { NodeIntoContainerService, NodeIntoContainerType } from '../../../node-into-container';\nimport { TipsGlobalStore } from './global-store';\n\nexport const useControlTips = () => {\n const node = useCurrentEntity();\n const [visible, setVisible] = useState(false);\n const globalStore = TipsGlobalStore.instance;\n\n const nodeIntoContainerService = useService<NodeIntoContainerService>(NodeIntoContainerService);\n\n const show = useCallback(() => {\n if (globalStore.isClosed()) {\n return;\n }\n\n setVisible(true);\n }, [globalStore]);\n\n const close = useCallback(() => {\n globalStore.close();\n setVisible(false);\n }, [globalStore]);\n\n const closeForever = useCallback(() => {\n globalStore.closeForever();\n close();\n }, [close, globalStore]);\n\n useEffect(() => {\n // 监听移入\n const inDisposer = nodeIntoContainerService.on((e) => {\n if (e.type !== NodeIntoContainerType.In) {\n return;\n }\n if (e.targetContainer === node) {\n show();\n }\n });\n // 监听移出事件\n const outDisposer = nodeIntoContainerService.on((e) => {\n if (e.type !== NodeIntoContainerType.Out) {\n return;\n }\n if (e.sourceContainer === node && !node.blocks.length) {\n setVisible(false);\n }\n });\n return () => {\n inDisposer.dispose();\n outDisposer.dispose();\n };\n }, [nodeIntoContainerService, node, show, close, visible]);\n\n return {\n visible,\n close,\n closeForever,\n };\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/* eslint-disable @typescript-eslint/naming-convention -- no need */\n\nconst STORAGE_KEY = 'workflow-move-into-sub-canvas-tip-visible';\nconst STORAGE_VALUE = 'false';\n\nexport class TipsGlobalStore {\n private static _instance?: TipsGlobalStore;\n\n public static get instance(): TipsGlobalStore {\n if (!this._instance) {\n this._instance = new TipsGlobalStore();\n }\n return this._instance;\n }\n\n private closed = false;\n\n public isClosed(): boolean {\n return this.isCloseForever() || this.closed;\n }\n\n public close(): void {\n this.closed = true;\n }\n\n public isCloseForever(): boolean {\n return localStorage.getItem(STORAGE_KEY) === STORAGE_VALUE;\n }\n\n public closeForever(): void {\n localStorage.setItem(STORAGE_KEY, STORAGE_VALUE);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasTipsStyle = styled.div`\n pointer-events: auto;\n position: absolute;\n top: 0;\n\n width: 100%;\n height: 28px;\n\n .container {\n height: 100%;\n background-color: #e4e6f5;\n border-radius: 4px 4px 0 0;\n\n .content {\n overflow: hidden;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n width: 100%;\n height: 100%;\n\n .text {\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n line-height: 20px;\n color: rgba(15, 21, 40, 82%);\n text-overflow: ellipsis;\n }\n\n .custom-content {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n\n /* 为自定义内容提供默认样式,但允许覆盖 */\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n color: rgba(15, 21, 40, 82%);\n\n /* 确保自定义内容不会超出容器 */\n overflow: hidden;\n }\n\n .space {\n width: 128px;\n }\n }\n\n .actions {\n position: absolute;\n top: 0;\n right: 0;\n\n display: flex;\n gap: 8px;\n align-items: center;\n\n height: 28px;\n padding: 0 16px;\n\n .close-forever {\n cursor: pointer;\n\n padding: 0 3px;\n\n font-size: 12px;\n font-weight: 400;\n font-style: normal;\n line-height: 12px;\n color: rgba(32, 41, 69, 62%);\n }\n\n .close {\n display: flex;\n cursor: pointer;\n height: 100%;\n align-items: center;\n }\n }\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport const isMacOS = /(Macintosh|MacIntel|MacPPC|Mac68K|iPad)/.test(navigator.userAgent);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nexport const IconClose = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path\n fill=\"#060709\"\n fillOpacity=\"0.5\"\n d=\"M12.13 12.128a.5.5 0 0 0 .001-.706L8.71 8l3.422-3.423a.5.5 0 0 0-.001-.705.5.5 0 0 0-.706-.002L8.002 7.293 4.579 3.87a.5.5 0 0 0-.705.002.5.5 0 0 0-.002.705L7.295 8l-3.423 3.422a.5.5 0 0 0 .002.706c.195.195.51.197.705.001l3.423-3.422 3.422 3.422c.196.196.51.194.706-.001\"\n ></path>\n </svg>\n);\n"],"mappings":"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","names":["NodeIntoContainerType","renderData","renderDom","FlowNodeTransformData","useCurrentEntity","useCurrentEntity","useCurrentEntity","React","styled","React","React","styled","React","useEffect","useState","useCurrentEntity","useService","useCurrentEntity","useState","useService","useEffect","styled","React","React","React"]}
1
+ {"version":3,"sources":["../../src/node-into-container/constant.ts","../../src/node-into-container/service.ts","../../src/utils/next-frame.ts","../../src/utils/is-container.ts","../../src/utils/get-container-transforms.ts","../../src/utils/get-collision-transform.ts","../../src/utils/is-rect-intersects.ts","../../src/utils/is-point-in-rect.ts","../../src/utils/adjust-sub-node-position.ts","../../src/utils/index.ts","../../src/node-into-container/plugin.tsx","../../src/sub-canvas/hooks/use-node-size.ts","../../src/sub-canvas/hooks/use-sync-node-render-size.ts","../../src/sub-canvas/components/background/index.tsx","../../src/sub-canvas/components/background/style.ts","../../src/sub-canvas/components/border/index.tsx","../../src/sub-canvas/components/border/style.ts","../../src/sub-canvas/components/render/index.tsx","../../src/sub-canvas/components/render/style.ts","../../src/sub-canvas/components/tips/index.tsx","../../src/sub-canvas/components/tips/use-control.ts","../../src/sub-canvas/components/tips/global-store.ts","../../src/sub-canvas/components/tips/style.ts","../../src/sub-canvas/components/tips/is-mac-os.ts","../../src/sub-canvas/components/tips/icon-close.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport enum NodeIntoContainerType {\n In = 'in',\n Out = 'out',\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion -- no need */\nimport { throttle } from 'lodash';\nimport { inject, injectable } from 'inversify';\nimport { type Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport {\n type NodesDragEvent,\n WorkflowDocument,\n WorkflowDragService,\n WorkflowLinesManager,\n type WorkflowNodeEntity,\n WorkflowNodeMeta,\n WorkflowOperationBaseService,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { HistoryService } from '@flowgram.ai/free-history-plugin';\nimport { FlowNodeRenderData, FlowNodeBaseType } from '@flowgram.ai/document';\nimport { PlaygroundConfigEntity, TransformData } from '@flowgram.ai/core';\n\nimport type { NodeIntoContainerEvent, NodeIntoContainerState } from './type';\nimport { NodeIntoContainerType } from './constant';\nimport { ContainerUtils } from '../utils';\n\n@injectable()\nexport class NodeIntoContainerService {\n public state: NodeIntoContainerState;\n\n @inject(WorkflowDragService)\n private dragService: WorkflowDragService;\n\n @inject(WorkflowDocument)\n private document: WorkflowDocument;\n\n @inject(PlaygroundConfigEntity)\n private playgroundConfig: PlaygroundConfigEntity;\n\n @inject(WorkflowOperationBaseService)\n private operationService: WorkflowOperationBaseService;\n\n @inject(WorkflowLinesManager)\n private linesManager: WorkflowLinesManager;\n\n @inject(HistoryService) private historyService: HistoryService;\n\n @inject(WorkflowSelectService) private selectService: WorkflowSelectService;\n\n private emitter = new Emitter<NodeIntoContainerEvent>();\n\n private toDispose = new DisposableCollection();\n\n public readonly on = this.emitter.event;\n\n public init(): void {\n this.initState();\n this.toDispose.push(this.emitter);\n }\n\n public ready(): void {\n this.toDispose.push(this.listenDragToContainer());\n }\n\n public dispose(): void {\n this.initState();\n this.toDispose.dispose();\n }\n\n /** 将节点移出容器 */\n public async moveOutContainer(params: { node: WorkflowNodeEntity }): Promise<void> {\n const { node } = params;\n const parentNode = node.parent;\n const containerNode = parentNode?.parent;\n const nodeJSON = this.document.toNodeJSON(node);\n if (\n !parentNode ||\n !containerNode ||\n !ContainerUtils.isContainer(parentNode) ||\n !nodeJSON.meta?.position\n ) {\n return;\n }\n const parentTransform = parentNode.getData<TransformData>(TransformData);\n this.operationService.moveNode(node, {\n parent: containerNode,\n });\n await ContainerUtils.nextFrame();\n parentTransform.fireChange();\n this.operationService.updateNodePosition(node, {\n x: parentTransform.position.x + nodeJSON.meta!.position!.x,\n y: parentTransform.position.y + nodeJSON.meta!.position!.y,\n });\n this.emitter.fire({\n type: NodeIntoContainerType.Out,\n node,\n sourceContainer: parentNode,\n targetContainer: containerNode,\n });\n }\n\n /** 能否将节点移出容器 */\n public canMoveOutContainer(node: WorkflowNodeEntity): boolean {\n const parentNode = node.parent;\n const containerNode = parentNode?.parent;\n if (!parentNode || !containerNode || !ContainerUtils.isContainer(parentNode)) {\n return false;\n }\n const canDrop = this.dragService.canDropToNode({\n dragNodeType: node.flowNodeType,\n dragNode: node,\n dropNodeType: containerNode?.flowNodeType,\n dropNode: containerNode,\n });\n if (!canDrop.allowDrop) {\n return false;\n }\n return true;\n }\n\n /** 移除节点所有非法连线 */\n public async clearInvalidLines(params: {\n dragNode?: WorkflowNodeEntity;\n sourceParent?: WorkflowNodeEntity;\n }): Promise<void> {\n const { dragNode, sourceParent } = params;\n if (!dragNode) {\n return;\n }\n if (dragNode.parent === sourceParent) {\n // 容器节点未改变\n return;\n }\n if (\n dragNode.parent?.flowNodeType === FlowNodeBaseType.GROUP ||\n sourceParent?.flowNodeType === FlowNodeBaseType.GROUP\n ) {\n // 移入移出 group 节点无需删除节点\n return;\n }\n await this.removeNodeLines(dragNode);\n }\n\n /** 移除节点连线 */\n public async removeNodeLines(node: WorkflowNodeEntity): Promise<void> {\n const lines = this.linesManager.getAllLines();\n lines.forEach((line) => {\n if (line.from.id !== node.id && line.to?.id !== node.id) {\n return;\n }\n line.dispose();\n });\n await ContainerUtils.nextFrame();\n }\n\n /** 初始化状态 */\n private initState(): void {\n this.state = {\n isDraggingNode: false,\n isSkipEvent: false,\n transforms: undefined,\n dragNode: undefined,\n dropNode: undefined,\n sourceParent: undefined,\n };\n }\n\n /** 监听节点拖拽 */\n private listenDragToContainer(): Disposable {\n const draggingNode = (e: NodesDragEvent) => this.draggingNode(e);\n const throttledDraggingNode = throttle(draggingNode, 200); // 200ms触发一次计算\n return this.dragService.onNodesDrag(async (event) => {\n if (this.selectService.selectedNodes.length !== 1) {\n return;\n }\n if (event.type === 'onDragStart') {\n if (this.state.isSkipEvent) {\n // 拖出容器后重新进入\n this.state.isSkipEvent = false;\n return;\n }\n this.historyService.startTransaction(); // 开始合并历史记录\n this.state.isDraggingNode = true;\n this.state.transforms = ContainerUtils.getContainerTransforms(this.document.getAllNodes());\n this.state.dragNode = this.selectService.selectedNodes[0];\n this.state.dropNode = undefined;\n this.state.sourceParent = this.state.dragNode?.parent;\n await this.dragOutContainer(event); // 检查是否需拖出容器\n }\n if (event.type === 'onDragging') {\n throttledDraggingNode(event);\n }\n if (event.type === 'onDragEnd') {\n if (this.state.isSkipEvent) {\n // 拖出容器情况下需跳过本次事件\n return;\n }\n throttledDraggingNode.cancel();\n draggingNode(event); // 直接触发一次计算,防止延迟\n await this.dropNodeToContainer(); // 放置节点\n await this.clearInvalidLines({\n dragNode: this.state.dragNode,\n sourceParent: this.state.sourceParent,\n }); // 清除非法线条\n this.setDropNode(undefined);\n this.initState(); // 重置状态\n this.historyService.endTransaction(); // 结束合并历史记录\n }\n });\n }\n\n /** 监听节点拖拽出容器 */\n private async dragOutContainer(event: NodesDragEvent): Promise<void> {\n const { dragNode } = this.state;\n const activated = event.triggerEvent.metaKey || event.triggerEvent.ctrlKey;\n if (\n !activated || // 必须按住指定按键\n !dragNode || // 必须有一个节点\n !this.canMoveOutContainer(dragNode) // 需要能被移出容器\n ) {\n return;\n }\n this.moveOutContainer({ node: dragNode });\n this.state.isSkipEvent = true;\n event.dragger.stop(event.dragEvent.clientX, event.dragEvent.clientY);\n await ContainerUtils.nextFrame();\n this.dragService.startDragSelectedNodes(event.triggerEvent);\n }\n\n /** 设置放置节点高亮 */\n private setDropNode(dropNode?: WorkflowNodeEntity) {\n if (this.state.dropNode === dropNode) {\n return;\n }\n if (this.state.dropNode) {\n // 清除上一个节点高亮\n const renderData = this.state.dropNode.getData(FlowNodeRenderData);\n const renderDom = renderData.node?.children?.[0] as HTMLElement;\n if (renderDom) {\n renderDom.classList.remove('selected');\n }\n }\n this.state.dropNode = dropNode;\n if (!dropNode) {\n return;\n }\n // 设置当前节点高亮\n const renderData = dropNode.getData(FlowNodeRenderData);\n const renderDom = renderData.node?.children?.[0] as HTMLElement;\n if (renderDom) {\n renderDom.classList.add('selected');\n }\n }\n\n /** 放置节点到容器 */\n private async dropNodeToContainer(): Promise<void> {\n const { dropNode, dragNode, isDraggingNode } = this.state;\n if (!isDraggingNode || !dragNode || !dropNode) {\n return;\n }\n return await this.moveIntoContainer({\n node: dragNode,\n containerNode: dropNode,\n });\n }\n\n /** 拖拽节点 */\n private draggingNode(nodeDragEvent: NodesDragEvent): void {\n const { dragNode, isDraggingNode, transforms = [] } = this.state;\n if (!isDraggingNode || !dragNode || !transforms?.length) {\n return this.setDropNode(undefined);\n }\n const mousePos = this.playgroundConfig.getPosFromMouseEvent(nodeDragEvent.dragEvent);\n const availableTransforms = transforms.filter(\n (transform) => transform.entity.id !== dragNode.id\n );\n const collisionTransform = ContainerUtils.getCollisionTransform({\n targetPoint: mousePos,\n transforms: availableTransforms,\n document: this.document,\n });\n const dropNode = collisionTransform?.entity;\n const canDrop = this.canDropToContainer({\n dragNode,\n dropNode,\n });\n if (!canDrop) {\n return this.setDropNode(undefined);\n }\n return this.setDropNode(dropNode);\n }\n\n /** 判断能否将节点拖入容器 */\n protected canDropToContainer(params: {\n dragNode: WorkflowNodeEntity;\n dropNode?: WorkflowNodeEntity;\n }): boolean {\n const { dragNode, dropNode } = params;\n const isDropContainer = dropNode?.getNodeMeta<WorkflowNodeMeta>().isContainer;\n if (!dropNode || !isDropContainer || this.isParent(dragNode, dropNode)) {\n return false;\n }\n if (\n dragNode.flowNodeType === FlowNodeBaseType.GROUP &&\n dropNode.flowNodeType !== FlowNodeBaseType.GROUP\n ) {\n // 禁止将 group 节点拖入非 group 节点(由于目前不支持多节点拖入容器,无法计算有效线条,因此进行屏蔽)\n return false;\n }\n const canDrop = this.dragService.canDropToNode({\n dragNodeType: dragNode.flowNodeType,\n dropNodeType: dropNode?.flowNodeType,\n dragNode,\n dropNode,\n });\n if (!canDrop.allowDrop) {\n return false;\n }\n return true;\n }\n\n /** 判断一个节点是否为另一个节点的父节点(向上查找直到根节点) */\n private isParent(node: WorkflowNodeEntity, parent: WorkflowNodeEntity): boolean {\n let current = node.parent;\n while (current) {\n if (current.id === parent.id) {\n return true;\n }\n current = current.parent;\n }\n return false;\n }\n\n /** 将节点移入容器 */\n private async moveIntoContainer(params: {\n node: WorkflowNodeEntity;\n containerNode: WorkflowNodeEntity;\n }): Promise<void> {\n const { node, containerNode } = params;\n const parentNode = node.parent;\n\n this.operationService.moveNode(node, {\n parent: containerNode,\n });\n\n const containerPadding = this.document.layout.getPadding(containerNode);\n const position = ContainerUtils.adjustSubNodePosition({\n targetNode: node,\n containerNode,\n containerPadding,\n });\n\n this.operationService.updateNodePosition(node, position);\n\n await ContainerUtils.nextFrame();\n\n this.emitter.fire({\n type: NodeIntoContainerType.In,\n node,\n sourceContainer: parentNode,\n targetContainer: containerNode,\n });\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport const nextFrame = async (): Promise<void> => {\n await new Promise((resolve) => requestAnimationFrame(resolve));\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { WorkflowNodeEntity, WorkflowNodeMeta } from '@flowgram.ai/free-layout-core';\n\nexport const isContainer = (node?: WorkflowNodeEntity): boolean =>\n node?.getNodeMeta<WorkflowNodeMeta>().isContainer ?? false;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { WorkflowNodeEntity } from '@flowgram.ai/free-layout-core';\nimport { FlowNodeTransformData } from '@flowgram.ai/document';\n\nimport { isContainer } from './is-container';\n\n/** 获取容器节点transforms */\nexport const getContainerTransforms = (allNodes: WorkflowNodeEntity[]): FlowNodeTransformData[] =>\n allNodes\n .filter((node) => {\n if (node.originParent) {\n return node.getNodeMeta().selectable && node.originParent.getNodeMeta().selectable;\n }\n return node.getNodeMeta().selectable;\n })\n .filter((node) => isContainer(node))\n .sort((a, b) => {\n const aIndex = a.renderData.stackIndex;\n const bIndex = b.renderData.stackIndex;\n // 确保层级高的节点在前面\n return bIndex - aIndex;\n })\n .map((node) => node.transform);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { PositionSchema, Rectangle } from '@flowgram.ai/utils';\nimport { WorkflowDocument } from '@flowgram.ai/free-layout-core';\nimport { FlowNodeTransformData } from '@flowgram.ai/document';\n\nimport { isRectIntersects } from './is-rect-intersects';\nimport { isPointInRect } from './is-point-in-rect';\n\n/** 获取重叠位置 */\nexport const getCollisionTransform = (params: {\n transforms: FlowNodeTransformData[];\n targetRect?: Rectangle;\n targetPoint?: PositionSchema;\n withPadding?: boolean;\n document: WorkflowDocument;\n}): FlowNodeTransformData | undefined => {\n const { targetRect, targetPoint, transforms, withPadding = false, document } = params;\n const collisionTransform = transforms.find((transform) => {\n const { bounds, entity } = transform;\n const padding = withPadding ? document.layout.getPadding(entity) : { left: 0, right: 0 };\n const transformRect = new Rectangle(\n bounds.x + padding.left + padding.right,\n bounds.y,\n bounds.width,\n bounds.height\n );\n // 检测两个正方形是否相互碰撞\n if (targetRect) {\n return isRectIntersects(targetRect, transformRect);\n }\n if (targetPoint) {\n return isPointInRect(targetPoint, transformRect);\n }\n return false;\n });\n return collisionTransform;\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Rectangle } from '@flowgram.ai/utils';\n\nexport const isRectIntersects = (rectA: Rectangle, rectB: Rectangle): boolean => {\n // 检查水平方向是否有重叠\n const hasHorizontalOverlap = rectA.right > rectB.left && rectA.left < rectB.right;\n // 检查垂直方向是否有重叠\n const hasVerticalOverlap = rectA.bottom > rectB.top && rectA.top < rectB.bottom;\n // 只有当水平和垂直方向都有重叠时,两个矩形才相交\n return hasHorizontalOverlap && hasVerticalOverlap;\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { PositionSchema, Rectangle } from '@flowgram.ai/utils';\n\nexport const isPointInRect = (point: PositionSchema, rect: Rectangle): boolean =>\n point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { IPoint, PaddingSchema } from '@flowgram.ai/utils';\nimport { WorkflowNodeEntity } from '@flowgram.ai/free-layout-core';\nimport { FlowNodeBaseType } from '@flowgram.ai/document';\n\n/**\n * 如果存在容器节点,且传入鼠标坐标,需要用容器的坐标减去传入的鼠标坐标\n */\nexport const adjustSubNodePosition = (params: {\n targetNode: WorkflowNodeEntity;\n containerNode: WorkflowNodeEntity;\n containerPadding: PaddingSchema;\n}): IPoint => {\n const { targetNode, containerNode, containerPadding } = params;\n if (containerNode.flowNodeType === FlowNodeBaseType.ROOT) {\n return targetNode.transform.position;\n }\n const nodeWorldTransform = targetNode.transform.transform.worldTransform;\n const containerWorldTransform = containerNode.transform.transform.worldTransform;\n const nodePosition = {\n x: nodeWorldTransform.tx,\n y: nodeWorldTransform.ty,\n };\n const isParentEmpty = !containerNode.children || containerNode.children.length === 0;\n if (isParentEmpty) {\n // 确保空容器节点不偏移\n return {\n x: 0,\n y: containerPadding.top,\n };\n } else {\n return {\n x: nodePosition.x - containerWorldTransform.tx,\n y: nodePosition.y - containerWorldTransform.ty,\n };\n }\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { nextFrame } from './next-frame';\nimport { isContainer } from './is-container';\nimport { getContainerTransforms } from './get-container-transforms';\nimport { getCollisionTransform } from './get-collision-transform';\nimport { adjustSubNodePosition } from './adjust-sub-node-position';\n\nexport const ContainerUtils = {\n nextFrame,\n isContainer,\n adjustSubNodePosition,\n getContainerTransforms,\n getCollisionTransform,\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator } from '@flowgram.ai/core';\n\nimport type { WorkflowContainerPluginOptions } from './type';\nimport { NodeIntoContainerService } from '.';\n\nexport const createContainerNodePlugin = definePluginCreator<WorkflowContainerPluginOptions>({\n onBind: ({ bind }) => {\n bind(NodeIntoContainerService).toSelf().inSingletonScope();\n },\n onInit(ctx, options) {\n ctx.get(NodeIntoContainerService).init();\n },\n onReady(ctx, options) {\n if (options.disableNodeIntoContainer !== true) {\n ctx.get(NodeIntoContainerService).ready();\n }\n },\n onDispose(ctx) {\n ctx.get(NodeIntoContainerService).dispose();\n },\n});\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useState, useEffect } from 'react';\n\nimport {\n useCurrentEntity,\n WorkflowNodeMeta,\n WorkflowNodePortsData,\n} from '@flowgram.ai/free-layout-core';\nimport { FlowNodeTransformData } from '@flowgram.ai/document';\n\nexport interface NodeSize {\n width: number;\n height: number;\n}\n\nexport const useNodeSize = (): NodeSize | undefined => {\n const node = useCurrentEntity();\n const nodeMeta = node.getNodeMeta<WorkflowNodeMeta>();\n const { size = { width: 300, height: 200 }, isContainer } = nodeMeta;\n\n const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData);\n const [width, setWidth] = useState(size.width);\n const [height, setHeight] = useState(size.height);\n\n const updatePorts = () => {\n const portsData = node.getData<WorkflowNodePortsData>(WorkflowNodePortsData);\n portsData.updateDynamicPorts();\n };\n\n const updateSize = () => {\n // 无子节点时\n if (node.blocks.length === 0) {\n setWidth(size.width);\n setHeight(size.height);\n return;\n }\n // 存在子节点时,只监听宽高变化\n setWidth(transform.bounds.width);\n setHeight(transform.bounds.height);\n };\n\n useEffect(() => {\n const dispose = transform.onDataChange(() => {\n updateSize();\n updatePorts();\n });\n return () => dispose.dispose();\n }, [transform, width, height]);\n\n useEffect(() => {\n // 初始化触发一次\n updateSize();\n }, []);\n\n if (!isContainer) {\n return;\n }\n\n return {\n width,\n height,\n };\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useLayoutEffect } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\n\nimport { NodeSize } from './use-node-size';\n\nexport const useSyncNodeRenderSize = (nodeSize?: NodeSize) => {\n const node = useCurrentEntity();\n\n useLayoutEffect(() => {\n if (!nodeSize) {\n return;\n }\n node.renderData.node.style.width = nodeSize.width + 'px';\n node.renderData.node.style.height = nodeSize.height + 'px';\n }, [nodeSize?.width, nodeSize?.height]);\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { type FC } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\nimport { BackgroundConfig, BackgroundLayerOptions } from '@flowgram.ai/background-plugin';\n\nimport { SubCanvasBackgroundStyle } from './style';\n\nexport const SubCanvasBackground: FC = () => {\n const node = useCurrentEntity();\n\n // 通过 inversify 获取背景配置,如果没有配置则使用默认值\n let backgroundConfig: BackgroundLayerOptions = {};\n try {\n backgroundConfig = useService<BackgroundLayerOptions>(BackgroundConfig);\n } catch (error) {\n // 如果 BackgroundConfig 没有注册,使用默认配置\n // 静默处理,使用默认配置\n }\n\n // 获取配置值,如果没有则使用默认值\n const gridSize = backgroundConfig.gridSize ?? 20;\n const dotSize = backgroundConfig.dotSize ?? 1;\n const dotColor = backgroundConfig.dotColor ?? '#eceeef';\n const dotOpacity = backgroundConfig.dotOpacity ?? 0.5;\n const backgroundColor = backgroundConfig.backgroundColor ?? '#f2f3f5';\n // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性\n const dotFillColor =\n backgroundConfig.dotFillColor === dotColor ? '' : backgroundConfig.dotFillColor;\n\n // 生成唯一的 pattern ID\n const patternId = `sub-canvas-dot-pattern-${node.id}`;\n\n return (\n <SubCanvasBackgroundStyle\n className=\"sub-canvas-background\"\n data-flow-editor-selectable=\"true\"\n style={{ backgroundColor: backgroundColor }}\n >\n <svg width=\"100%\" height=\"100%\">\n <pattern id={patternId} width={gridSize} height={gridSize} patternUnits=\"userSpaceOnUse\">\n <circle\n cx={dotSize}\n cy={dotSize}\n r={dotSize}\n stroke={dotColor}\n fill={dotFillColor}\n fillOpacity={dotOpacity}\n />\n </pattern>\n <rect\n width=\"100%\"\n height=\"100%\"\n fill={`url(#${patternId})`}\n data-node-panel-container={node.id}\n />\n </svg>\n </SubCanvasBackgroundStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasBackgroundStyle = styled.div`\n width: 100%;\n height: 100%;\n inset: 56px 18px 18px;\n /* 背景色现在通过 style 属性动态设置 */\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { CSSProperties, ReactNode, type FC } from 'react';\n\nimport { SubCanvasBorderStyle } from './style';\n\ninterface ISubCanvasBorder {\n style?: CSSProperties;\n children?: ReactNode | ReactNode[];\n}\n\nexport const SubCanvasBorder: FC<ISubCanvasBorder> = ({ style, children }) => (\n <SubCanvasBorderStyle\n className=\"sub-canvas-border\"\n style={{\n ...style,\n }}\n >\n {children}\n </SubCanvasBorderStyle>\n);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasBorderStyle = styled.div`\n pointer-events: none;\n\n position: relative;\n\n display: flex;\n align-items: center;\n\n width: 100%;\n height: 100%;\n\n background-color: transparent;\n border: 1px solid var(--coz-stroke-plus, rgba(6, 7, 9, 15%));\n border-color: var(--coz-bg-plus, rgb(249, 249, 249));\n border-style: solid;\n border-width: 8px;\n border-radius: 8px;\n\n &::before {\n content: '';\n\n position: absolute;\n z-index: 0;\n inset: -4px;\n\n background-color: transparent;\n border-color: var(--coz-bg-plus, rgb(249, 249, 249));\n border-style: solid;\n border-width: 4px;\n border-radius: 8px;\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { CSSProperties, type FC } from 'react';\n\nimport { SubCanvasRenderStyle } from './style';\nimport { SubCanvasTips } from '../tips';\nimport { SubCanvasBorder } from '../border';\nimport { SubCanvasBackground } from '../background';\nimport { useNodeSize, useSyncNodeRenderSize } from '../../hooks';\n\ninterface ISubCanvasRender {\n offsetY?: number;\n className?: string;\n style?: CSSProperties;\n tipText?: string | React.ReactNode;\n}\n\nexport const SubCanvasRender: FC<ISubCanvasRender> = ({\n className,\n style,\n offsetY = 0,\n tipText,\n}) => {\n const nodeSize = useNodeSize();\n const nodeHeight = nodeSize?.height ?? 0;\n\n useSyncNodeRenderSize(nodeSize);\n\n return (\n <SubCanvasRenderStyle\n className={`sub-canvas-render ${className ?? ''}`}\n style={{\n height: nodeHeight + offsetY,\n ...style,\n }}\n data-flow-editor-selectable=\"true\"\n onDragStart={(e) => {\n e.stopPropagation();\n }}\n >\n <SubCanvasBorder>\n <SubCanvasBackground />\n <SubCanvasTips tipText={tipText} />\n </SubCanvasBorder>\n </SubCanvasRenderStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasRenderStyle = styled.div`\n width: 100%;\n height: 100%;\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { I18n } from '@flowgram.ai/i18n';\n\nimport { useControlTips } from './use-control';\nimport { SubCanvasTipsStyle } from './style';\nimport { isMacOS } from './is-mac-os';\nimport { IconClose } from './icon-close';\n\ninterface SubCanvasTipsProps {\n tipText?: string | React.ReactNode;\n neverRemindText?: string | React.ReactNode;\n}\n\nexport const SubCanvasTips = ({ tipText, neverRemindText }: SubCanvasTipsProps) => {\n const { visible, close, closeForever } = useControlTips();\n\n const displayContent =\n tipText || I18n.t('Hold {{key}} to drag node out', { key: isMacOS ? 'Cmd ⌘' : 'Ctrl' });\n\n if (!visible) {\n return null;\n }\n return (\n <SubCanvasTipsStyle className={'sub-canvas-tips'}>\n <div className=\"container\">\n <div className=\"content\">\n {typeof displayContent === 'string' ? (\n <p className=\"text\">{displayContent}</p>\n ) : (\n <div className=\"custom-content\">{displayContent}</div>\n )}\n <div\n className=\"space\"\n style={{\n width: 0,\n }}\n />\n </div>\n <div className=\"actions\">\n <p className=\"close-forever\" onClick={closeForever}>\n {neverRemindText || I18n.t('Never Remind')}\n </p>\n <div className=\"close\" onClick={close}>\n <IconClose />\n </div>\n </div>\n </div>\n </SubCanvasTipsStyle>\n );\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { useCurrentEntity } from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { NodeIntoContainerService, NodeIntoContainerType } from '../../../node-into-container';\nimport { TipsGlobalStore } from './global-store';\n\nexport const useControlTips = () => {\n const node = useCurrentEntity();\n const [visible, setVisible] = useState(false);\n const globalStore = TipsGlobalStore.instance;\n\n const nodeIntoContainerService = useService<NodeIntoContainerService>(NodeIntoContainerService);\n\n const show = useCallback(() => {\n if (globalStore.isClosed()) {\n return;\n }\n\n setVisible(true);\n }, [globalStore]);\n\n const close = useCallback(() => {\n globalStore.close();\n setVisible(false);\n }, [globalStore]);\n\n const closeForever = useCallback(() => {\n globalStore.closeForever();\n close();\n }, [close, globalStore]);\n\n useEffect(() => {\n // 监听移入\n const inDisposer = nodeIntoContainerService.on((e) => {\n if (e.type !== NodeIntoContainerType.In) {\n return;\n }\n if (e.targetContainer === node) {\n show();\n }\n });\n // 监听移出事件\n const outDisposer = nodeIntoContainerService.on((e) => {\n if (e.type !== NodeIntoContainerType.Out) {\n return;\n }\n if (e.sourceContainer === node && !node.blocks.length) {\n setVisible(false);\n }\n });\n return () => {\n inDisposer.dispose();\n outDisposer.dispose();\n };\n }, [nodeIntoContainerService, node, show, close, visible]);\n\n return {\n visible,\n close,\n closeForever,\n };\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/* eslint-disable @typescript-eslint/naming-convention -- no need */\n\nconst STORAGE_KEY = 'workflow-move-into-sub-canvas-tip-visible';\nconst STORAGE_VALUE = 'false';\n\nexport class TipsGlobalStore {\n private static _instance?: TipsGlobalStore;\n\n public static get instance(): TipsGlobalStore {\n if (!this._instance) {\n this._instance = new TipsGlobalStore();\n }\n return this._instance;\n }\n\n private closed = false;\n\n public isClosed(): boolean {\n return this.isCloseForever() || this.closed;\n }\n\n public close(): void {\n this.closed = true;\n }\n\n public isCloseForever(): boolean {\n return localStorage.getItem(STORAGE_KEY) === STORAGE_VALUE;\n }\n\n public closeForever(): void {\n localStorage.setItem(STORAGE_KEY, STORAGE_VALUE);\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\n\nexport const SubCanvasTipsStyle = styled.div`\n pointer-events: auto;\n position: absolute;\n top: 0;\n\n width: 100%;\n height: 28px;\n\n .container {\n height: 100%;\n background-color: #e4e6f5;\n border-radius: 4px 4px 0 0;\n\n .content {\n overflow: hidden;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n width: 100%;\n height: 100%;\n\n .text {\n font-size: 14px;\n font-weight: 400;\n font-style: normal;\n line-height: 20px;\n color: rgba(15, 21, 40, 82%);\n text-overflow: ellipsis;\n }\n\n .custom-content {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n\n /* 为自定义内容提供默认样式,但允许覆盖 */\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n color: rgba(15, 21, 40, 82%);\n\n /* 确保自定义内容不会超出容器 */\n overflow: hidden;\n }\n\n .space {\n width: 128px;\n }\n }\n\n .actions {\n position: absolute;\n top: 0;\n right: 0;\n\n display: flex;\n gap: 8px;\n align-items: center;\n\n height: 28px;\n padding: 0 16px;\n\n .close-forever {\n cursor: pointer;\n\n padding: 0 3px;\n\n font-size: 12px;\n font-weight: 400;\n font-style: normal;\n line-height: 12px;\n color: rgba(32, 41, 69, 62%);\n }\n\n .close {\n display: flex;\n cursor: pointer;\n height: 100%;\n align-items: center;\n }\n }\n }\n`;\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport const isMacOS = /(Macintosh|MacIntel|MacPPC|Mac68K|iPad)/.test(navigator.userAgent);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nexport const IconClose = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path\n fill=\"#060709\"\n fillOpacity=\"0.5\"\n d=\"M12.13 12.128a.5.5 0 0 0 .001-.706L8.71 8l3.422-3.423a.5.5 0 0 0-.001-.705.5.5 0 0 0-.706-.002L8.002 7.293 4.579 3.87a.5.5 0 0 0-.705.002.5.5 0 0 0-.002.705L7.295 8l-3.423 3.422a.5.5 0 0 0 .002.706c.195.195.51.197.705.001l3.423-3.422 3.422 3.422c.196.196.51.194.706-.001\"\n ></path>\n </svg>\n);\n"],"mappings":"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","names":["NodeIntoContainerType","FlowNodeBaseType","FlowNodeBaseType","renderData","renderDom","isContainer","useCurrentEntity","useCurrentEntity","useCurrentEntity","React","styled","React","React","styled","React","useEffect","useState","useCurrentEntity","useService","useCurrentEntity","useState","useService","useEffect","styled","React","React","React"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as _flowgram_ai_utils from '@flowgram.ai/utils';
2
+ import * as _flowgram_ai_free_layout_core from '@flowgram.ai/free-layout-core';
2
3
  import { WorkflowNodeEntity } from '@flowgram.ai/free-layout-core';
4
+ import * as _flowgram_ai_document from '@flowgram.ai/document';
3
5
  import { FlowNodeTransformData } from '@flowgram.ai/document';
4
6
  import * as _flowgram_ai_core from '@flowgram.ai/core';
5
7
  import React, { FC, CSSProperties, ReactNode } from 'react';
@@ -70,12 +72,8 @@ declare class NodeIntoContainerService {
70
72
  private listenDragToContainer;
71
73
  /** 监听节点拖拽出容器 */
72
74
  private dragOutContainer;
73
- /** 获取重叠位置 */
74
- private getCollisionTransform;
75
75
  /** 设置放置节点高亮 */
76
76
  private setDropNode;
77
- /** 获取容器节点transforms */
78
- private getContainerTransforms;
79
77
  /** 放置节点到容器 */
80
78
  private dropNodeToContainer;
81
79
  /** 拖拽节点 */
@@ -89,16 +87,6 @@ declare class NodeIntoContainerService {
89
87
  private isParent;
90
88
  /** 将节点移入容器 */
91
89
  private moveIntoContainer;
92
- /**
93
- * 如果存在容器节点,且传入鼠标坐标,需要用容器的坐标减去传入的鼠标坐标
94
- */
95
- private adjustSubNodePosition;
96
- private isContainer;
97
- /** 判断点是否在矩形内 */
98
- private isPointInRect;
99
- /** 判断两个矩形是否相交 */
100
- private isRectIntersects;
101
- private nextFrame;
102
90
  }
103
91
 
104
92
  declare const createContainerNodePlugin: _flowgram_ai_core.PluginCreator<WorkflowContainerPluginOptions>;
@@ -162,4 +150,26 @@ interface SubCanvasTipsProps {
162
150
  }
163
151
  declare const SubCanvasTips: ({ tipText, neverRemindText }: SubCanvasTipsProps) => React.JSX.Element | null;
164
152
 
165
- export { type NodeIntoContainerEvent, NodeIntoContainerService, type NodeIntoContainerState, NodeIntoContainerType, type NodeSize, SubCanvasBackground, SubCanvasBorder, SubCanvasRender, SubCanvasTips, type WorkflowContainerPluginOptions, createContainerNodePlugin, useNodeSize, useSyncNodeRenderSize };
153
+ /**
154
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
155
+ * SPDX-License-Identifier: MIT
156
+ */
157
+ declare const ContainerUtils: {
158
+ nextFrame: () => Promise<void>;
159
+ isContainer: (node?: _flowgram_ai_free_layout_core.WorkflowNodeEntity) => boolean;
160
+ adjustSubNodePosition: (params: {
161
+ targetNode: _flowgram_ai_free_layout_core.WorkflowNodeEntity;
162
+ containerNode: _flowgram_ai_free_layout_core.WorkflowNodeEntity;
163
+ containerPadding: _flowgram_ai_utils.PaddingSchema;
164
+ }) => _flowgram_ai_utils.IPoint;
165
+ getContainerTransforms: (allNodes: _flowgram_ai_free_layout_core.WorkflowNodeEntity[]) => _flowgram_ai_document.FlowNodeTransformData[];
166
+ getCollisionTransform: (params: {
167
+ transforms: _flowgram_ai_document.FlowNodeTransformData[];
168
+ targetRect?: _flowgram_ai_utils.Rectangle;
169
+ targetPoint?: _flowgram_ai_utils.PositionSchema;
170
+ withPadding?: boolean;
171
+ document: _flowgram_ai_free_layout_core.WorkflowDocument;
172
+ }) => _flowgram_ai_document.FlowNodeTransformData | undefined;
173
+ };
174
+
175
+ export { ContainerUtils, type NodeIntoContainerEvent, NodeIntoContainerService, type NodeIntoContainerState, NodeIntoContainerType, type NodeSize, SubCanvasBackground, SubCanvasBorder, SubCanvasRender, SubCanvasTips, type WorkflowContainerPluginOptions, createContainerNodePlugin, useNodeSize, useSyncNodeRenderSize };