@flowgram.ai/free-lines-plugin 0.1.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.
- package/dist/esm/index.js +613 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +65 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +638 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/components/workflow-port-render/index.tsx
|
|
13
|
+
import ReactDOM from "react-dom";
|
|
14
|
+
import React2, { useEffect, useState } from "react";
|
|
15
|
+
import classNames from "clsx";
|
|
16
|
+
import {
|
|
17
|
+
WorkflowHoverService,
|
|
18
|
+
usePlaygroundReadonlyState,
|
|
19
|
+
WorkflowLinesManager
|
|
20
|
+
} from "@flowgram.ai/free-layout-core";
|
|
21
|
+
import { useService } from "@flowgram.ai/core";
|
|
22
|
+
|
|
23
|
+
// src/constants/points.ts
|
|
24
|
+
var STROKE_WIDTH_SLECTED = 3;
|
|
25
|
+
var STROKE_WIDTH = 2;
|
|
26
|
+
var PORT_BG_CLASS_NAME = "workflow-port-bg";
|
|
27
|
+
|
|
28
|
+
// src/components/workflow-port-render/style.ts
|
|
29
|
+
import styled from "styled-components";
|
|
30
|
+
var WorkflowPointStyle = styled.div`
|
|
31
|
+
width: 20px;
|
|
32
|
+
height: 20px;
|
|
33
|
+
border-radius: 50%;
|
|
34
|
+
margin-top: -10px;
|
|
35
|
+
margin-left: -10px;
|
|
36
|
+
left: 50%;
|
|
37
|
+
top: 50%;
|
|
38
|
+
position: absolute;
|
|
39
|
+
// 非 hover 状态下的样式
|
|
40
|
+
border: none;
|
|
41
|
+
|
|
42
|
+
& > .symbol {
|
|
43
|
+
opacity: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.bg-circle {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
position: absolute;
|
|
51
|
+
border-radius: 50%;
|
|
52
|
+
width: 20px;
|
|
53
|
+
height: 20px;
|
|
54
|
+
background-color: #fff;
|
|
55
|
+
transform: scale(0.5);
|
|
56
|
+
transition: all 0.2s linear 0s;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.bg {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
position: relative;
|
|
64
|
+
width: 100%;
|
|
65
|
+
height: 100%;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
background: #9197F1;
|
|
68
|
+
transform: scale(0.4, 0.4);
|
|
69
|
+
transition: all 0.2s linear 0s;
|
|
70
|
+
|
|
71
|
+
&.hasError {
|
|
72
|
+
background: red;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.symbol {
|
|
76
|
+
position: absolute;
|
|
77
|
+
width: 14px;
|
|
78
|
+
height: 14px;
|
|
79
|
+
opacity: 0;
|
|
80
|
+
pointer-events: none;
|
|
81
|
+
color: #fff;
|
|
82
|
+
transition: opacity 0.2s linear 0s;
|
|
83
|
+
|
|
84
|
+
& > svg {
|
|
85
|
+
width: 14px;
|
|
86
|
+
height: 14px;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.focus-circle {
|
|
91
|
+
position: absolute;
|
|
92
|
+
display: flex;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
align-items: center;
|
|
95
|
+
width: 8px;
|
|
96
|
+
height: 8px;
|
|
97
|
+
opacity: 0;
|
|
98
|
+
background: #9197f1;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
transition: opacity 0.2s linear 0s;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
&.linked .bg:not(.hasError) {
|
|
105
|
+
background: #4d53e8;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.hovered .bg:not(.hasError) {
|
|
109
|
+
border: none;
|
|
110
|
+
cursor: crosshair;
|
|
111
|
+
transform: scale(1, 1);
|
|
112
|
+
background: #4d53e8;
|
|
113
|
+
|
|
114
|
+
& > .symbol {
|
|
115
|
+
opacity: 1;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.cross-hair {
|
|
120
|
+
position: relative;
|
|
121
|
+
left: 2px;
|
|
122
|
+
top: 2px;
|
|
123
|
+
|
|
124
|
+
&::after,
|
|
125
|
+
&::before {
|
|
126
|
+
content: '';
|
|
127
|
+
background: #fff;
|
|
128
|
+
border-radius: 2px;
|
|
129
|
+
position: absolute;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&::after {
|
|
133
|
+
left: 4px;
|
|
134
|
+
width: 2px;
|
|
135
|
+
height: 6px;
|
|
136
|
+
box-shadow: 0 4px #fff;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&::before {
|
|
140
|
+
top: 4px;
|
|
141
|
+
width: 6px;
|
|
142
|
+
height: 2px;
|
|
143
|
+
box-shadow: 4px 0 #fff;
|
|
144
|
+
}
|
|
145
|
+
`;
|
|
146
|
+
|
|
147
|
+
// src/components/workflow-port-render/cross-hair.tsx
|
|
148
|
+
import React from "react";
|
|
149
|
+
function CrossHair() {
|
|
150
|
+
return /* @__PURE__ */ React.createElement("div", { className: "symbol" }, /* @__PURE__ */ React.createElement("div", { className: "cross-hair" }));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/components/workflow-port-render/index.tsx
|
|
154
|
+
var WorkflowPortRender = (
|
|
155
|
+
// eslint-disable-next-line react/display-name
|
|
156
|
+
React2.memo((props) => {
|
|
157
|
+
const hoverService = useService(WorkflowHoverService);
|
|
158
|
+
const linesManager = useService(WorkflowLinesManager);
|
|
159
|
+
const { entity, onClick } = props;
|
|
160
|
+
const { portType, relativePosition, disabled } = entity;
|
|
161
|
+
const [targetElement, setTargetElement] = useState(entity.targetElement);
|
|
162
|
+
const [posX, updatePosX] = useState(relativePosition.x);
|
|
163
|
+
const [posY, updatePosY] = useState(relativePosition.y);
|
|
164
|
+
const [hovered, setHovered] = useState(false);
|
|
165
|
+
const [linked, setLinked] = useState(Boolean(entity?.lines?.length));
|
|
166
|
+
const [hasError, setHasError] = useState(props.entity.hasError);
|
|
167
|
+
const readonly = usePlaygroundReadonlyState();
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
entity.validate();
|
|
170
|
+
setHasError(entity.hasError);
|
|
171
|
+
const dispose = entity.onEntityChange(() => {
|
|
172
|
+
if (entity.targetElement) {
|
|
173
|
+
if (entity.targetElement !== targetElement) {
|
|
174
|
+
setTargetElement(entity.targetElement);
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const newPos = entity.relativePosition;
|
|
179
|
+
updatePosX(Math.round(newPos.x));
|
|
180
|
+
updatePosY(Math.round(newPos.y));
|
|
181
|
+
});
|
|
182
|
+
const dispose2 = hoverService.onHoveredChange((id) => {
|
|
183
|
+
setHovered(hoverService.isHovered(entity.id));
|
|
184
|
+
});
|
|
185
|
+
const dispose3 = entity.onErrorChanged(() => {
|
|
186
|
+
setHasError(entity.hasError);
|
|
187
|
+
});
|
|
188
|
+
const dispose4 = linesManager.onAvailableLinesChange(() => {
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
if (linesManager.disposed || entity.disposed) return;
|
|
191
|
+
setLinked(Boolean(entity.lines.length));
|
|
192
|
+
}, 0);
|
|
193
|
+
});
|
|
194
|
+
return () => {
|
|
195
|
+
dispose.dispose();
|
|
196
|
+
dispose2.dispose();
|
|
197
|
+
dispose3.dispose();
|
|
198
|
+
dispose4.dispose();
|
|
199
|
+
};
|
|
200
|
+
}, [hoverService, entity, targetElement]);
|
|
201
|
+
const className = classNames(props.className || "", {
|
|
202
|
+
hovered: !readonly && hovered && !disabled && portType !== "input",
|
|
203
|
+
// 有线条链接的时候深蓝色小圆点
|
|
204
|
+
linked
|
|
205
|
+
});
|
|
206
|
+
const content = /* @__PURE__ */ React2.createElement(
|
|
207
|
+
WorkflowPointStyle,
|
|
208
|
+
{
|
|
209
|
+
className,
|
|
210
|
+
style: targetElement ? props.style : { ...props.style, left: posX, top: posY },
|
|
211
|
+
onClick,
|
|
212
|
+
"data-port-entity-id": entity.id,
|
|
213
|
+
"data-port-entity-type": entity.portType,
|
|
214
|
+
"data-testid": "sdk.workflow.canvas.node.port"
|
|
215
|
+
},
|
|
216
|
+
/* @__PURE__ */ React2.createElement("div", { className: classNames("bg-circle", "workflow-bg-circle") }),
|
|
217
|
+
/* @__PURE__ */ React2.createElement(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
className: classNames({
|
|
221
|
+
bg: true,
|
|
222
|
+
[PORT_BG_CLASS_NAME]: true,
|
|
223
|
+
"workflow-point-bg": true,
|
|
224
|
+
hasError
|
|
225
|
+
})
|
|
226
|
+
},
|
|
227
|
+
/* @__PURE__ */ React2.createElement(CrossHair, null)
|
|
228
|
+
),
|
|
229
|
+
/* @__PURE__ */ React2.createElement("div", { className: "focus-circle" })
|
|
230
|
+
);
|
|
231
|
+
if (targetElement) {
|
|
232
|
+
return ReactDOM.createPortal(content, targetElement);
|
|
233
|
+
}
|
|
234
|
+
return content;
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// src/constants/lines.ts
|
|
239
|
+
var LINE_OFFSET = 6;
|
|
240
|
+
|
|
241
|
+
// src/create-free-lines-plugin.ts
|
|
242
|
+
import { definePluginCreator } from "@flowgram.ai/core";
|
|
243
|
+
|
|
244
|
+
// src/layer/lines-layer.tsx
|
|
245
|
+
import ReactDOM2 from "react-dom";
|
|
246
|
+
import React7, { useLayoutEffect, useState as useState2 } from "react";
|
|
247
|
+
import { inject, injectable } from "inversify";
|
|
248
|
+
import { domUtils } from "@flowgram.ai/utils";
|
|
249
|
+
import {
|
|
250
|
+
nanoid,
|
|
251
|
+
WorkflowDocument,
|
|
252
|
+
WorkflowHoverService as WorkflowHoverService2,
|
|
253
|
+
WorkflowLineEntity,
|
|
254
|
+
WorkflowNodeEntity,
|
|
255
|
+
WorkflowPortEntity,
|
|
256
|
+
WorkflowSelectService
|
|
257
|
+
} from "@flowgram.ai/free-layout-core";
|
|
258
|
+
import { Layer, observeEntities, observeEntityDatas, TransformData } from "@flowgram.ai/core";
|
|
259
|
+
|
|
260
|
+
// src/components/lines/index.tsx
|
|
261
|
+
import React6, { memo } from "react";
|
|
262
|
+
import { LineType } from "@flowgram.ai/free-layout-core";
|
|
263
|
+
|
|
264
|
+
// src/components/lines/fold-line/index.tsx
|
|
265
|
+
import React4 from "react";
|
|
266
|
+
import { POINT_RADIUS } from "@flowgram.ai/free-layout-core";
|
|
267
|
+
|
|
268
|
+
// src/components/lines/index.style.ts
|
|
269
|
+
import styled2 from "styled-components";
|
|
270
|
+
var LineStyle = styled2.div.attrs({
|
|
271
|
+
className: "gedit-flow-activity-edge"
|
|
272
|
+
})`
|
|
273
|
+
position: absolute;
|
|
274
|
+
|
|
275
|
+
@keyframes flowingDash {
|
|
276
|
+
to {
|
|
277
|
+
stroke-dashoffset: -13;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.flowing-line {
|
|
282
|
+
stroke-dasharray: 8, 5;
|
|
283
|
+
animation: flowingDash 0.5s linear infinite;
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
286
|
+
|
|
287
|
+
// src/components/lines/arrow/index.tsx
|
|
288
|
+
import React3 from "react";
|
|
289
|
+
function ArrowRenderer({
|
|
290
|
+
id,
|
|
291
|
+
pos,
|
|
292
|
+
reverseArrow,
|
|
293
|
+
strokeWidth,
|
|
294
|
+
vertical,
|
|
295
|
+
hide
|
|
296
|
+
}) {
|
|
297
|
+
if (hide) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const arrowPath = vertical ? reverseArrow ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${pos.x + LINE_OFFSET},${pos.y}` : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${pos.x + LINE_OFFSET},${pos.y - LINE_OFFSET}` : reverseArrow ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET}` : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${pos.x - LINE_OFFSET},${pos.y + LINE_OFFSET}`;
|
|
301
|
+
return /* @__PURE__ */ React3.createElement(
|
|
302
|
+
"path",
|
|
303
|
+
{
|
|
304
|
+
d: arrowPath,
|
|
305
|
+
strokeLinecap: "round",
|
|
306
|
+
stroke: `url(#${id})`,
|
|
307
|
+
fill: "none",
|
|
308
|
+
strokeWidth
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// src/components/lines/fold-line/index.tsx
|
|
314
|
+
var FoldLineRender = (props) => {
|
|
315
|
+
const { selected, color, line, children } = props;
|
|
316
|
+
const { to, from } = line.position;
|
|
317
|
+
const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;
|
|
318
|
+
const arrowToPos = {
|
|
319
|
+
x: to.x - POINT_RADIUS,
|
|
320
|
+
y: to.y
|
|
321
|
+
};
|
|
322
|
+
const arrowFromPos = {
|
|
323
|
+
x: from.x + POINT_RADIUS + LINE_OFFSET,
|
|
324
|
+
y: from.y
|
|
325
|
+
};
|
|
326
|
+
return /* @__PURE__ */ React4.createElement(LineStyle, null, children, /* @__PURE__ */ React4.createElement("svg", { overflow: "visible" }, /* @__PURE__ */ React4.createElement("defs", null, /* @__PURE__ */ React4.createElement(
|
|
327
|
+
"linearGradient",
|
|
328
|
+
{
|
|
329
|
+
x1: "0%",
|
|
330
|
+
y1: "100%",
|
|
331
|
+
x2: "100%",
|
|
332
|
+
y2: "100%",
|
|
333
|
+
id: line.id,
|
|
334
|
+
gradientUnits: "userSpaceOnUse"
|
|
335
|
+
},
|
|
336
|
+
/* @__PURE__ */ React4.createElement("stop", { stopColor: color, offset: "0%" }),
|
|
337
|
+
/* @__PURE__ */ React4.createElement("stop", { stopColor: color, offset: "100%" })
|
|
338
|
+
)), /* @__PURE__ */ React4.createElement("g", null, /* @__PURE__ */ React4.createElement(
|
|
339
|
+
"path",
|
|
340
|
+
{
|
|
341
|
+
d: line.bezier.foldPath,
|
|
342
|
+
fill: "none",
|
|
343
|
+
strokeLinecap: "round",
|
|
344
|
+
stroke: color,
|
|
345
|
+
strokeWidth,
|
|
346
|
+
className: line.flowing || line.processing ? "flowing-line" : ""
|
|
347
|
+
}
|
|
348
|
+
), /* @__PURE__ */ React4.createElement(
|
|
349
|
+
ArrowRenderer,
|
|
350
|
+
{
|
|
351
|
+
id: line.id,
|
|
352
|
+
reverseArrow: line.reverse,
|
|
353
|
+
pos: line.reverse ? arrowFromPos : arrowToPos,
|
|
354
|
+
strokeWidth,
|
|
355
|
+
hide: line.hideArrow
|
|
356
|
+
}
|
|
357
|
+
))));
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// src/components/lines/bezier-line/index.tsx
|
|
361
|
+
import React5 from "react";
|
|
362
|
+
import { POINT_RADIUS as POINT_RADIUS2 } from "@flowgram.ai/free-layout-core";
|
|
363
|
+
var PADDING = 12;
|
|
364
|
+
var BezierLineRender = (props) => {
|
|
365
|
+
const { line, color, fromColor, toColor, selected, children, strokePrefix } = props;
|
|
366
|
+
const { bbox } = line.bezier;
|
|
367
|
+
const { position, reverse, vertical, hideArrow } = line;
|
|
368
|
+
const toRelative = (p) => ({
|
|
369
|
+
x: p.x - bbox.x + PADDING,
|
|
370
|
+
y: p.y - bbox.y + PADDING
|
|
371
|
+
});
|
|
372
|
+
const fromPos = toRelative(position.from);
|
|
373
|
+
const toPos = toRelative(position.to);
|
|
374
|
+
const arrowToPos = vertical ? { x: toPos.x, y: toPos.y - POINT_RADIUS2 } : { x: toPos.x - POINT_RADIUS2, y: toPos.y };
|
|
375
|
+
const arrowFromPos = vertical ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS2 + LINE_OFFSET } : { x: fromPos.x + POINT_RADIUS2 + LINE_OFFSET, y: fromPos.y };
|
|
376
|
+
const controls = line.bezier.controls.map((c) => toRelative(c));
|
|
377
|
+
const getLinearStartColor = () => {
|
|
378
|
+
if (vertical) {
|
|
379
|
+
return fromPos.y < arrowToPos.y ? fromColor : toColor;
|
|
380
|
+
}
|
|
381
|
+
return fromPos.x < arrowToPos.x ? fromColor : toColor;
|
|
382
|
+
};
|
|
383
|
+
const getLinearEndColor = () => {
|
|
384
|
+
if (vertical) {
|
|
385
|
+
return fromPos.y < arrowToPos.y ? toColor : fromColor;
|
|
386
|
+
}
|
|
387
|
+
return fromPos.x < arrowToPos.x ? toColor : fromColor;
|
|
388
|
+
};
|
|
389
|
+
const linearStartColor = getLinearStartColor();
|
|
390
|
+
const linearEndColor = getLinearEndColor();
|
|
391
|
+
const getPathData = () => {
|
|
392
|
+
const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(",");
|
|
393
|
+
const curveType = controls.length === 1 ? "S" : "C";
|
|
394
|
+
if (vertical) {
|
|
395
|
+
return `M${fromPos.x} ${fromPos.y + POINT_RADIUS2} ${curveType} ${controlPoints}, ${arrowToPos.x} ${arrowToPos.y}`;
|
|
396
|
+
}
|
|
397
|
+
return `M${fromPos.x + POINT_RADIUS2} ${fromPos.y} ${curveType} ${controlPoints}, ${arrowToPos.x} ${arrowToPos.y}`;
|
|
398
|
+
};
|
|
399
|
+
const pathData = getPathData();
|
|
400
|
+
const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;
|
|
401
|
+
const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;
|
|
402
|
+
const path = /* @__PURE__ */ React5.createElement(
|
|
403
|
+
"path",
|
|
404
|
+
{
|
|
405
|
+
d: pathData,
|
|
406
|
+
fill: "none",
|
|
407
|
+
stroke: `url(#${strokeID})`,
|
|
408
|
+
strokeWidth,
|
|
409
|
+
className: line.processing || line.flowing ? "flowing-line" : ""
|
|
410
|
+
}
|
|
411
|
+
);
|
|
412
|
+
return /* @__PURE__ */ React5.createElement(
|
|
413
|
+
LineStyle,
|
|
414
|
+
{
|
|
415
|
+
style: {
|
|
416
|
+
left: bbox.x - PADDING,
|
|
417
|
+
top: bbox.y - PADDING,
|
|
418
|
+
position: "absolute"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
children,
|
|
422
|
+
/* @__PURE__ */ React5.createElement("svg", { width: bbox.width + PADDING * 2, height: bbox.height + PADDING * 2 }, /* @__PURE__ */ React5.createElement("defs", null, /* @__PURE__ */ React5.createElement(
|
|
423
|
+
"linearGradient",
|
|
424
|
+
{
|
|
425
|
+
x1: vertical ? "100%" : "0%",
|
|
426
|
+
y1: vertical ? "0%" : "100%",
|
|
427
|
+
x2: "100%",
|
|
428
|
+
y2: "100%",
|
|
429
|
+
id: strokeID,
|
|
430
|
+
gradientUnits: "userSpaceOnUse"
|
|
431
|
+
},
|
|
432
|
+
/* @__PURE__ */ React5.createElement("stop", { stopColor: color || linearStartColor, offset: "0%" }),
|
|
433
|
+
/* @__PURE__ */ React5.createElement("stop", { stopColor: color || linearEndColor, offset: "100%" })
|
|
434
|
+
)), /* @__PURE__ */ React5.createElement("g", null, path, /* @__PURE__ */ React5.createElement(
|
|
435
|
+
ArrowRenderer,
|
|
436
|
+
{
|
|
437
|
+
id: strokeID,
|
|
438
|
+
reverseArrow: reverse,
|
|
439
|
+
pos: reverse ? arrowFromPos : arrowToPos,
|
|
440
|
+
strokeWidth,
|
|
441
|
+
vertical,
|
|
442
|
+
hide: hideArrow
|
|
443
|
+
}
|
|
444
|
+
), props.showControlPoints ? controls.map((c, i) => /* @__PURE__ */ React5.createElement("circle", { key: i, cx: c.x, cy: c.y, r: "4", fill: "#ccc" })) : void 0))
|
|
445
|
+
);
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// src/components/lines/index.tsx
|
|
449
|
+
var LineTypeRender = (props) => {
|
|
450
|
+
if (props.lineType === LineType.LINE_CHART) {
|
|
451
|
+
return /* @__PURE__ */ React6.createElement(FoldLineRender, { ...props });
|
|
452
|
+
}
|
|
453
|
+
return /* @__PURE__ */ React6.createElement(BezierLineRender, { ...props });
|
|
454
|
+
};
|
|
455
|
+
var LineRender = memo(
|
|
456
|
+
LineTypeRender,
|
|
457
|
+
(prevProps, nextProps) => prevProps.version === nextProps.version
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
// src/layer/lines-layer.tsx
|
|
461
|
+
var LinesLayer = class extends Layer {
|
|
462
|
+
constructor() {
|
|
463
|
+
super(...arguments);
|
|
464
|
+
this.layerID = nanoid();
|
|
465
|
+
this.mountedLines = /* @__PURE__ */ new Map();
|
|
466
|
+
this._version = 0;
|
|
467
|
+
/**
|
|
468
|
+
* 节点线条
|
|
469
|
+
*/
|
|
470
|
+
this.node = domUtils.createDivWithClass("gedit-playground-layer gedit-flow-lines-layer");
|
|
471
|
+
}
|
|
472
|
+
onZoom(scale) {
|
|
473
|
+
this.node.style.transform = `scale(${scale})`;
|
|
474
|
+
}
|
|
475
|
+
onReady() {
|
|
476
|
+
this.pipelineNode.appendChild(this.node);
|
|
477
|
+
this.toDispose.pushAll([
|
|
478
|
+
this.selectService.onSelectionChanged(() => this.render()),
|
|
479
|
+
this.hoverService.onHoveredChange(() => this.render()),
|
|
480
|
+
this.workflowDocument.linesManager.onForceUpdate(() => {
|
|
481
|
+
this.mountedLines.clear();
|
|
482
|
+
this.bumpVersion();
|
|
483
|
+
this.render();
|
|
484
|
+
})
|
|
485
|
+
]);
|
|
486
|
+
}
|
|
487
|
+
dispose() {
|
|
488
|
+
this.mountedLines.clear();
|
|
489
|
+
}
|
|
490
|
+
render() {
|
|
491
|
+
const [, forceUpdate] = useState2({});
|
|
492
|
+
useLayoutEffect(() => {
|
|
493
|
+
const updateLines = () => {
|
|
494
|
+
let needsUpdate = false;
|
|
495
|
+
this.lines.forEach((line) => {
|
|
496
|
+
const oldVersion = line.bezierDataVersion;
|
|
497
|
+
line.refreshBezier();
|
|
498
|
+
if (line.bezierDataVersion !== oldVersion) {
|
|
499
|
+
needsUpdate = true;
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
if (needsUpdate) {
|
|
503
|
+
forceUpdate({});
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
const rafId = requestAnimationFrame(updateLines);
|
|
507
|
+
return () => cancelAnimationFrame(rafId);
|
|
508
|
+
}, [this.lines]);
|
|
509
|
+
const lines = this.lines.map((line) => this.renderLine(line));
|
|
510
|
+
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, lines);
|
|
511
|
+
}
|
|
512
|
+
// 用来绕过 memo
|
|
513
|
+
bumpVersion() {
|
|
514
|
+
this._version = this._version + 1;
|
|
515
|
+
if (this._version === Number.MAX_SAFE_INTEGER) {
|
|
516
|
+
this._version = 0;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
lineProps(line) {
|
|
520
|
+
const { lineType } = this.workflowDocument.linesManager;
|
|
521
|
+
const selected = this.selectService.isSelected(line.id);
|
|
522
|
+
const { version: lineVersion, bezierDataVersion, color } = line;
|
|
523
|
+
const version = `${this._version}:${lineVersion}:${bezierDataVersion}:${lineType}:${color}:${selected}`;
|
|
524
|
+
return {
|
|
525
|
+
key: line.id,
|
|
526
|
+
color: line.color,
|
|
527
|
+
selected,
|
|
528
|
+
line,
|
|
529
|
+
lineType,
|
|
530
|
+
version,
|
|
531
|
+
strokePrefix: this.layerID
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
lineComponent(props) {
|
|
535
|
+
const RenderInsideLine = this.options.renderInsideLine ?? (() => /* @__PURE__ */ React7.createElement(React7.Fragment, null));
|
|
536
|
+
return /* @__PURE__ */ React7.createElement(LineRender, { ...props }, /* @__PURE__ */ React7.createElement(RenderInsideLine, { ...props }));
|
|
537
|
+
}
|
|
538
|
+
renderLine(line) {
|
|
539
|
+
const lineProps = this.lineProps(line);
|
|
540
|
+
const cache = this.mountedLines.get(line.id);
|
|
541
|
+
const isCached = cache !== void 0;
|
|
542
|
+
const { portal: cachedPortal, version: cachedVersion } = cache ?? {};
|
|
543
|
+
if (isCached && cachedVersion === lineProps.version) {
|
|
544
|
+
return cachedPortal;
|
|
545
|
+
}
|
|
546
|
+
if (!isCached) {
|
|
547
|
+
this.renderElement.appendChild(line.node);
|
|
548
|
+
line.onDispose(() => {
|
|
549
|
+
this.mountedLines.delete(line.id);
|
|
550
|
+
line.node.remove();
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
const portal = ReactDOM2.createPortal(this.lineComponent(lineProps), line.node);
|
|
554
|
+
this.mountedLines.set(line.id, { line, portal, version: lineProps.version });
|
|
555
|
+
return portal;
|
|
556
|
+
}
|
|
557
|
+
get renderElement() {
|
|
558
|
+
if (typeof this.options.renderElement === "function") {
|
|
559
|
+
const element = this.options.renderElement();
|
|
560
|
+
if (element) {
|
|
561
|
+
return element;
|
|
562
|
+
}
|
|
563
|
+
} else if (typeof this.options.renderElement !== "undefined") {
|
|
564
|
+
return this.options.renderElement;
|
|
565
|
+
}
|
|
566
|
+
return this.node;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
LinesLayer.type = "WorkflowLinesLayer";
|
|
570
|
+
__decorateClass([
|
|
571
|
+
inject(WorkflowHoverService2)
|
|
572
|
+
], LinesLayer.prototype, "hoverService", 2);
|
|
573
|
+
__decorateClass([
|
|
574
|
+
inject(WorkflowSelectService)
|
|
575
|
+
], LinesLayer.prototype, "selectService", 2);
|
|
576
|
+
__decorateClass([
|
|
577
|
+
observeEntities(WorkflowLineEntity)
|
|
578
|
+
], LinesLayer.prototype, "lines", 2);
|
|
579
|
+
__decorateClass([
|
|
580
|
+
observeEntities(WorkflowPortEntity)
|
|
581
|
+
], LinesLayer.prototype, "ports", 2);
|
|
582
|
+
__decorateClass([
|
|
583
|
+
observeEntityDatas(WorkflowNodeEntity, TransformData)
|
|
584
|
+
], LinesLayer.prototype, "trans", 2);
|
|
585
|
+
__decorateClass([
|
|
586
|
+
inject(WorkflowDocument)
|
|
587
|
+
], LinesLayer.prototype, "workflowDocument", 2);
|
|
588
|
+
LinesLayer = __decorateClass([
|
|
589
|
+
injectable()
|
|
590
|
+
], LinesLayer);
|
|
591
|
+
|
|
592
|
+
// src/create-free-lines-plugin.ts
|
|
593
|
+
var createFreeLinesPlugin = definePluginCreator({
|
|
594
|
+
onInit: (ctx, opts) => {
|
|
595
|
+
ctx.playground.registerLayer(LinesLayer, {
|
|
596
|
+
...opts,
|
|
597
|
+
renderElement: () => {
|
|
598
|
+
if (typeof opts.renderElement === "function") {
|
|
599
|
+
return opts.renderElement(ctx);
|
|
600
|
+
} else {
|
|
601
|
+
return opts.renderElement;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
export {
|
|
608
|
+
LINE_OFFSET,
|
|
609
|
+
LinesLayer,
|
|
610
|
+
WorkflowPortRender,
|
|
611
|
+
createFreeLinesPlugin
|
|
612
|
+
};
|
|
613
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/workflow-port-render/index.tsx","../../src/constants/points.ts","../../src/components/workflow-port-render/style.ts","../../src/components/workflow-port-render/cross-hair.tsx","../../src/constants/lines.ts","../../src/create-free-lines-plugin.ts","../../src/layer/lines-layer.tsx","../../src/components/lines/index.tsx","../../src/components/lines/fold-line/index.tsx","../../src/components/lines/index.style.ts","../../src/components/lines/arrow/index.tsx","../../src/components/lines/bezier-line/index.tsx"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n","import { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { LinesLayer } from './layer';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(LinesLayer, {\n ...opts,\n renderElement: () => {\n if (typeof opts.renderElement === 'function') {\n return opts.renderElement(ctx);\n } else {\n return opts.renderElement;\n }\n },\n });\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { LineRender } from '../components/lines';\n\n@injectable()\nexport class LinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const oldVersion = line.bezierDataVersion;\n line.refreshBezier();\n // 如果有任何一条线发生变化,标记需要更新\n if (line.bezierDataVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, bezierDataVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${bezierDataVersion}:${lineType}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <LineRender {...props}>\n <RenderInsideLine {...props} />\n </LineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n if (typeof this.options.renderElement === 'function') {\n const element = this.options.renderElement();\n if (element) {\n return element;\n }\n } else if (typeof this.options.renderElement !== 'undefined') {\n return this.options.renderElement as HTMLElement;\n }\n return this.node;\n }\n}\n","import React, { memo } from 'react';\n\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport type { LineRenderProps } from '../../type';\nimport { FoldLineRender } from './fold-line';\nimport { BezierLineRender } from './bezier-line';\n\nconst LineTypeRender = (props: LineRenderProps) => {\n if (props.lineType === LineType.LINE_CHART) {\n return <FoldLineRender {...props} />;\n }\n return <BezierLineRender {...props} />;\n};\n\nexport const LineRender = memo(\n LineTypeRender,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\n\nimport { LineStyle } from '../index.style';\nimport ArrowRenderer from '../arrow';\nimport { LineRenderProps } from '../../../type';\nimport { STROKE_WIDTH, STROKE_WIDTH_SLECTED } from '../../../constants/points';\nimport { LINE_OFFSET } from '../../../constants/lines';\n\n/**\n * 折叠线\n */\n// eslint-disable-next-line react/display-name\nexport const FoldLineRender = (props: LineRenderProps) => {\n const { selected, color, line, children } = props;\n const { to, from } = line.position;\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n // 真正连接线需要到的点的位置\n const arrowToPos = {\n x: to.x - POINT_RADIUS,\n y: to.y,\n };\n const arrowFromPos = {\n x: from.x + POINT_RADIUS + LINE_OFFSET,\n y: from.y,\n };\n\n return (\n <LineStyle>\n {children}\n <svg overflow=\"visible\">\n <defs>\n <linearGradient\n x1=\"0%\"\n y1=\"100%\"\n x2=\"100%\"\n y2=\"100%\"\n id={line.id}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n <path\n d={line.bezier.foldPath}\n fill=\"none\"\n strokeLinecap=\"round\"\n stroke={color}\n strokeWidth={strokeWidth}\n className={line.flowing || line.processing ? 'flowing-line' : ''}\n />\n <ArrowRenderer\n id={line.id}\n reverseArrow={line.reverse}\n pos={line.reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n hide={line.hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .flowing-line {\n stroke-dasharray: 8, 5;\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../../constants/lines';\n\nexport default function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import React from 'react';\n\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\n\nimport { LineStyle } from '../index.style';\nimport ArrowRenderer from '../arrow';\nimport { LineRenderProps } from '../../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../../constants/points';\nimport { LINE_OFFSET } from '../../../constants/lines';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const BezierLineRender = (props: LineRenderProps) => {\n const { line, color, fromColor, toColor, selected, children, strokePrefix } = props;\n const { bbox } = line.bezier;\n const { position, reverse, vertical, hideArrow } = line;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + PADDING,\n y: p.y - bbox.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const controls = line.bezier.controls.map((c) => toRelative(c));\n\n const getLinearStartColor = (): string | undefined => {\n if (vertical) {\n return fromPos.y < arrowToPos.y ? fromColor : toColor;\n }\n return fromPos.x < arrowToPos.x ? fromColor : toColor;\n };\n\n const getLinearEndColor = (): string | undefined => {\n if (vertical) {\n return fromPos.y < arrowToPos.y ? toColor : fromColor;\n }\n return fromPos.x < arrowToPos.x ? toColor : fromColor;\n };\n\n const linearStartColor = getLinearStartColor();\n const linearEndColor = getLinearEndColor();\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n arrowToPos.x\n } ${arrowToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n arrowToPos.x\n } ${arrowToPos.y}`;\n };\n const pathData = getPathData();\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={pathData}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={line.processing || line.flowing ? 'flowing-line' : ''}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bbox.x - PADDING,\n top: bbox.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bbox.width + PADDING * 2} height={bbox.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color || linearStartColor} offset=\"0%\" />\n <stop stopColor={color || linearEndColor} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n {props.showControlPoints\n ? controls.map((c, i) => <circle key={i} cx={c.x} cy={c.y} r=\"4\" fill=\"#ccc\" />)\n : undefined}\n </g>\n </svg>\n </LineStyle>\n );\n};\n"],"mappings":"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","names":["React","React","ReactDOM","React","useState","WorkflowHoverService","React","React","styled","React","React","React","React","POINT_RADIUS","POINT_RADIUS","React","React","useState","React","ReactDOM","WorkflowHoverService"]}
|