@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,98 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { Point } from '@flowgram-vue/utils';
7
+ import { FlowRendererKey } from '@flowgram-vue/renderer';
8
+ import {
9
+ FlowNodeBaseType,
10
+ type FlowNodeRegistry,
11
+ FlowNodeRenderData,
12
+ FlowTransitionLabelEnum,
13
+ FlowNodeSplitType,
14
+ getDefaultSpacing,
15
+ ConstantKeys,
16
+ } from '@flowgram-vue/document';
17
+
18
+ /**
19
+ * 多输入节点, 只能作为 开始节点
20
+ * - multiInputs:
21
+ * - inlineBlocks
22
+ * - input
23
+ * - input
24
+ */
25
+ export const MultiInputsRegistry: FlowNodeRegistry = {
26
+ type: FlowNodeBaseType.MULTI_INPUTS,
27
+ extend: FlowNodeSplitType.SIMPLE_SPLIT,
28
+ extendChildRegistries: [
29
+ {
30
+ type: FlowNodeBaseType.BLOCK_ICON,
31
+ meta: {
32
+ hidden: true,
33
+ spacing: 0,
34
+ },
35
+ getLines() {
36
+ return [];
37
+ },
38
+ getLabels() {
39
+ return [];
40
+ },
41
+ },
42
+ {
43
+ type: FlowNodeBaseType.INLINE_BLOCKS,
44
+ meta: {
45
+ inlineSpacingPre: 0,
46
+ },
47
+ getLabels(transition) {
48
+ const isVertical = transition.entity.isVertical;
49
+ const currentTransform = transition.transform;
50
+ const spacing = getDefaultSpacing(
51
+ transition.entity,
52
+ ConstantKeys.INLINE_BLOCKS_PADDING_BOTTOM
53
+ );
54
+
55
+ if (currentTransform.collapsed || transition.entity.childrenLength === 0) {
56
+ return [
57
+ {
58
+ type: FlowTransitionLabelEnum.CUSTOM_LABEL,
59
+ renderKey: FlowRendererKey.BRANCH_ADDER,
60
+ offset: Point.move(
61
+ currentTransform.outputPoint,
62
+ isVertical ? { y: spacing } : { x: spacing }
63
+ ),
64
+ props: {
65
+ // 激活状态
66
+ activated: transition.entity.getData(FlowNodeRenderData)!.activated,
67
+ transform: currentTransform,
68
+ // 传给外部使用的 node 信息
69
+ node: currentTransform.originParent?.entity,
70
+ },
71
+ },
72
+ ];
73
+ }
74
+
75
+ return [
76
+ {
77
+ type: FlowTransitionLabelEnum.CUSTOM_LABEL,
78
+ renderKey: FlowRendererKey.BRANCH_ADDER,
79
+ offset: Point.move(
80
+ currentTransform.outputPoint,
81
+ isVertical ? { y: -spacing / 2 } : { x: -spacing / 2 }
82
+ ),
83
+ props: {
84
+ // 激活状态
85
+ activated: transition.entity.getData(FlowNodeRenderData)!.activated,
86
+ transform: currentTransform,
87
+ // 传给外部使用的 node 信息
88
+ node: currentTransform.originParent?.entity,
89
+ },
90
+ },
91
+ ];
92
+ },
93
+ },
94
+ ],
95
+ getLabels() {
96
+ return [];
97
+ },
98
+ };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ FlowLayoutDefault,
8
+ type FlowNodeRegistry,
9
+ FlowNodeSplitType,
10
+ FlowNodeBaseType,
11
+ } from '@flowgram-vue/document';
12
+
13
+ import { DynamicSplitRegistry } from './dynamic-split';
14
+ import { BlockRegistry } from './block';
15
+
16
+ /**
17
+ * 多输出节点
18
+ * - multiOutputs:
19
+ * - blockIcon
20
+ * - inlineBlocks
21
+ * - output or multiOutputs
22
+ * - output or multiOutputs
23
+ */
24
+ export const MultiOuputsRegistry: FlowNodeRegistry = {
25
+ type: FlowNodeBaseType.MULTI_OUTPUTS,
26
+ extend: FlowNodeSplitType.SIMPLE_SPLIT,
27
+ meta: {
28
+ isNodeEnd: true,
29
+ },
30
+ getLines: (transition, layout) => {
31
+ // 嵌套在 mutliOutputs 下边
32
+ if (transition.entity.parent?.flowNodeType === FlowNodeBaseType.INLINE_BLOCKS) {
33
+ return BlockRegistry.getLines!(transition, layout);
34
+ }
35
+ return [];
36
+ },
37
+ getLabels: (transition, layout) => [
38
+ ...DynamicSplitRegistry.getLabels!(transition, layout),
39
+ ...BlockRegistry.getLabels!(transition, layout),
40
+ ],
41
+ getOutputPoint(transform, layout) {
42
+ const isVertical = FlowLayoutDefault.isVertical(layout);
43
+ const lastChildOutput = transform.lastChild?.outputPoint;
44
+
45
+ if (isVertical) {
46
+ return {
47
+ x: lastChildOutput ? lastChildOutput.x : transform.bounds.center.x,
48
+ y: transform.bounds.bottom,
49
+ };
50
+ }
51
+
52
+ return {
53
+ x: transform.bounds.right,
54
+ y: lastChildOutput ? lastChildOutput.y : transform.bounds.center.y,
55
+ };
56
+ },
57
+ extendChildRegistries: [
58
+ {
59
+ type: FlowNodeBaseType.BLOCK_ICON,
60
+ meta: {
61
+ // isNodeEnd: true
62
+ },
63
+ },
64
+ ],
65
+ };
@@ -0,0 +1,18 @@
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
+ * 输出节点, 一般作为 end 节点
10
+ */
11
+ export const OuputRegistry: FlowNodeRegistry = {
12
+ type: FlowNodeBaseType.OUTPUT,
13
+ extend: FlowNodeBaseType.BLOCK,
14
+ meta: {
15
+ hidden: false,
16
+ isNodeEnd: true,
17
+ },
18
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { DEFAULT_SPACING, FlowNodeBaseType, type FlowNodeRegistry } from '@flowgram-vue/document';
7
+
8
+ /**
9
+ * 根节点
10
+ */
11
+ export const RootRegistry: FlowNodeRegistry = {
12
+ type: FlowNodeBaseType.ROOT,
13
+ meta: {
14
+ spacing: DEFAULT_SPACING.NULL,
15
+ hidden: true,
16
+ },
17
+ getInputPoint(transform) {
18
+ return transform.firstChild?.inputPoint || transform.bounds.topCenter;
19
+ },
20
+ getOutputPoint(transform) {
21
+ return transform.lastChild?.outputPoint || transform.bounds.bottomCenter;
22
+ },
23
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ type FlowNodeRegistry,
8
+ FlowNodeSplitType,
9
+ FlowNodeBaseType,
10
+ FlowNodeJSON,
11
+ FlowNodeEntity,
12
+ } from '@flowgram-vue/document';
13
+
14
+ /**
15
+ * - simpleSplit: (最原始的 id)
16
+ * blockIcon
17
+ * inlineBlocks
18
+ * node1
19
+ * node2
20
+ */
21
+ export const SimpleSplitRegistry: FlowNodeRegistry = {
22
+ type: FlowNodeSplitType.SIMPLE_SPLIT,
23
+ extend: FlowNodeSplitType.DYNAMIC_SPLIT,
24
+ onBlockChildCreate(
25
+ originParent: FlowNodeEntity,
26
+ blockData: FlowNodeJSON,
27
+ addedNodes: FlowNodeEntity[] = [] // 新创建的节点都要存在这里
28
+ ) {
29
+ const { document } = originParent;
30
+ const parent = document.getNode(`$inlineBlocks$${originParent.id}`);
31
+ const realBlock = document.addNode(
32
+ {
33
+ ...blockData,
34
+ type: blockData.type || FlowNodeBaseType.BLOCK,
35
+ parent,
36
+ },
37
+ addedNodes
38
+ );
39
+ addedNodes.push(realBlock);
40
+ return realBlock;
41
+ },
42
+ // addChild(node, json, options = {}) {
43
+ // const { index } = options;
44
+ // const document = node.document;
45
+ // return document.addBlock(node, json, undefined, undefined, index);
46
+ // }
47
+ };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowRendererKey } from '@flowgram-vue/renderer';
7
+
8
+ export const RENDER_SLOT_ADDER_KEY: string = FlowRendererKey.SLOT_ADDER;
9
+ export const RENDER_SLOT_LABEL_KEY: string = FlowRendererKey.SLOT_LABEL;
10
+ export const RENDER_SLOT_COLLAPSE_KEY: string = FlowRendererKey.SLOT_COLLAPSE;
11
+
12
+ export const SlotSpacingKey = {
13
+ /**
14
+ * = Next Node - Slot END
15
+ */
16
+ SLOT_SPACING: 'SLOT_SPACING',
17
+
18
+ /**
19
+ * = Slot Start Line - Slot Icon Right
20
+ */
21
+ SLOT_START_DISTANCE: 'SLOT_START_DISTANCE',
22
+
23
+ /**
24
+ * = Slot Radius
25
+ */
26
+ SLOT_RADIUS: 'SLOT_RADIUS',
27
+
28
+ /**
29
+ * = Slot Port - Slot Start
30
+ */
31
+ SLOT_PORT_DISTANCE: 'SLOT_PORT_DISTANCE',
32
+
33
+ /**
34
+ * = Slot Label - Slot Start
35
+ */
36
+ SLOT_LABEL_DISTANCE: 'SLOT_LABEL_DISTANCE',
37
+
38
+ /**
39
+ * = Slot Block - Slot Port
40
+ */
41
+ SLOT_BLOCK_PORT_DISTANCE: 'SLOT_BLOCK_PORT_DISTANCE',
42
+
43
+ /**
44
+ * Vertical Layout: Slot Block - Slot Block
45
+ */
46
+ SLOT_BLOCK_VERTICAL_SPACING: 'SLOT_BLOCK_VERTICAL_SPACING',
47
+ };
48
+
49
+ export const SLOT_START_DISTANCE = 16;
50
+ export const SLOT_PORT_DISTANCE = 100;
51
+ export const SLOT_LABEL_DISTANCE = 32;
52
+ export const SLOT_BLOCK_PORT_DISTANCE = 32.5;
53
+ export const SLOT_RADIUS = 16;
54
+ export const SLOT_SPACING = 32;
55
+ export const SLOT_BLOCK_VERTICAL_SPACING = 32.5;
56
+ export const SLOT_NODE_LAST_SPACING = 10;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { SlotIconRegistry } from './slot-icon';
7
+ export { SlotInlineBlocksRegistry } from './slot-inline-blocks';
8
+ export { SlotBlockRegistry } from './slot-block';
@@ -0,0 +1,229 @@
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 {
8
+ FlowNodeRegistry,
9
+ FlowNodeBaseType,
10
+ FlowTransitionLabelEnum,
11
+ FlowTransitionLineEnum,
12
+ getDefaultSpacing,
13
+ Vertex,
14
+ } from '@flowgram-vue/document';
15
+ import { FlowNodeTransformData } from '@flowgram-vue/document';
16
+
17
+ import { getPortChildInput, getSlotChildLineStartPoint } from '../utils/transition';
18
+ import { SlotNodeType } from '../typings';
19
+ import {
20
+ RENDER_SLOT_ADDER_KEY,
21
+ SlotSpacingKey,
22
+ SLOT_PORT_DISTANCE,
23
+ SLOT_RADIUS,
24
+ SLOT_LABEL_DISTANCE,
25
+ RENDER_SLOT_LABEL_KEY,
26
+ SLOT_BLOCK_VERTICAL_SPACING,
27
+ } from '../constants';
28
+
29
+ export const SlotBlockRegistry: FlowNodeRegistry = {
30
+ type: SlotNodeType.SlotBlock,
31
+ extend: FlowNodeBaseType.BLOCK,
32
+ meta: {
33
+ inlineSpacingAfter: 0,
34
+ inlineSpacingPre: 0,
35
+ spacing: (transform) => {
36
+ // 水平布局没有子节点情况
37
+ if (!transform.entity.isVertical && transform.size.width === 0) {
38
+ return 90;
39
+ }
40
+ return getDefaultSpacing(
41
+ transform.entity,
42
+ SlotSpacingKey.SLOT_BLOCK_VERTICAL_SPACING,
43
+ SLOT_BLOCK_VERTICAL_SPACING
44
+ );
45
+ },
46
+ isInlineBlocks: (node) => !node.isVertical,
47
+ },
48
+ getLines(transition) {
49
+ const icon = transition.transform.parent?.pre;
50
+ const start = getSlotChildLineStartPoint(icon);
51
+ const portPoint = transition.transform.inputPoint;
52
+
53
+ const radius = getDefaultSpacing(
54
+ transition.transform.entity,
55
+ SlotSpacingKey.SLOT_RADIUS,
56
+ SLOT_RADIUS
57
+ );
58
+
59
+ let startPortVertices: Vertex[] = [{ x: start.x, y: portPoint.y }];
60
+
61
+ /**
62
+ * When Radius is not enough, we should use truncate strategy
63
+ * 弧度不够时,采取截断策略
64
+ */
65
+ if (transition.entity.isVertical) {
66
+ const deltaY = Math.abs(portPoint.y - start.y);
67
+ let deltaX = radius;
68
+ let isTruncated = false;
69
+
70
+ if (deltaY < radius * 2) {
71
+ isTruncated = true;
72
+ if (deltaY < radius) {
73
+ // Calculate the x by circle equation
74
+ deltaX = Math.sqrt(radius ** 2 - (radius - deltaY) ** 2);
75
+ }
76
+ }
77
+
78
+ startPortVertices = [
79
+ {
80
+ x: start.x + deltaX,
81
+ y: start.y,
82
+ radiusX: radius,
83
+ radiusY: radius,
84
+ radiusOverflow: 'truncate',
85
+ },
86
+ {
87
+ x: start.x + deltaX,
88
+ y: portPoint.y,
89
+ ...(isTruncated ? { radiusX: 0, radiusY: 0 } : {}),
90
+ },
91
+ ];
92
+ }
93
+
94
+ /**
95
+ * When One Children, we should keep dash array align, so we draw one line directly to child nodes
96
+ * 只有一个子节点时,我们通常需要保证两条虚线是连贯的,因此我们直接合并,绘制一条线连到子节点
97
+ */
98
+ if (transition.transform.children.length === 1) {
99
+ return [
100
+ {
101
+ type: FlowTransitionLineEnum.ROUNDED_LINE,
102
+ from: start,
103
+ to: getPortChildInput(transition.transform.children[0]),
104
+ vertices: startPortVertices,
105
+ style: {
106
+ strokeDasharray: '5 5',
107
+ },
108
+ radius,
109
+ },
110
+ ];
111
+ }
112
+
113
+ return [
114
+ {
115
+ type: FlowTransitionLineEnum.ROUNDED_LINE,
116
+ from: start,
117
+ to: portPoint,
118
+ vertices: startPortVertices,
119
+ style: {
120
+ strokeDasharray: '5 5',
121
+ },
122
+ radius,
123
+ },
124
+ ...transition.transform.children.map((_child) => {
125
+ const childInput = getPortChildInput(_child);
126
+
127
+ return {
128
+ type: FlowTransitionLineEnum.ROUNDED_LINE,
129
+ radius,
130
+ from: portPoint,
131
+ to: childInput,
132
+ vertices: [{ x: portPoint.x, y: childInput.y }],
133
+ style: {
134
+ strokeDasharray: '5 5',
135
+ },
136
+ };
137
+ }),
138
+ ];
139
+ },
140
+ getLabels(transition) {
141
+ const icon = transition.transform.parent?.pre;
142
+ const start = getSlotChildLineStartPoint(icon);
143
+ const portPoint = transition.transform.inputPoint;
144
+
145
+ return [
146
+ {
147
+ type: FlowTransitionLabelEnum.CUSTOM_LABEL,
148
+ renderKey: RENDER_SLOT_ADDER_KEY,
149
+ props: {
150
+ node: transition.entity,
151
+ },
152
+ offset: portPoint,
153
+ },
154
+ {
155
+ type: FlowTransitionLabelEnum.CUSTOM_LABEL,
156
+ renderKey: RENDER_SLOT_LABEL_KEY,
157
+ props: {
158
+ node: transition.entity,
159
+ },
160
+ offset: {
161
+ x:
162
+ start.x +
163
+ getDefaultSpacing(
164
+ transition.entity,
165
+ SlotSpacingKey.SLOT_LABEL_DISTANCE,
166
+ SLOT_LABEL_DISTANCE
167
+ ),
168
+ y: portPoint.y,
169
+ },
170
+ origin: [0, 0.5],
171
+ },
172
+ ];
173
+ },
174
+ getInputPoint(transform) {
175
+ const icon = transform.parent?.pre;
176
+ const start = getSlotChildLineStartPoint(icon);
177
+
178
+ let inputY = transform.bounds.center.y;
179
+ if (transform.children.length) {
180
+ inputY = mean([
181
+ getPortChildInput(transform.firstChild).y,
182
+ getPortChildInput(transform.lastChild).y,
183
+ ]);
184
+ }
185
+
186
+ return {
187
+ x:
188
+ start.x +
189
+ getDefaultSpacing(transform.entity, SlotSpacingKey.SLOT_PORT_DISTANCE, SLOT_PORT_DISTANCE),
190
+ y: inputY,
191
+ };
192
+ },
193
+ getChildDelta(child, layout) {
194
+ const hasChild = !!child.firstChild;
195
+
196
+ if (child.entity.isVertical) {
197
+ // 绑定普通节点时进行重心纠偏
198
+ let deltaX = hasChild ? 0 : -child.originDeltaX;
199
+
200
+ return { x: deltaX, y: 0 };
201
+ }
202
+
203
+ let deltaY = hasChild ? 0 : -child.originDeltaY;
204
+
205
+ const preTransform = child.entity.pre?.getData(FlowNodeTransformData);
206
+ if (preTransform) {
207
+ const { localBounds: preBounds } = preTransform;
208
+
209
+ return {
210
+ x: 0,
211
+ y: preBounds.bottom + 30 + deltaY,
212
+ };
213
+ }
214
+
215
+ return { x: 0, y: deltaY };
216
+ },
217
+ getChildLabels() {
218
+ return [];
219
+ },
220
+ getChildLines() {
221
+ return [];
222
+ },
223
+ getDelta(transform) {
224
+ return {
225
+ x: 0,
226
+ y: 0,
227
+ };
228
+ },
229
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowNodeRegistry, FlowNodeBaseType } from '@flowgram-vue/document';
7
+
8
+ import { drawCollapseLabel, drawCollapseLine } from '../utils/transition';
9
+ import { canSlotDrilldown, insideSlot } from '../utils/node';
10
+
11
+ export const SlotIconRegistry: FlowNodeRegistry = {
12
+ type: FlowNodeBaseType.BLOCK_ICON,
13
+ meta: {
14
+ defaultExpanded: false,
15
+ spacing: 0,
16
+ },
17
+ getLines: (transition) => [
18
+ ...(canSlotDrilldown(transition.entity.parent!) ? drawCollapseLine(transition) : []),
19
+ ],
20
+ getLabels: (transition) => [
21
+ ...(canSlotDrilldown(transition.entity.parent!) ? drawCollapseLabel(transition) : []),
22
+ ],
23
+ getDelta: (transform) => {
24
+ // Slot 节点内部时,重新纠正重心调整产生的偏移
25
+ if (insideSlot(transform.entity.parent)) {
26
+ return transform.entity.isVertical
27
+ ? { x: -transform.originDeltaX, y: 0 }
28
+ : { x: 0, y: -transform.originDeltaY };
29
+ }
30
+ return { x: 0, y: 0 };
31
+ },
32
+ };
@@ -0,0 +1,102 @@
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
+ import { FlowNodeTransformData } from '@flowgram-vue/document';
8
+
9
+ import { SlotNodeType } from '../typings';
10
+ import {
11
+ SlotSpacingKey,
12
+ SLOT_START_DISTANCE,
13
+ SLOT_PORT_DISTANCE,
14
+ SLOT_BLOCK_PORT_DISTANCE,
15
+ } from '../constants';
16
+
17
+ export const SlotInlineBlocksRegistry: FlowNodeRegistry = {
18
+ type: SlotNodeType.SlotInlineBlocks,
19
+ extend: FlowNodeBaseType.BLOCK,
20
+ meta: {
21
+ spacing: 0,
22
+ inlineSpacingPre: 0,
23
+ inlineSpacingAfter: 0,
24
+ isInlineBlocks: (node) => !node.isVertical,
25
+ },
26
+ getLines() {
27
+ return [];
28
+ },
29
+ getLabels() {
30
+ return [];
31
+ },
32
+ getChildDelta(child, layout) {
33
+ if (child.entity.isVertical) {
34
+ return { x: 0, y: 0 };
35
+ }
36
+ const preTransform = child.entity.pre?.getData(FlowNodeTransformData);
37
+ if (preTransform) {
38
+ const { localBounds: preBounds } = preTransform;
39
+
40
+ return {
41
+ x: 0,
42
+ y: preBounds.bottom + 30,
43
+ };
44
+ }
45
+
46
+ return { x: 0, y: 0 };
47
+ },
48
+ /**
49
+ * 控制条件分支居右布局
50
+ */
51
+ getDelta(transform) {
52
+ if (!transform.children.length) {
53
+ return { x: 0, y: 0 };
54
+ }
55
+
56
+ const icon = transform.pre;
57
+ if (!icon) {
58
+ return { x: 0, y: 0 };
59
+ }
60
+
61
+ const startDistance = getDefaultSpacing(
62
+ transform.entity,
63
+ SlotSpacingKey.SLOT_START_DISTANCE,
64
+ SLOT_START_DISTANCE
65
+ );
66
+
67
+ const portDistance = getDefaultSpacing(
68
+ transform.entity,
69
+ SlotSpacingKey.SLOT_PORT_DISTANCE,
70
+ SLOT_PORT_DISTANCE
71
+ );
72
+
73
+ const portBlockDistance = getDefaultSpacing(
74
+ transform.entity,
75
+ SlotSpacingKey.SLOT_BLOCK_PORT_DISTANCE,
76
+ SLOT_BLOCK_PORT_DISTANCE
77
+ );
78
+
79
+ if (!transform.entity.isVertical) {
80
+ const noChildren = transform?.children?.every?.((_port) => !_port.children.length);
81
+ /**
82
+ * 如果没有 children 的时候,不需要有右侧的间距,避免水平布局的时候 Slot 右侧空间过大。
83
+ */
84
+ if (noChildren) {
85
+ return {
86
+ x: portDistance - icon.localBounds.width / 2,
87
+ y: icon.localBounds.bottom + startDistance,
88
+ };
89
+ }
90
+ return {
91
+ x: portDistance + portBlockDistance - icon.localBounds.width / 2,
92
+ y: icon.localBounds.bottom + startDistance,
93
+ };
94
+ }
95
+
96
+ const slotInlineBlockDelta = startDistance + portDistance + portBlockDistance;
97
+ return {
98
+ x: icon.localBounds.right + slotInlineBlockDelta,
99
+ y: -icon.localBounds.height,
100
+ };
101
+ },
102
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { SlotRegistry } from './slot';
7
+ export { SlotBlockRegistry } from './extends';
8
+ export { SlotSpacingKey } from './constants';