@flowgram.ai/free-layout-core 0.3.5 → 0.4.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.
@@ -19,4 +19,4 @@ export {
19
19
  LineType,
20
20
  LineColors
21
21
  };
22
- //# sourceMappingURL=chunk-CTGO4RKX.js.map
22
+ //# sourceMappingURL=chunk-E7ZUQ7LV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/typings/workflow-line.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport type { Rectangle, IPoint } from '@flowgram.ai/utils';\n\nimport { type WorkflowLineEntity } from '../entities';\n\nexport enum LineType {\n BEZIER, // 贝塞尔曲线\n LINE_CHART, // 折叠线\n}\n\nexport type LineRenderType = LineType | string;\n\nexport type LinePointLocation = 'left' | 'top' | 'right' | 'bottom';\n\nexport interface LinePoint {\n x: number;\n y: number;\n location: LinePointLocation;\n}\nexport interface LinePosition {\n from: LinePoint;\n to: LinePoint;\n}\n\nexport interface LineColor {\n hidden: string;\n default: string;\n drawing: string;\n hovered: string;\n selected: string;\n error: string;\n flowing: string;\n}\n\nexport enum LineColors {\n HIDDEN = 'var(--g-workflow-line-color-hidden,transparent)', // 隐藏线条\n DEFUALT = 'var(--g-workflow-line-color-default,#4d53e8)',\n DRAWING = 'var(--g-workflow-line-color-drawing, #5DD6E3)', // '#b5bbf8', // '#9197F1',\n HOVER = 'var(--g-workflow-line-color-hover,#37d0ff)',\n SELECTED = 'var(--g-workflow-line-color-selected,#37d0ff)',\n ERROR = 'var(--g-workflow-line-color-error,red)',\n FLOWING = 'var(--g-workflow-line-color-flowing,#4d53e8)', // 流动线条,默认使用主题色\n}\n\nexport interface WorkflowLineRenderContribution {\n entity: WorkflowLineEntity;\n path: string;\n bounds: Rectangle;\n update: (params: { fromPos: LinePoint; toPos: LinePoint }) => void;\n calcDistance: (pos: IPoint) => number;\n}\n\nexport type WorkflowLineRenderContributionFactory = (new (\n entity: WorkflowLineEntity\n) => WorkflowLineRenderContribution) & {\n type: LineRenderType;\n};\n"],"mappings":";AASO,IAAK,WAAL,kBAAKA,cAAL;AACL,EAAAA,oBAAA;AACA,EAAAA,oBAAA;AAFU,SAAAA;AAAA,GAAA;AA6BL,IAAK,aAAL,kBAAKC,gBAAL;AACL,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,cAAW;AACX,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,aAAU;AAPA,SAAAA;AAAA,GAAA;","names":["LineType","LineColors"]}
package/dist/esm/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  LineColors,
13
13
  LineType
14
- } from "./chunk-CTGO4RKX.js";
14
+ } from "./chunk-E7ZUQ7LV.js";
15
15
  import "./chunk-DDJTYHXN.js";
