Kaynağa Gözat

feat(free-layout-demo): loop support collapsed (#694)

* feat(free-layout-demo): loop support collapsed

*  This is a combination of 2 commits.
 This is the 1st commit message:

feat(free-layout-demo): loop support collapsed

 The commit message #2 will be skipped:

  This is a combination of 2 commits.
  This is the 1st commit message:

 feat(free-layout-demo): loop support collapsed

  The commit message #2 will be skipped:

  feat(free-layout-demo): loop support collapsed
xiamidaxia 4 ay önce
ebeveyn
işleme
f2dff3c59c

+ 2 - 1
apps/demo-free-layout/package.json

@@ -12,7 +12,8 @@
     "index.html",
     "package.json",
     "rsbuild.config.ts",
-    "tsconfig.json"
+    "tsconfig.json",
+    "README.md"
   ],
   "scripts": {
     "build": "exit 0",

+ 5 - 0
apps/demo-free-layout/src/form-components/form-header/index.tsx

@@ -9,6 +9,7 @@ import { useClientContext, CommandService } from '@flowgram.ai/free-layout-edito
 import { Button } from '@douyinfe/semi-ui';
 import { IconClose, IconSmallTriangleDown, IconSmallTriangleLeft } from '@douyinfe/semi-icons';
 
+import { toggleLoopExpanded } from '../../utils';
 import { FlowCommandId } from '../../shortcuts';
 import { useIsSidebar, useNodeRenderContext } from '../../hooks';
 import { SidebarContext } from '../../context';
@@ -25,6 +26,10 @@ export function FormHeader() {
   const isSidebar = useIsSidebar();
   const handleExpand = (e: React.MouseEvent) => {
     toggleExpand();
+    // 折叠 loop 子节点
+    if (node.flowNodeType === 'loop') {
+      toggleLoopExpanded(node);
+    }
     e.stopPropagation(); // Disable clicking prevents the sidebar from opening
   };
   const handleDelete = () => {

+ 1 - 1
apps/demo-free-layout/src/nodes/loop/index.ts

@@ -59,7 +59,7 @@ export const LoopNodeRegistry: FlowNodeRegistry = {
       // 鼠标开始时所在位置不包括当前节点时才可选中
       return !transform.bounds.contains(mousePos.x, mousePos.y);
     },
-    expandable: false, // disable expanded
+    // expandable: false, // disable expanded
     wrapperStyle: {
       minWidth: 'unset',
       width: '100%',

+ 1 - 0
apps/demo-free-layout/src/utils/index.ts

@@ -4,3 +4,4 @@
  */
 
 export { onDragLineEnd } from './on-drag-line-end';
+export { toggleLoopExpanded } from './toggle-loop-expanded';

+ 60 - 0
apps/demo-free-layout/src/utils/toggle-loop-expanded.ts

@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+ * SPDX-License-Identifier: MIT
+ */
+
+import { WorkflowNodeEntity, WorkflowNodeLinesData } from '@flowgram.ai/free-layout-editor';
+
+export function toggleLoopExpanded(
+  node: WorkflowNodeEntity,
+  expanded: boolean = node.transform.collapsed,
+  heightCollapsed = 54
+) {
+  const bounds = node.bounds.clone();
+  const prePosition = {
+    x: node.transform.position.x,
+    y: node.transform.position.y,
+  };
+  node.transform.collapsed = !expanded;
+  if (!expanded) {
+    node.transform.transform.update({
+      position: {
+        x: prePosition.x - node.transform.padding.left,
+        y: prePosition.y - node.transform.padding.top,
+      },
+      origin: {
+        x: 0,
+        y: 0,
+      },
+    });
+    setTimeout(() => {
+      // When folded, the width and height no longer change according to the child nodes, and need to be set manually
+      // 折叠起来,宽高不再根据子节点变化,需要手动设置
+      node.transform.size = {
+        width: bounds.width,
+        height: heightCollapsed,
+      };
+    }, 0);
+  } else {
+    node.transform.transform.update({
+      position: {
+        x: prePosition.x + node.transform.padding.left,
+        y: prePosition.y + node.transform.padding.top,
+      },
+      origin: {
+        x: 0,
+        y: 0,
+      },
+    });
+  }
+
+  // 隐藏子节点线条
+  // Hide the child node lines
+  node.blocks.forEach((block) => {
+    block.getData(WorkflowNodeLinesData).allLines.forEach((line) => {
+      line.updateUIState({
+        style: !expanded ? { display: 'none' } : {},
+      });
+    });
+  });
+}