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