16
16
  import {
17
17
  WorkflowOperationBaseService
@@ -110,8 +110,8 @@ function nanoid(n) {
110
110
  import { compose, composeAsync } from "@flowgram.ai/utils";
111
111
 
112
112
  // src/utils/fit-view.ts
113
- import { TransformData } from "@flowgram.ai/core";
114
113
  import { Rectangle } from "@flowgram.ai/utils";
114
+ import { TransformData } from "@flowgram.ai/core";
115
115
  var fitView = (doc, playgroundConfig, easing = true) => {
116
116
  const bounds = Rectangle.enlarge(
117
117
  doc.getAllNodes().map((node) => node.getData(TransformData).bounds)
@@ -223,43 +223,51 @@ var WorkflowPortEntity = class extends Entity {
223
223
  isErrorPort() {
224
224
  return this.node.document.isErrorPort(this, this.hasError);
225
225
  }
226
+ get location() {
227
+ if (this._location) {
228
+ return this._location;
229
+ }
230
+ if (this.portType === "input") {
231
+ return "left";
232
+ }
233
+ return "right";
234
+ }
226
235
  get point() {
227
236
  const { targetElement } = this;
228
237
  const { bounds } = this.node.getData(FlowNodeTransformData);
238
+ const location2 = this.location;
229
239
  if (targetElement) {
230
240
  const pos = domReactToBounds(targetElement.getBoundingClientRect()).center;
231
- return this.entityManager.getEntity(PlaygroundConfigEntity).getPosFromMouseEvent({
241
+ const point2 = this.entityManager.getEntity(PlaygroundConfigEntity).getPosFromMouseEvent({
232
242
  clientX: pos.x,
233
243
  clientY: pos.y
234
244
  });
245
+ return {
246
+ x: point2.x,
247
+ y: point2.y,
248
+ location: location2
249
+ };
235
250
  }
236
251
  let point = { x: 0, y: 0 };
237
252
  const offset = this._offset || { x: 0, y: 0 };
238
- if (this._location) {
239
- switch (this._location) {
240
- case "left":
241
- point = bounds.leftCenter;
242
- break;
243
- case "top":
244
- point = bounds.topCenter;
245
- break;
246
- case "right":
247
- point = bounds.rightCenter;
248
- break;
249
- case "bottom":
250
- point = bounds.bottomCenter;
251
- break;
252
- }
253
- } else {
254
- if (this.portType === "input") {
253
+ switch (location2) {
254
+ case "left":
255
255
  point = bounds.leftCenter;
256
- } else {
256
+ break;
257
+ case "top":
258
+ point = bounds.topCenter;
259
+ break;
260
+ case "right":
257
261
  point = bounds.rightCenter;
258
- }
262
+ break;
263
+ case "bottom":
264
+ point = bounds.bottomCenter;
265
+ break;
259
266
  }
260
267
  return {
261
268
  x: point.x + offset.x,
262
- y: point.y + offset.y
269
+ y: point.y + offset.y,
270
+ location: location2
263
271
  };
264
272
  }
265
273
  /**
@@ -703,8 +711,8 @@ var WorkflowLineRenderData = class extends EntityData3 {
703
711
  version: "",
704
712
  contributions: /* @__PURE__ */ new Map(),
705
713
  position: {
706
- from: { x: 0, y: 0 },
707
- to: { x: 0, y: 0 }
714
+ from: { x: 0, y: 0, location: "right" },
715
+ to: { x: 0, y: 0, location: "left" }
708
716
  }
709
717
  };
710
718
  }
@@ -750,16 +758,23 @@ var WorkflowLineRenderData = class extends EntityData3 {
750
758
  */
751
759
  updatePosition() {
752
760
  this.data.position.from = this.entity.from.getData(WorkflowNodePortsData).getOutputPoint(this.entity.info.fromPort);
753
- this.data.position.to = this.entity.info.drawingTo ?? this.entity.to?.getData(WorkflowNodePortsData)?.getInputPoint(this.entity.info.toPort) ?? {
754
- x: this.data.position.from.x,
755
- y: this.data.position.from.y
756
- };
761
+ if (this.entity.info.drawingTo) {
762
+ this.data.position.to = this.entity.info.drawingTo;
763
+ } else {
764
+ this.data.position.to = this.entity.to?.getData(WorkflowNodePortsData)?.getInputPoint(this.entity.info.toPort) ?? {
765
+ x: this.data.position.from.x,
766
+ y: this.data.position.from.y,
767
+ location: this.data.position.from.location === "right" ? "left" : "top"
768
+ };
769
+ }
757
770
  this.data.version = [
758
771
  this.lineType,
759
772
  this.data.position.from.x,
760
773
  this.data.position.from.y,
774
+ this.data.position.from.location,
761
775
  this.data.position.to.x,
762
- this.data.position.to.y
776
+ this.data.position.to.y,
777
+ this.data.position.to.location
763
778
  ].join("-");
764
779
  }
765
780
  get currentLine() {
@@ -795,9 +810,10 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
795
810
  hasError: false,
796
811
  flowing: false,
797
812
  disabled: false,
798
- vertical: false,
799
813
  hideArrow: false,
800
814
  reverse: false,
815
+ shrink: 10,
816
+ curvature: 0.25,
801
817
  highlightColor: "",
802
818
  lockedColor: ""
803
819
  };
@@ -901,20 +917,17 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
901
917
  }
902
918
  /**
903
919
  * 获取是否 testrun processing
904
- * @deprecated use `uiState.flowing` instead
920
+ * @deprecated use `flowing` instead
905
921
  */
906
922
  get processing() {
907
923
  return this._uiState.flowing;
908
924
  }
909
925
  /**
910
926
  * 设置 testrun processing 状态
911
- * @deprecated use `uiState.flowing` instead
927
+ * @deprecated use `flowing` instead
912
928
  */
913
929
  set processing(status) {
914
- if (this._uiState.flowing !== status) {
915
- this._uiState.flowing = status;
916
- this.fireChange();
917
- }
930
+ this.flowing = status;
918
931
  }
919
932
  // 获取连线是否为错误态
920
933
  get hasError() {
@@ -1033,13 +1046,25 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
1033
1046
  get flowing() {
1034
1047
  return this.linesManager.isFlowingLine(this, this.uiState.flowing);
1035
1048
  }
1049
+ set flowing(flowing) {
1050
+ if (this._uiState.flowing !== flowing) {
1051
+ this._uiState.flowing = flowing;
1052
+ this.fireChange();
1053
+ }
1054
+ }
1036
1055
  /** 是否禁用 */
1037
1056
  get disabled() {
1038
1057
  return this.linesManager.isDisabledLine(this, this.uiState.disabled);
1039
1058
  }
1040
1059
  /** 是否竖向 */
1041
1060
  get vertical() {
1042
- return this.linesManager.isVerticalLine(this, this.uiState.vertical);
1061
+ const fromLocation = this.fromPort.location;
1062
+ const toLocation = this.toPort?.location;
1063
+ if (toLocation) {
1064
+ return toLocation === "top";
1065
+ } else {
1066
+ return fromLocation === "bottom";
1067
+ }
1043
1068
  }
1044
1069
  /** 获取线条渲染器类型 */
1045
1070
  get renderType() {
@@ -1047,7 +1072,7 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
1047
1072
  }
1048
1073
  /** 获取线条样式 */
1049
1074
  get className() {
1050
- return this.linesManager.setLineClassName(this) ?? "";
1075
+ return [this.linesManager.setLineClassName(this), this._uiState.className].filter((s) => !!s).join(" ");
1051
1076
  }
1052
1077
  get color() {
1053
1078
  return this.linesManager.getLineColor(this);
@@ -1597,12 +1622,6 @@ var WorkflowLinesManager = class {
1597
1622
  }
1598
1623
  return defaultValue;
1599
1624
  }
1600
- isVerticalLine(line, defaultValue = false) {
1601
- if (this.options.isVerticalLine) {
1602
- return this.options.isVerticalLine(line);
1603
- }
1604
- return defaultValue;
1605
- }
1606
1625
  setLineRenderType(line) {
1607
1626
  if (this.options.setLineRenderType) {
1608
1627
  return this.options.setLineRenderType(line);
@@ -1933,6 +1952,11 @@ var WorkflowDocument = class extends FlowDocument {
1933
1952
  get loading() {
1934
1953
  return this._loading;
1935
1954
  }
1955
+ /**
1956
+ * use `ctx.tools.fitView()` instead
1957
+ * @deprecated
1958
+ * @param easing
1959
+ */
1936
1960
  async fitView(easing) {
1937
1961
  return fitView(this, this.playgroundConfig, easing).then(() => {
1938
1962
  this.linesManager.forceUpdate();
@@ -2937,11 +2961,16 @@ var WorkflowDragService = class {
2937
2961
  originLine.highlightColor = this.linesManager.lineColor.hidden;
2938
2962
  }
2939
2963
  dragSuccess = true;
2964
+ const pos = config.getPosFromMouseEvent(event);
2940
2965
  line = this.linesManager.createLine({
2941
2966
  from: fromPort.node.id,
2942
2967
  fromPort: fromPort.portID,
2943
- drawingTo: config.getPosFromMouseEvent(event),
2944
- data: originLine?.lineData
2968
+ data: originLine?.lineData,
2969
+ drawingTo: {
2970
+ x: pos.x,
2971
+ y: pos.y,
2972
+ location: fromPort.location === "right" ? "left" : "top"
2973
+ }
2945
2974
  });
2946
2975
  if (!line) {
2947
2976
  return;
@@ -2976,9 +3005,17 @@ var WorkflowDragService = class {
2976
3005
  lineErrorReset = hasError;
2977
3006
  }
2978
3007
  if (line.toPort) {
2979
- line.drawingTo = { x: line.toPort.point.x, y: line.toPort.point.y };
3008
+ line.drawingTo = {
3009
+ x: line.toPort.point.x,
3010
+ y: line.toPort.point.y,
3011
+ location: line.toPort.location
3012
+ };
2980
3013
  } else {
2981
- line.drawingTo = { x: dragPos.x, y: dragPos.y };
3014
+ line.drawingTo = {
3015
+ x: dragPos.x,
3016
+ y: dragPos.y,
3017
+ location: line.fromPort.location === "right" ? "left" : "top"
3018
+ };
2982
3019
  }
2983
3020
  originLine?.validate();
2984
3021
  line.validate();
@@ -3293,6 +3330,7 @@ function usePlaygroundReadonlyState(listenChange) {
3293
3330
  function checkTargetDraggable(el) {
3294
3331
  return el && el.tagName !== "INPUT" && el.tagName !== "TEXTAREA" && !el.closest(".flow-canvas-not-draggable");
3295
3332
  }
3333
+ var isFirefox = navigator?.userAgent?.includes?.("Firefox");
3296
3334
  function useNodeRender(nodeFromProps) {
3297
3335
  const node = nodeFromProps || useContext(PlaygroundEntityContext);
3298
3336
  const renderData = node.getData(FlowNodeRenderData3);
@@ -3356,7 +3394,6 @@ function useNodeRender(nodeFromProps) {
3356
3394
  );
3357
3395
  const deleteNode = useCallback(() => node.dispose(), [node]);
3358
3396
  useListenEvents(portsData.onDataChange);
3359
- const isFirefox = navigator?.userAgent?.includes?.("Firefox");
3360
3397
  const onFocus = useCallback(() => {
3361
3398
  if (isFirefox) {
3362
3399
  nodeRef.current?.setAttribute("draggable", "false");