@flowgram-vue/fixed-layout-core 0.2.0

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 (54) hide show
  1. package/LICENSE +22 -0
  2. package/dist/index.cjs +2327 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +61 -0
  5. package/dist/index.js +2323 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +56 -0
  8. package/src/activities/block-icon.ts +55 -0
  9. package/src/activities/block-order-icon.ts +64 -0
  10. package/src/activities/block.ts +192 -0
  11. package/src/activities/break.ts +14 -0
  12. package/src/activities/dynamic-split.ts +94 -0
  13. package/src/activities/empty.ts +35 -0
  14. package/src/activities/end.ts +26 -0
  15. package/src/activities/index.ts +24 -0
  16. package/src/activities/inline-blocks.ts +197 -0
  17. package/src/activities/input.ts +152 -0
  18. package/src/activities/loop-extends/constants.ts +25 -0
  19. package/src/activities/loop-extends/index.ts +10 -0
  20. package/src/activities/loop-extends/loop-empty-branch.ts +60 -0
  21. package/src/activities/loop-extends/loop-inline-blocks.ts +140 -0
  22. package/src/activities/loop-extends/loop-left-empty-block.ts +43 -0
  23. package/src/activities/loop-extends/loop-right-empty-block.ts +18 -0
  24. package/src/activities/loop.ts +198 -0
  25. package/src/activities/multi-inputs.ts +98 -0
  26. package/src/activities/multi-outputs.ts +65 -0
  27. package/src/activities/output.ts +18 -0
  28. package/src/activities/root.ts +23 -0
  29. package/src/activities/simple-split.ts +47 -0
  30. package/src/activities/slot/constants.ts +56 -0
  31. package/src/activities/slot/extends/index.ts +8 -0
  32. package/src/activities/slot/extends/slot-block.ts +229 -0
  33. package/src/activities/slot/extends/slot-icon.ts +32 -0
  34. package/src/activities/slot/extends/slot-inline-blocks.ts +102 -0
  35. package/src/activities/slot/index.ts +8 -0
  36. package/src/activities/slot/slot.ts +108 -0
  37. package/src/activities/slot/typings.ts +13 -0
  38. package/src/activities/slot/utils/create.ts +105 -0
  39. package/src/activities/slot/utils/layout.ts +49 -0
  40. package/src/activities/slot/utils/node.ts +38 -0
  41. package/src/activities/slot/utils/transition.ts +222 -0
  42. package/src/activities/start.ts +21 -0
  43. package/src/activities/static-split.ts +29 -0
  44. package/src/activities/try-catch-extends/catch-block.ts +78 -0
  45. package/src/activities/try-catch-extends/catch-inline-blocks.ts +122 -0
  46. package/src/activities/try-catch-extends/constants.ts +27 -0
  47. package/src/activities/try-catch-extends/index.ts +11 -0
  48. package/src/activities/try-catch-extends/main-inline-blocks.ts +147 -0
  49. package/src/activities/try-catch-extends/try-block.ts +26 -0
  50. package/src/activities/try-catch-extends/try-slot.ts +48 -0
  51. package/src/activities/try-catch.ts +176 -0
  52. package/src/fixed-layout-container-module.ts +20 -0
  53. package/src/flow-registers.ts +117 -0
  54. package/src/index.ts +45 -0
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeRegistry, FlowNodeBaseType, getDefaultSpacing } from '@flowgram-vue/document';
7
+
8
+ import {
9
+ drawStraightAdder,
10
+ drawStraightLine,
11
+ getInputPoint,
12
+ getOutputPoint,
13
+ } from './utils/transition';
14
+ import { insideSlot } from './utils/node';
15
+ import { getAllPortsMiddle } from './utils/layout';
16
+ import { createSlotFromJSON } from './utils/create';
17
+ import { SlotInlineBlocksRegistry, SlotIconRegistry } from './extends';
18
+ import {
19
+ SLOT_NODE_LAST_SPACING,
20
+ SLOT_SPACING,
21
+ SLOT_START_DISTANCE,
22
+ SlotSpacingKey,
23
+ } from './constants';
24
+
25
+ export const SlotRegistry: FlowNodeRegistry = {
26
+ type: FlowNodeBaseType.SLOT,
27
+ extend: 'block',
28
+ meta: {
29
+ // Slot 节点内部暂时不允许拖拽
30
+ draggable: (node) => !insideSlot(node),
31
+ hidden: true,
32
+ spacing: (node) => getDefaultSpacing(node.entity, SlotSpacingKey.SLOT_SPACING, SLOT_SPACING),
33
+ padding: (node) => ({
34
+ left: 0,
35
+ right: node.collapsed
36
+ ? getDefaultSpacing(node.entity, SlotSpacingKey.SLOT_START_DISTANCE, SLOT_START_DISTANCE)
37
+ : 0,
38
+ bottom: !insideSlot(node.entity) && node.isLast ? SLOT_NODE_LAST_SPACING : 0,
39
+ top: 0,
40
+ }),
41
+ copyDisable: false,
42
+ defaultExpanded: false,
43
+ },
44
+ /**
45
+ * 业务通常需要重载方法
46
+ */
47
+ onCreate: createSlotFromJSON,
48
+ getLines: (transition) => [
49
+ ...(!insideSlot(transition.entity) ? drawStraightLine(transition) : []),
50
+ ],
51
+ getLabels: (transition) => [
52
+ ...(!insideSlot(transition.entity) ? drawStraightAdder(transition) : []),
53
+ ],
54
+ getInputPoint,
55
+ getOutputPoint,
56
+ onAfterUpdateLocalTransform(transform) {
57
+ const { isVertical } = transform.entity;
58
+
59
+ if (!isVertical) {
60
+ return;
61
+ }
62
+
63
+ const icon = transform.firstChild;
64
+ const inlineBlocks = transform.lastChild;
65
+
66
+ if (!icon || !inlineBlocks) {
67
+ return;
68
+ }
69
+
70
+ const iconSize = icon.localBounds.height;
71
+ const inlineBlocksSize = inlineBlocks.localBounds.height;
72
+
73
+ if (transform.collapsed || !inlineBlocks) {
74
+ return;
75
+ }
76
+
77
+ // 所有 Ports 的中间点
78
+ const portsMiddle = getAllPortsMiddle(inlineBlocks);
79
+
80
+ icon.entity.clearMemoLocal();
81
+ inlineBlocks.entity.clearMemoLocal();
82
+
83
+ if (iconSize / 2 + portsMiddle > inlineBlocksSize || !inlineBlocks.children.length) {
84
+ icon.transform.update({
85
+ position: { x: icon.transform.position.x, y: 0 },
86
+ });
87
+ inlineBlocks.transform.update({
88
+ position: {
89
+ x: inlineBlocks.transform.position.x,
90
+ y: Math.max(iconSize / 2 - inlineBlocksSize / 2, 0),
91
+ },
92
+ });
93
+
94
+ return;
95
+ }
96
+
97
+ inlineBlocks.transform.update({
98
+ position: { x: inlineBlocks.transform.position.x, y: 0 },
99
+ });
100
+ icon?.transform.update({
101
+ position: {
102
+ x: icon.transform.position.x,
103
+ y: Math.max(portsMiddle - iconSize / 2, 0), // 所有 port 的中间点
104
+ },
105
+ });
106
+ },
107
+ extendChildRegistries: [SlotIconRegistry, SlotInlineBlocksRegistry],
108
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeBaseType } from '@flowgram-vue/document';
7
+
8
+ export enum SlotNodeType {
9
+ Slot = FlowNodeBaseType.SLOT,
10
+ SlotBlock = FlowNodeBaseType.SLOT_BLOCK,
11
+ SlotInlineBlocks = 'slotInlineBlocks',
12
+ SlotBlockInlineBlocks = 'slotBlockInlineBlocks',
13
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeBaseType } from '@flowgram-vue/document';
7
+ import { type FlowNodeEntity } from '@flowgram-vue/document';
8
+ import { FlowNodeJSON } from '@flowgram-vue/document';
9
+
10
+ import { SlotNodeType } from '../typings';
11
+
12
+ // Slot 样例数据
13
+ // const mock = {
14
+ // type: 'slot',
15
+ // id: 'reactor_parent',
16
+ // blocks: [
17
+ // {
18
+ // id: 'port_LnSdK',
19
+ // blocks: [{ type: 'Slot', id: 'reactor_child' }],
20
+ // },
21
+ // {
22
+ // id: 'port_60X7U',
23
+ // },
24
+ // {
25
+ // id: 'port_JWhcm',
26
+ // },
27
+ // {
28
+ // id: 'port_scHWa',
29
+ // },
30
+ // ],
31
+ // };
32
+
33
+ /**
34
+ * 创建 Slot 子节点
35
+ * - Slot
36
+ * - SlotBlockIcon
37
+ * - SlotInlineBlocks
38
+ * - SlotBlock 1
39
+ * - SlotBlockIcon 1
40
+ * - ChildSlot 1
41
+ * - ChildSlot 2
42
+ * - SlotBlock 2
43
+ *
44
+ * 范例数据:
45
+ * {
46
+ * type: 'Slot',
47
+ * id: 'reactor_parent',
48
+ * blocks: [
49
+ * {
50
+ * id: 'port_LnSdK',
51
+ * blocks: [{ type: 'Slot', id: 'reactor_child' }],
52
+ * },
53
+ * {
54
+ * id: 'port_60X7U',
55
+ * }
56
+ * ],
57
+ * }
58
+ *
59
+ */
60
+ export const createSlotFromJSON = (node: FlowNodeEntity, json: FlowNodeJSON): FlowNodeEntity[] => {
61
+ const { document } = node;
62
+
63
+ const addedNodes: FlowNodeEntity[] = [];
64
+
65
+ // 块列表开始节点,用来展示块的按钮
66
+ const blockIconNode = document.addNode({
67
+ id: `$slotIcon$${node.id}`,
68
+ type: FlowNodeBaseType.BLOCK_ICON,
69
+ originParent: node,
70
+ parent: node,
71
+ });
72
+ const inlineBlocksNode = document.addNode({
73
+ id: `$slotInlineBlocks$${node.id}`,
74
+ type: SlotNodeType.SlotInlineBlocks,
75
+ originParent: node,
76
+ parent: node,
77
+ });
78
+ addedNodes.push(blockIconNode);
79
+ addedNodes.push(inlineBlocksNode);
80
+
81
+ const portJSONList = json.blocks || [];
82
+
83
+ portJSONList.forEach((_portJSON) => {
84
+ const port = document.addNode({
85
+ type: SlotNodeType.SlotBlock,
86
+ ..._portJSON,
87
+ originParent: node,
88
+ parent: inlineBlocksNode,
89
+ });
90
+ addedNodes.push(port);
91
+
92
+ (_portJSON.blocks || []).forEach((_portChild) => {
93
+ document.addNode(
94
+ {
95
+ type: SlotNodeType.Slot,
96
+ ..._portChild,
97
+ parent: port,
98
+ },
99
+ addedNodes
100
+ );
101
+ });
102
+ });
103
+
104
+ return addedNodes;
105
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { mean } from 'lodash-es';
7
+ import { FlowNodeTransformData } from '@flowgram-vue/document';
8
+
9
+ export const getDisplayFirstChildTop = (transform: FlowNodeTransformData): number => {
10
+ if (transform.firstChild) {
11
+ return transform.localBounds.top + getDisplayFirstChildTop(transform.firstChild);
12
+ }
13
+
14
+ return transform.localBounds.center.y;
15
+ };
16
+
17
+ /**
18
+ * 获取单个 Port 的中间点
19
+ * @param inlineBlocks
20
+ * @returns
21
+ */
22
+ export const getPortMiddle = (_port: FlowNodeTransformData) => {
23
+ if (!_port.children.length) {
24
+ return _port.localBounds.top;
25
+ }
26
+
27
+ const portChildInputs = [_port.firstChild!, _port.lastChild!].map((_portChild) =>
28
+ getDisplayFirstChildTop(_portChild)
29
+ );
30
+
31
+ return _port.localBounds.top + mean(portChildInputs);
32
+ };
33
+
34
+ /**
35
+ * 获取所有 Port 的中间点
36
+ * @param inlineBlocks
37
+ * @returns
38
+ */
39
+ export const getAllPortsMiddle = (inlineBlocks: FlowNodeTransformData) => {
40
+ if (!inlineBlocks.children.length) {
41
+ return inlineBlocks.localBounds.height / 2;
42
+ }
43
+
44
+ const portInputs = [inlineBlocks.firstChild!, inlineBlocks.lastChild!].map((_port) =>
45
+ getPortMiddle(_port)
46
+ );
47
+
48
+ return mean(portInputs);
49
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeEntity } from '@flowgram-vue/document';
7
+ import { FlowNodeTransformData } from '@flowgram-vue/document';
8
+
9
+ import { SlotNodeType } from '../typings';
10
+
11
+ /**
12
+ * Slot 节点是否可下钻,看 inlineBlocks 是否有子节点
13
+ * @param Slot Slot 节点
14
+ */
15
+ export const canSlotDrilldown = (Slot: FlowNodeEntity): boolean =>
16
+ !!Slot?.lastCollapsedChild?.blocks.length;
17
+
18
+ /**
19
+ * 是否是 Slot 内部
20
+ * @param entity
21
+ * @returns
22
+ */
23
+ export const insideSlot = (entity?: FlowNodeEntity): boolean =>
24
+ !!entity?.parent?.isTypeOrExtendType(SlotNodeType.SlotBlock);
25
+
26
+ /**
27
+ * 获取在页面上实际渲染的第一个 Child 节点
28
+ * @param node
29
+ */
30
+ export const getDisplayFirstChildTransform = (
31
+ transform: FlowNodeTransformData
32
+ ): FlowNodeTransformData => {
33
+ if (transform.firstChild) {
34
+ return getDisplayFirstChildTransform(transform.firstChild);
35
+ }
36
+
37
+ return transform;
38
+ };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { IPoint, Point } from '@flowgram-vue/utils';
7
+ import {
8
+ type FlowNodeTransitionData,
9
+ FlowTransitionLineEnum,
10
+ FlowTransitionLabelEnum,
11
+ type FlowNodeTransformData,
12
+ type FlowTransitionLine,
13
+ type FlowTransitionLabel,
14
+ getDefaultSpacing,
15
+ } from '@flowgram-vue/document';
16
+
17
+ import { RENDER_SLOT_COLLAPSE_KEY, SlotSpacingKey, SLOT_START_DISTANCE } from '../constants';
18
+ import { getDisplayFirstChildTransform } from './node';
19
+
20
+ /**
21
+ * 画 Slot 节点虚线起点
22
+ * @param iconTransform blockIcon 的 transform
23
+ * @returns
24
+ */
25
+ export const getSlotChildLineStartPoint = (iconTransform?: FlowNodeTransformData): IPoint => {
26
+ if (!iconTransform) {
27
+ return { x: 0, y: 0 };
28
+ }
29
+
30
+ const startDistance = getDefaultSpacing(
31
+ iconTransform.entity,
32
+ SlotSpacingKey.SLOT_START_DISTANCE,
33
+ SLOT_START_DISTANCE
34
+ );
35
+
36
+ if (!iconTransform.entity.isVertical) {
37
+ return {
38
+ x: iconTransform?.bounds.center.x,
39
+ y: iconTransform?.bounds.bottom + startDistance,
40
+ };
41
+ }
42
+ return {
43
+ x: iconTransform?.bounds.right + startDistance,
44
+ y: iconTransform?.bounds.center.y,
45
+ };
46
+ };
47
+
48
+ export const getOutputPoint = (transform: FlowNodeTransformData): IPoint => {
49
+ const icon = transform.firstChild;
50
+
51
+ if (!icon) {
52
+ return { x: 0, y: 0 };
53
+ }
54
+
55
+ if (!transform.entity.isVertical) {
56
+ return {
57
+ x: transform.bounds.right,
58
+ y: icon.outputPoint.y,
59
+ };
60
+ }
61
+
62
+ return {
63
+ x: icon.outputPoint.x,
64
+ y: transform.bounds.bottom,
65
+ };
66
+ };
67
+
68
+ export const getInputPoint = (transform: FlowNodeTransformData): IPoint => {
69
+ const icon = transform.firstChild;
70
+
71
+ if (!icon) {
72
+ return { x: 0, y: 0 };
73
+ }
74
+
75
+ if (!transform.entity.isVertical) {
76
+ return {
77
+ x: transform.bounds.left,
78
+ y: icon.outputPoint.y,
79
+ };
80
+ }
81
+
82
+ return icon.inputPoint;
83
+ };
84
+
85
+ /**
86
+ * 获取实连线终点
87
+ * @param transition
88
+ * @returns
89
+ */
90
+ export const getTransitionToPoint = (transition: FlowNodeTransitionData): IPoint => {
91
+ let toPoint = transition.transform.next?.inputPoint;
92
+ const icon = transition.transform.firstChild;
93
+
94
+ const parent = transition.transform.parent;
95
+
96
+ if (!icon || !parent) {
97
+ return { x: 0, y: 0 };
98
+ }
99
+
100
+ if (!transition.transform.next) {
101
+ if (!transition.entity.isVertical) {
102
+ toPoint = {
103
+ x: parent.outputPoint.x,
104
+ y: icon.outputPoint.y,
105
+ };
106
+ } else {
107
+ toPoint = {
108
+ x: icon.outputPoint.x,
109
+ y: parent.outputPoint.y,
110
+ };
111
+ }
112
+ }
113
+
114
+ return toPoint || { x: 0, y: 0 };
115
+ };
116
+
117
+ /**
118
+ * 画实现线
119
+ * @param transition Slot 节点的 transition
120
+ * @returns
121
+ */
122
+ export const drawStraightLine = (transition: FlowNodeTransitionData): FlowTransitionLine[] => {
123
+ const icon = transition.transform.firstChild;
124
+ const toPoint = getTransitionToPoint(transition);
125
+
126
+ if (!icon) {
127
+ return [];
128
+ }
129
+
130
+ return [
131
+ {
132
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
133
+ from: icon.outputPoint,
134
+ to: toPoint,
135
+ },
136
+ {
137
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
138
+ from: icon.inputPoint,
139
+ to: transition.transform.inputPoint,
140
+ },
141
+ ];
142
+ };
143
+
144
+ export const drawCollapseLabel = (transition: FlowNodeTransitionData): FlowTransitionLabel[] => {
145
+ const icon = transition.transform;
146
+
147
+ return [
148
+ {
149
+ type: FlowTransitionLabelEnum.CUSTOM_LABEL,
150
+ renderKey: RENDER_SLOT_COLLAPSE_KEY,
151
+ offset: getSlotChildLineStartPoint(icon),
152
+ props: {
153
+ node: transition.entity.parent,
154
+ },
155
+ },
156
+ ];
157
+ };
158
+
159
+ export const drawCollapseLine = (transition: FlowNodeTransitionData): FlowTransitionLine[] => {
160
+ const startDistance = getDefaultSpacing(
161
+ transition.transform.entity,
162
+ SlotSpacingKey.SLOT_START_DISTANCE,
163
+ SLOT_START_DISTANCE
164
+ );
165
+
166
+ return [
167
+ {
168
+ type: FlowTransitionLineEnum.STRAIGHT_LINE,
169
+ from: getSlotChildLineStartPoint(transition.transform),
170
+ to: Point.move(
171
+ getSlotChildLineStartPoint(transition.transform),
172
+ transition.entity.isVertical ? { x: -startDistance, y: 0 } : { x: 0, y: -startDistance }
173
+ ),
174
+ style: {
175
+ strokeDasharray: '5 5',
176
+ },
177
+ },
178
+ ];
179
+ };
180
+
181
+ /**
182
+ * 画实线上的叫号
183
+ * @param transition
184
+ * @returns
185
+ */
186
+ export const drawStraightAdder = (transition: FlowNodeTransitionData): FlowTransitionLabel[] => {
187
+ const toPoint = getTransitionToPoint(transition);
188
+ const fromPoint = transition.transform.firstChild!.outputPoint;
189
+
190
+ const hoverProps = transition.entity.isVertical
191
+ ? {
192
+ hoverHeight: toPoint.y - fromPoint.y,
193
+ hoverWidth: transition.transform.firstChild?.bounds.width,
194
+ }
195
+ : {
196
+ hoverHeight: transition.transform.firstChild?.bounds.height,
197
+ hoverWidth: toPoint.x - fromPoint.x,
198
+ };
199
+
200
+ return [
201
+ {
202
+ offset: Point.getMiddlePoint(fromPoint, toPoint),
203
+ type: FlowTransitionLabelEnum.ADDER_LABEL,
204
+ props: hoverProps,
205
+ },
206
+ ];
207
+ };
208
+
209
+ /**
210
+ * 获取端口的子节点线条输入点
211
+ * @param _child
212
+ * @returns
213
+ */
214
+ export const getPortChildInput = (_child?: FlowNodeTransformData) => {
215
+ if (!_child) {
216
+ return { x: 0, y: 0 };
217
+ }
218
+
219
+ const firstChild = getDisplayFirstChildTransform(_child);
220
+
221
+ return { x: _child.bounds.left, y: firstChild.bounds.center.y };
222
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeBaseType, type FlowNodeRegistry } from '@flowgram-vue/document';
7
+
8
+ /**
9
+ * 开始节点
10
+ */
11
+ export const StartRegistry: FlowNodeRegistry = {
12
+ type: FlowNodeBaseType.START,
13
+ meta: {
14
+ isStart: true,
15
+ draggable: false,
16
+ selectable: false, // 触发器等开始节点不能被框选
17
+ deleteDisable: true, // 禁止删除
18
+ copyDisable: true, // 禁止copy
19
+ addDisable: true, // 禁止添加
20
+ },
21
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeBaseType, type FlowNodeRegistry, FlowNodeSplitType } from '@flowgram-vue/document';
7
+
8
+ /**
9
+ * 不能动态添加分支的分支节点
10
+ * staticSplit: (最原始的 id)
11
+ * blockIcon
12
+ * inlineBlocks
13
+ * block1
14
+ * blockOrderIcon
15
+ * block2
16
+ * blockOrderIcon
17
+ */
18
+ export const StaticSplitRegistry: FlowNodeRegistry = {
19
+ extend: FlowNodeSplitType.DYNAMIC_SPLIT,
20
+ type: FlowNodeSplitType.STATIC_SPLIT,
21
+ extendChildRegistries: [
22
+ {
23
+ type: FlowNodeBaseType.INLINE_BLOCKS,
24
+ getLabels() {
25
+ return [];
26
+ },
27
+ },
28
+ ],
29
+ };
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ DEFAULT_SPACING,
8
+ FlowNodeBaseType,
9
+ type FlowNodeRegistry,
10
+ FlowTransitionLineEnum,
11
+ } from '@flowgram-vue/document';
12
+
13
+ import { TryCatchSpacings, TryCatchTypeEnum } from './constants';
14
+
15
+ /**
16
+ * catch 分支
17
+ */
18
+ export const CatchBlockRegistry: FlowNodeRegistry = {
19
+ extend: FlowNodeBaseType.BLOCK,
20
+ type: TryCatchTypeEnum.CATCH_BLOCK,
21
+ meta: {
22
+ hidden: true,
23
+ spacing: DEFAULT_SPACING.NULL,
24
+ },
25
+ getLines(transition) {
26
+ const { transform } = transition;
27
+ const { isVertical } = transition.entity;
28
+ const parentPoint = transform.parent!;
29
+ const { inputPoint, outputPoint } = transform;
30
+ let parentInputPoint;
31
+ if (isVertical) {
32
+ parentInputPoint = {
33
+ x: parentPoint.inputPoint.x,
34
+ y: parentPoint.inputPoint.y - TryCatchSpacings.CATCH_INLINE_SPACING,
35
+ };
36
+ } else {
37
+ parentInputPoint = {
38
+ x: parentPoint.inputPoint.x - TryCatchSpacings.CATCH_INLINE_SPACING,
39
+ y: parentPoint.inputPoint.y,
40
+ };
41
+ }
42
+
43
+ const lines = [
44
+ {
45
+ type: FlowTransitionLineEnum.DIVERGE_LINE,
46
+ from: parentInputPoint,
47
+ to: inputPoint,
48
+ },
49
+ ];
50
+
51
+ // 最后一个节点是 end 节点,不绘制 mergeLine
52
+ if (!transition.isNodeEnd) {
53
+ let mergePoint;
54
+ if (isVertical) {
55
+ mergePoint = {
56
+ x: parentPoint.outputPoint.x,
57
+ y: parentPoint.bounds.bottom,
58
+ };
59
+ } else {
60
+ mergePoint = {
61
+ x: parentPoint.bounds.right,
62
+ y: parentPoint.outputPoint.y,
63
+ };
64
+ }
65
+
66
+ lines.push({
67
+ type: FlowTransitionLineEnum.MERGE_LINE,
68
+ from: outputPoint,
69
+ to: mergePoint,
70
+ });
71
+ }
72
+
73
+ return lines;
74
+ },
75
+ getLabels() {
76
+ return [];
77
+ },
78
+ };