@html-graph/html-graph 8.17.0 → 8.18.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/README.md CHANGED
@@ -30,9 +30,9 @@ import { CanvasBuilder } from "@html-graph/html-graph";
30
30
  const element = document.getElementById("canvas");
31
31
 
32
32
  const canvas = new CanvasBuilder(element)
33
- .enableUserTransformableViewport()
34
- .enableUserDraggableNodes()
35
- .enableBackground()
33
+ .enableUserTransformableViewport() // Enables viewport pan and zoom
34
+ .enableUserDraggableNodes() // Enables draggable nodes
35
+ .enableBackground() // Renders background
36
36
  .build();
37
37
  ```
38
38
 
@@ -291,17 +291,14 @@ export declare type CenterFn = (width: number, height: number) => Point;
291
291
  export declare interface ConnectablePortsConfig {
292
292
  readonly edgeShape?: EdgeShapeConfig;
293
293
  readonly connectionTypeResolver?: ConnectionTypeResolver;
294
- readonly connectionPreprocessor?: ConnectionPreprocessor;
295
294
  readonly connectionAllowedVerifier?: ConnectionAllowedVerifier;
295
+ readonly connectionPreprocessor?: ConnectionPreprocessor;
296
296
  readonly mouseDownEventVerifier?: MouseEventVerifier;
297
297
  readonly mouseUpEventVerifier?: MouseEventVerifier;
298
- readonly dragPortDirection?: number | undefined;
298
+ readonly dragPortDirection?: DraggingPortDirectionConfig;
299
299
  readonly events?: {
300
300
  readonly onAfterEdgeCreated?: (edgeId: Identifier) => void;
301
- readonly onEdgeCreationInterrupted?: (params: {
302
- readonly staticPortId: Identifier;
303
- readonly isDirect: boolean;
304
- }) => void;
301
+ readonly onEdgeCreationInterrupted?: (params: EdgeCreationInProgressParams) => void;
305
302
  readonly onEdgeCreationPrevented?: (request: AddEdgeRequest) => void;
306
303
  };
307
304
  }
@@ -380,13 +377,14 @@ declare interface DotsRenderer {
380
377
  readonly color?: string;
381
378
  }
382
379
 
383
- declare interface DraggableEdgesConfig {
380
+ export declare interface DraggableEdgesConfig {
384
381
  readonly connectionPreprocessor?: ConnectionPreprocessor;
385
382
  readonly connectionAllowedVerifier?: ConnectionAllowedVerifier;
386
383
  readonly mouseDownEventVerifier?: MouseEventVerifier;
387
384
  readonly mouseUpEventVerifier?: MouseEventVerifier;
388
385
  readonly draggingEdgeResolver?: DraggingEdgeResolver;
389
386
  readonly draggingEdgeShape?: EdgeShapeConfig;
387
+ readonly dragPortDirection?: DraggingPortDirectionConfig;
390
388
  readonly events?: {
391
389
  readonly onAfterEdgeReattached?: (edgeId: Identifier) => void;
392
390
  readonly onEdgeReattachInterrupted?: (edge: GraphEdge & {
@@ -415,6 +413,13 @@ export declare interface DraggableNodesConfig {
415
413
 
416
414
  export declare type DraggingEdgeResolver = (portId: Identifier) => Identifier | null;
417
415
 
416
+ declare type DraggingPortDirectionConfig = number | undefined | "closest-connectable-port";
417
+
418
+ export declare interface EdgeCreationInProgressParams {
419
+ readonly staticPortId: Identifier;
420
+ readonly isDirect: boolean;
421
+ }
422
+
418
423
  declare interface EdgePath {
419
424
  readonly path: string;
420
425
  readonly midpoint: Point;
@@ -771,11 +776,7 @@ export declare interface LayoutAlgorithmParams {
771
776
  readonly viewport: Viewport;
772
777
  }
773
778
 
774
- export declare type LayoutApplyOn = {
775
- type: "topologyChangeMacrotask";
776
- } | {
777
- type: "topologyChangeMicrotask";
778
- } | EventSubject<void>;
779
+ export declare type LayoutApplyOn = TopologyChangeMacrotask | TopologyChangeMicrotask | EventSubject<void>;
779
780
 
780
781
  export declare interface LayoutConfig {
781
782
  readonly algorithm?: LayoutAlgorithmConfig | undefined;
@@ -946,6 +947,18 @@ export declare interface StructuredEdgeShape extends EdgeShape {
946
947
  readonly onAfterRender: EventHandler<StructuredEdgeRenderModel>;
947
948
  }
948
949
 
950
+ /**
951
+ * @deprecated
952
+ * use topologyChangeMicrotask instead
953
+ */
954
+ declare type TopologyChangeMacrotask = {
955
+ type: "topologyChangeMacrotask";
956
+ };
957
+
958
+ declare type TopologyChangeMicrotask = {
959
+ type: "topologyChangeMicrotask";
960
+ };
961
+
949
962
  export declare type TransformDeclaration = {
950
963
  readonly a?: number | undefined;
951
964
  readonly b?: number | undefined;
@@ -3305,7 +3305,7 @@ class DraggablePortsConfigurator {
3305
3305
  }
3306
3306
  const target = event.currentTarget;
3307
3307
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3308
- const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3308
+ const dragAllowed = this.params.onPointerDownVerifier(portId, {
3309
3309
  x: mouseEvent.clientX,
3310
3310
  y: mouseEvent.clientY
3311
3311
  });
@@ -3347,7 +3347,7 @@ class DraggablePortsConfigurator {
3347
3347
  const touch = touchEvent.touches[0];
3348
3348
  const target = event.currentTarget;
3349
3349
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3350
- const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3350
+ const dragAllowed = this.params.onPointerDownVerifier(portId, {
3351
3351
  x: touch.clientX,
3352
3352
  y: touch.clientY
3353
3353
  });
@@ -3585,6 +3585,52 @@ class UserSelectableElementsConfigurator {
3585
3585
  }
3586
3586
  }
3587
3587
  }
3588
+ const resolveCreateEdgeRequest = (params, targetPortId) => {
3589
+ return {
3590
+ from: params.isDirect ? params.staticPortId : targetPortId,
3591
+ to: params.isDirect ? targetPortId : params.staticPortId
3592
+ };
3593
+ };
3594
+ class ClosestConnectablePortDraggingPortDirectionResolver {
3595
+ constructor(graph, connectionAllowedVerifier) {
3596
+ this.graph = graph;
3597
+ this.connectionAllowedVerifier = connectionAllowedVerifier;
3598
+ }
3599
+ resolve(params) {
3600
+ let closestDirection = void 0;
3601
+ let closestDistance = Infinity;
3602
+ const { cursor } = params;
3603
+ this.graph.getAllPortIds().forEach((portId) => {
3604
+ const { element, direction, nodeId } = this.graph.getPort(portId);
3605
+ const { x, y } = this.graph.getNode(nodeId);
3606
+ if (x === null || y === null) {
3607
+ return;
3608
+ }
3609
+ const request = resolveCreateEdgeRequest(params, portId);
3610
+ if (!this.connectionAllowedVerifier(request)) {
3611
+ return;
3612
+ }
3613
+ const { top, left, width, height } = element.getBoundingClientRect();
3614
+ const center = { x: left + width / 2, y: top + height / 2 };
3615
+ const dx = cursor.x - center.x;
3616
+ const dy = cursor.y - center.y;
3617
+ const distance = Math.sqrt(dx * dx + dy * dy);
3618
+ if (distance < closestDistance) {
3619
+ closestDistance = distance;
3620
+ closestDirection = direction;
3621
+ }
3622
+ });
3623
+ return closestDirection;
3624
+ }
3625
+ }
3626
+ class ConstantDraggingPortDirectionResolver {
3627
+ constructor(direction) {
3628
+ this.direction = direction;
3629
+ }
3630
+ resolve() {
3631
+ return this.direction;
3632
+ }
3633
+ }
3588
3634
  class UserDraggableNodesConfigurator {
3589
3635
  constructor(canvas, element, window2, pointInsideVerifier, params) {
3590
3636
  __publicField(this, "grabbedNode", null);
@@ -4306,8 +4352,7 @@ class BackgroundConfigurator {
4306
4352
  class UserConnectablePortsConfigurator {
4307
4353
  constructor(canvas, overlayLayer, viewportStore, window2, pointInsideVerifier, params) {
4308
4354
  __publicField(this, "overlayCanvas");
4309
- __publicField(this, "staticPortId", null);
4310
- __publicField(this, "isTargetDragging", true);
4355
+ __publicField(this, "edgeInProgress", null);
4311
4356
  __publicField(this, "onEdgeCreated", (edgeId) => {
4312
4357
  this.params.onAfterEdgeCreated(edgeId);
4313
4358
  });
@@ -4325,7 +4370,7 @@ class UserConnectablePortsConfigurator {
4325
4370
  const draggablePortsParams = {
4326
4371
  mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4327
4372
  mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4328
- portDragAllowedVerifier: (portId, cursor) => {
4373
+ onPointerDownVerifier: (portId, cursor) => {
4329
4374
  const connectionType = this.params.connectionTypeResolver(portId);
4330
4375
  if (connectionType === null) {
4331
4376
  return false;
@@ -4341,13 +4386,9 @@ class UserConnectablePortsConfigurator {
4341
4386
  this.resetDragState();
4342
4387
  },
4343
4388
  onPointerOutside: () => {
4344
- const staticPortId = this.staticPortId;
4345
- const isTargetDragging = this.isTargetDragging;
4389
+ const params2 = this.edgeInProgress;
4346
4390
  this.resetDragState();
4347
- this.params.onEdgeCreationInterrupted({
4348
- staticPortId,
4349
- isDirect: isTargetDragging
4350
- });
4391
+ this.params.onEdgeCreationInterrupted(params2);
4351
4392
  }
4352
4393
  };
4353
4394
  DraggablePortsConfigurator.configure(
@@ -4367,9 +4408,8 @@ class UserConnectablePortsConfigurator {
4367
4408
  params
4368
4409
  );
4369
4410
  }
4370
- grabPort(portId, cursor, connectionType) {
4371
- const port = this.canvas.graph.getPort(portId);
4372
- this.staticPortId = portId;
4411
+ grabPort(staticPortId, cursor, connectionType) {
4412
+ const port = this.canvas.graph.getPort(staticPortId);
4373
4413
  const portRect = port.element.getBoundingClientRect();
4374
4414
  const portX = portRect.x + portRect.width / 2;
4375
4415
  const portY = portRect.y + portRect.height / 2;
@@ -4387,13 +4427,20 @@ class UserConnectablePortsConfigurator {
4387
4427
  portCoords: portPoint,
4388
4428
  portDirection: port.direction
4389
4429
  };
4430
+ const isDirect = connectionType === "direct";
4431
+ this.edgeInProgress = {
4432
+ staticPortId,
4433
+ isDirect
4434
+ };
4390
4435
  const draggingParams = {
4391
4436
  overlayNodeId: OverlayId.DraggingNodeId,
4392
4437
  portCoords: cursorPoint,
4393
- portDirection: this.params.dragPortDirection
4438
+ portDirection: this.params.draggingPortDirectionResolver.resolve({
4439
+ cursor,
4440
+ ...this.edgeInProgress
4441
+ }) ?? port.direction
4394
4442
  };
4395
- this.isTargetDragging = connectionType === "direct";
4396
- const [sourceParams, targetParams] = this.isTargetDragging ? [staticParams, draggingParams] : [draggingParams, staticParams];
4443
+ const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4397
4444
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
4398
4445
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(targetParams));
4399
4446
  this.overlayCanvas.addEdge({
@@ -4403,25 +4450,24 @@ class UserConnectablePortsConfigurator {
4403
4450
  });
4404
4451
  }
4405
4452
  resetDragState() {
4406
- this.staticPortId = null;
4407
- this.isTargetDragging = true;
4453
+ this.edgeInProgress = null;
4408
4454
  this.overlayCanvas.clear();
4409
4455
  }
4410
4456
  tryCreateConnection(cursor) {
4411
- const draggingPortId = findPortAtPoint(this.canvas.graph, cursor);
4412
- if (draggingPortId === null) {
4413
- this.params.onEdgeCreationInterrupted({
4414
- staticPortId: this.staticPortId,
4415
- isDirect: this.isTargetDragging
4416
- });
4457
+ const targetPortId = findPortAtPoint(this.canvas.graph, cursor);
4458
+ if (targetPortId === null) {
4459
+ this.params.onEdgeCreationInterrupted(this.edgeInProgress);
4417
4460
  return;
4418
4461
  }
4419
- const staticPortId = this.staticPortId;
4420
- const sourceId = this.isTargetDragging ? staticPortId : draggingPortId;
4421
- const targetId = this.isTargetDragging ? draggingPortId : staticPortId;
4422
- const request = { from: sourceId, to: targetId };
4462
+ const request = resolveCreateEdgeRequest(
4463
+ this.edgeInProgress,
4464
+ targetPortId
4465
+ );
4423
4466
  const connectionAllowed = this.params.connectionAllowedVerifier(request);
4424
- const processedRequest = this.params.connectionPreprocessor(request);
4467
+ const processedRequest = this.params.connectionPreprocessor({
4468
+ from: request.from,
4469
+ to: request.to
4470
+ });
4425
4471
  if (connectionAllowed && processedRequest !== null) {
4426
4472
  this.canvas.graph.onAfterEdgeAdded.subscribe(this.onEdgeCreated);
4427
4473
  this.canvas.addEdge(processedRequest);
@@ -4430,23 +4476,26 @@ class UserConnectablePortsConfigurator {
4430
4476
  this.params.onEdgeCreationPrevented(request);
4431
4477
  }
4432
4478
  }
4433
- moveDraggingPort(dragPoint) {
4479
+ moveDraggingPort(cursor) {
4434
4480
  const canvasRect = this.overlayLayer.getBoundingClientRect();
4435
4481
  const nodeContentCoords = this.canvas.viewport.createContentCoords({
4436
- x: dragPoint.x - canvasRect.x,
4437
- y: dragPoint.y - canvasRect.y
4482
+ x: cursor.x - canvasRect.x,
4483
+ y: cursor.y - canvasRect.y
4484
+ });
4485
+ const direction = this.params.draggingPortDirectionResolver.resolve({
4486
+ cursor,
4487
+ ...this.edgeInProgress
4438
4488
  });
4439
4489
  this.overlayCanvas.updateNode(OverlayId.DraggingNodeId, {
4440
4490
  x: nodeContentCoords.x,
4441
4491
  y: nodeContentCoords.y
4442
- });
4492
+ }).updatePort(OverlayId.DraggingNodeId, { direction });
4443
4493
  }
4444
4494
  }
4445
4495
  class UserDraggableEdgesConfigurator {
4446
4496
  constructor(canvas, overlayLayer, viewportStore, window2, pointInsideVerifier, params) {
4447
4497
  __publicField(this, "overlayCanvas");
4448
- __publicField(this, "staticPortId", null);
4449
- __publicField(this, "isTargetDragging", true);
4498
+ __publicField(this, "edgeInProgress", null);
4450
4499
  __publicField(this, "draggingEdgePayload", null);
4451
4500
  __publicField(this, "onEdgeReattached", (edgeId) => {
4452
4501
  this.params.onAfterEdgeReattached(edgeId);
@@ -4465,7 +4514,7 @@ class UserDraggableEdgesConfigurator {
4465
4514
  const draggablePortsParams = {
4466
4515
  mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4467
4516
  mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4468
- portDragAllowedVerifier: (portId, cursor) => {
4517
+ onPointerDownVerifier: (portId, cursor) => {
4469
4518
  return this.tryStartEdgeDragging(portId, cursor);
4470
4519
  },
4471
4520
  onPointerMove: (cursor) => {
@@ -4511,10 +4560,9 @@ class UserDraggableEdgesConfigurator {
4511
4560
  }
4512
4561
  const edge = this.canvas.graph.getEdge(edgeId);
4513
4562
  const isSourceDragging = portId === edge.from;
4514
- const isTargetDragging = portId === edge.to;
4563
+ const isDirect = portId === edge.to;
4515
4564
  const staticPortId = isSourceDragging ? edge.to : edge.from;
4516
- this.staticPortId = staticPortId;
4517
- this.isTargetDragging = isTargetDragging;
4565
+ this.edgeInProgress = { staticPortId, isDirect };
4518
4566
  const draggingPort = this.canvas.graph.getPort(portId);
4519
4567
  const staticPort = this.canvas.graph.getPort(staticPortId);
4520
4568
  const staticRect = staticPort.element.getBoundingClientRect();
@@ -4544,12 +4592,16 @@ class UserDraggableEdgesConfigurator {
4544
4592
  portCoords: staticPoint,
4545
4593
  portDirection: staticPort.direction
4546
4594
  };
4595
+ const direction = this.params.draggingPortDirectionResolver.resolve({
4596
+ cursor,
4597
+ ...this.edgeInProgress
4598
+ });
4547
4599
  const draggingParams = {
4548
4600
  overlayNodeId: OverlayId.DraggingNodeId,
4549
4601
  portCoords: draggingPoint,
4550
- portDirection: draggingPort.direction
4602
+ portDirection: direction ?? draggingPort.direction
4551
4603
  };
4552
- const [sourceParams, targetParams] = this.isTargetDragging ? [staticParams, draggingParams] : [draggingParams, staticParams];
4604
+ const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4553
4605
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
4554
4606
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(targetParams));
4555
4607
  const overlayEdgeShape = this.params.draggingEdgeShapeFactory !== null ? this.params.draggingEdgeShapeFactory(OverlayId.EdgeId) : edge.shape;
@@ -4563,30 +4615,43 @@ class UserDraggableEdgesConfigurator {
4563
4615
  }
4564
4616
  resetDragState() {
4565
4617
  this.draggingEdgePayload = null;
4566
- this.staticPortId = null;
4567
- this.isTargetDragging = true;
4618
+ this.edgeInProgress = null;
4568
4619
  this.overlayCanvas.clear();
4569
4620
  }
4570
- moveDraggingPort(dragPoint) {
4621
+ moveDraggingPort(cursor) {
4571
4622
  const canvasRect = this.overlayLayer.getBoundingClientRect();
4572
4623
  const nodeViewCoords = {
4573
- x: dragPoint.x - canvasRect.x,
4574
- y: dragPoint.y - canvasRect.y
4624
+ x: cursor.x - canvasRect.x,
4625
+ y: cursor.y - canvasRect.y
4575
4626
  };
4576
4627
  const nodeContentCoords = this.canvas.viewport.createContentCoords(nodeViewCoords);
4628
+ const direction = this.params.draggingPortDirectionResolver.resolve({
4629
+ cursor,
4630
+ ...this.edgeInProgress
4631
+ });
4577
4632
  this.overlayCanvas.updateNode(OverlayId.DraggingNodeId, {
4578
4633
  x: nodeContentCoords.x,
4579
4634
  y: nodeContentCoords.y
4580
- });
4635
+ }).updatePort(OverlayId.DraggingNodeId, { direction });
4581
4636
  }
4582
4637
  tryCreateConnection(cursor) {
4583
4638
  const draggingPortId = findPortAtPoint(this.canvas.graph, cursor);
4584
4639
  this.overlayCanvas.removeEdge(OverlayId.EdgeId);
4585
4640
  if (draggingPortId === null) {
4586
- this.handleEdgeReattachInterrupted();
4641
+ const edge2 = this.draggingEdgePayload;
4642
+ this.params.onEdgeReattachInterrupted({
4643
+ id: edge2.id,
4644
+ from: edge2.from,
4645
+ to: edge2.to,
4646
+ shape: edge2.shape,
4647
+ priority: edge2.priority
4648
+ });
4587
4649
  return;
4588
4650
  }
4589
- const [from, to] = this.isTargetDragging ? [this.staticPortId, draggingPortId] : [draggingPortId, this.staticPortId];
4651
+ const { from, to } = resolveCreateEdgeRequest(
4652
+ this.edgeInProgress,
4653
+ draggingPortId
4654
+ );
4590
4655
  const edge = this.draggingEdgePayload;
4591
4656
  const request = {
4592
4657
  id: edge.id,
@@ -4615,16 +4680,6 @@ class UserDraggableEdgesConfigurator {
4615
4680
  });
4616
4681
  }
4617
4682
  }
4618
- handleEdgeReattachInterrupted() {
4619
- const edge = this.draggingEdgePayload;
4620
- this.params.onEdgeReattachInterrupted({
4621
- id: edge.id,
4622
- from: edge.from,
4623
- to: edge.to,
4624
- shape: edge.shape,
4625
- priority: edge.priority
4626
- });
4627
- }
4628
4683
  }
4629
4684
  class ManualLayoutApplicationStrategyConfigurator {
4630
4685
  constructor(applier, trigger) {
@@ -4989,6 +5044,87 @@ const selectionDefaults = Object.freeze({
4989
5044
  });
4990
5045
  const noopFn = () => {
4991
5046
  };
5047
+ const resolveDraggingPortDirectionResolver = (config, graph, connectionAllowedVerifier) => {
5048
+ if (config === "closest-connectable-port") {
5049
+ return new ClosestConnectablePortDraggingPortDirectionResolver(
5050
+ graph,
5051
+ connectionAllowedVerifier
5052
+ );
5053
+ }
5054
+ return new ConstantDraggingPortDirectionResolver(config);
5055
+ };
5056
+ const resolveEdgeShapeFactory = (config) => {
5057
+ if (typeof config === "function") {
5058
+ return config;
5059
+ }
5060
+ switch (config.type) {
5061
+ case "straight":
5062
+ return () => new StraightEdgeShape({
5063
+ color: config.color,
5064
+ width: config.width,
5065
+ arrowLength: config.arrowLength,
5066
+ arrowOffset: config.arrowOffset,
5067
+ arrowRenderer: config.arrowRenderer,
5068
+ hasSourceArrow: config.hasSourceArrow,
5069
+ hasTargetArrow: config.hasTargetArrow,
5070
+ cycleSquareSide: config.cycleSquareSide,
5071
+ roundness: config.roundness,
5072
+ detourDistance: config.detourDistance,
5073
+ detourDirection: config.detourDirection
5074
+ });
5075
+ case "horizontal":
5076
+ return () => new HorizontalEdgeShape({
5077
+ color: config.color,
5078
+ width: config.width,
5079
+ arrowLength: config.arrowLength,
5080
+ arrowOffset: config.arrowOffset,
5081
+ arrowRenderer: config.arrowRenderer,
5082
+ hasSourceArrow: config.hasSourceArrow,
5083
+ hasTargetArrow: config.hasTargetArrow,
5084
+ cycleSquareSide: config.cycleSquareSide,
5085
+ roundness: config.roundness,
5086
+ detourDistance: config.detourDistance
5087
+ });
5088
+ case "vertical":
5089
+ return () => new VerticalEdgeShape({
5090
+ color: config.color,
5091
+ width: config.width,
5092
+ arrowLength: config.arrowLength,
5093
+ arrowOffset: config.arrowOffset,
5094
+ arrowRenderer: config.arrowRenderer,
5095
+ hasSourceArrow: config.hasSourceArrow,
5096
+ hasTargetArrow: config.hasTargetArrow,
5097
+ cycleSquareSide: config.cycleSquareSide,
5098
+ roundness: config.roundness,
5099
+ detourDistance: config.detourDistance
5100
+ });
5101
+ case "direct":
5102
+ return () => new DirectEdgeShape({
5103
+ color: config.color,
5104
+ width: config.width,
5105
+ arrowLength: config.arrowLength,
5106
+ arrowRenderer: config.arrowRenderer,
5107
+ hasSourceArrow: config.hasSourceArrow,
5108
+ hasTargetArrow: config.hasTargetArrow,
5109
+ sourceOffset: config.sourceOffset,
5110
+ targetOffset: config.targetOffset
5111
+ });
5112
+ default:
5113
+ return () => new BezierEdgeShape({
5114
+ color: config.color,
5115
+ width: config.width,
5116
+ arrowLength: config.arrowLength,
5117
+ arrowRenderer: config.arrowRenderer,
5118
+ hasSourceArrow: config.hasSourceArrow,
5119
+ hasTargetArrow: config.hasTargetArrow,
5120
+ cycleRadius: config.cycleRadius,
5121
+ smallCycleRadius: config.smallCycleRadius,
5122
+ curvature: config.curvature,
5123
+ detourDistance: config.detourDistance,
5124
+ detourDirection: config.detourDirection
5125
+ });
5126
+ }
5127
+ };
4992
5128
  const createDraggableNodesParams = (config) => {
4993
5129
  var _a, _b, _c, _d, _e, _f;
4994
5130
  const nodeDragVerifier = config.nodeDragVerifier ?? (() => true);
@@ -5183,102 +5319,36 @@ const createBackgroundParams = (backgroundConfig) => {
5183
5319
  maxViewportScale: backgroundConfig.maxViewportScale ?? 10
5184
5320
  };
5185
5321
  };
5186
- const resolveEdgeShapeFactory = (config) => {
5187
- if (typeof config === "function") {
5188
- return config;
5189
- }
5190
- switch (config.type) {
5191
- case "straight":
5192
- return () => new StraightEdgeShape({
5193
- color: config.color,
5194
- width: config.width,
5195
- arrowLength: config.arrowLength,
5196
- arrowOffset: config.arrowOffset,
5197
- arrowRenderer: config.arrowRenderer,
5198
- hasSourceArrow: config.hasSourceArrow,
5199
- hasTargetArrow: config.hasTargetArrow,
5200
- cycleSquareSide: config.cycleSquareSide,
5201
- roundness: config.roundness,
5202
- detourDistance: config.detourDistance,
5203
- detourDirection: config.detourDirection
5204
- });
5205
- case "horizontal":
5206
- return () => new HorizontalEdgeShape({
5207
- color: config.color,
5208
- width: config.width,
5209
- arrowLength: config.arrowLength,
5210
- arrowOffset: config.arrowOffset,
5211
- arrowRenderer: config.arrowRenderer,
5212
- hasSourceArrow: config.hasSourceArrow,
5213
- hasTargetArrow: config.hasTargetArrow,
5214
- cycleSquareSide: config.cycleSquareSide,
5215
- roundness: config.roundness,
5216
- detourDistance: config.detourDistance
5217
- });
5218
- case "vertical":
5219
- return () => new VerticalEdgeShape({
5220
- color: config.color,
5221
- width: config.width,
5222
- arrowLength: config.arrowLength,
5223
- arrowOffset: config.arrowOffset,
5224
- arrowRenderer: config.arrowRenderer,
5225
- hasSourceArrow: config.hasSourceArrow,
5226
- hasTargetArrow: config.hasTargetArrow,
5227
- cycleSquareSide: config.cycleSquareSide,
5228
- roundness: config.roundness,
5229
- detourDistance: config.detourDistance
5230
- });
5231
- case "direct":
5232
- return () => new DirectEdgeShape({
5233
- color: config.color,
5234
- width: config.width,
5235
- arrowLength: config.arrowLength,
5236
- arrowRenderer: config.arrowRenderer,
5237
- hasSourceArrow: config.hasSourceArrow,
5238
- hasTargetArrow: config.hasTargetArrow,
5239
- sourceOffset: config.sourceOffset,
5240
- targetOffset: config.targetOffset
5241
- });
5242
- default:
5243
- return () => new BezierEdgeShape({
5244
- color: config.color,
5245
- width: config.width,
5246
- arrowLength: config.arrowLength,
5247
- arrowRenderer: config.arrowRenderer,
5248
- hasSourceArrow: config.hasSourceArrow,
5249
- hasTargetArrow: config.hasTargetArrow,
5250
- cycleRadius: config.cycleRadius,
5251
- smallCycleRadius: config.smallCycleRadius,
5252
- curvature: config.curvature,
5253
- detourDistance: config.detourDistance,
5254
- detourDirection: config.detourDirection
5255
- });
5256
- }
5257
- };
5258
5322
  const defaults$3 = Object.freeze({
5259
5323
  connectionTypeResolver: () => "direct",
5260
5324
  connectionPreprocessor: (request) => request,
5261
5325
  connectionAllowedVerifier: () => true,
5262
5326
  mouseEventVerifier: (event) => event.button === 0
5263
5327
  });
5264
- const createConnectablePortsParams = (config, defaultEdgeShapeFactory, defaultDragPortDirection) => {
5328
+ const createConnectablePortsParams = (config, defaultEdgeShapeFactory, graph) => {
5265
5329
  var _a, _b, _c;
5330
+ const connectionAllowedVerifier = config.connectionAllowedVerifier ?? defaults$3.connectionAllowedVerifier;
5266
5331
  return {
5267
5332
  connectionTypeResolver: config.connectionTypeResolver ?? defaults$3.connectionTypeResolver,
5333
+ connectionAllowedVerifier,
5334
+ draggingPortDirectionResolver: resolveDraggingPortDirectionResolver(
5335
+ config.dragPortDirection,
5336
+ graph,
5337
+ connectionAllowedVerifier
5338
+ ),
5339
+ edgeShapeFactory: config.edgeShape !== void 0 ? resolveEdgeShapeFactory(config.edgeShape) : defaultEdgeShapeFactory,
5268
5340
  connectionPreprocessor: config.connectionPreprocessor ?? defaults$3.connectionPreprocessor,
5269
- connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$3.connectionAllowedVerifier,
5270
5341
  mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$3.mouseEventVerifier,
5271
5342
  mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$3.mouseEventVerifier,
5272
5343
  onAfterEdgeCreated: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeCreated) ?? noopFn,
5273
5344
  onEdgeCreationInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeCreationInterrupted) ?? noopFn,
5274
- onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? noopFn,
5275
- dragPortDirection: config.dragPortDirection ?? defaultDragPortDirection,
5276
- edgeShapeFactory: config.edgeShape !== void 0 ? resolveEdgeShapeFactory(config.edgeShape) : defaultEdgeShapeFactory
5345
+ onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? noopFn
5277
5346
  };
5278
5347
  };
5279
5348
  const defaults$2 = Object.freeze({
5280
5349
  connectionAllowedVerifier: () => true,
5281
5350
  connectionPreprocessor: (request) => request,
5351
+ // TODO: remove ctrl key
5282
5352
  mouseDownEventVerifier: (event) => event.button === 0 && event.ctrlKey,
5283
5353
  mouseUpEventVerifier: (event) => event.button === 0
5284
5354
  });
@@ -5292,16 +5362,22 @@ const createDraggableEdgeParams = (config, graph) => {
5292
5362
  return null;
5293
5363
  }
5294
5364
  };
5365
+ const connectionAllowedVerifier = config.connectionAllowedVerifier ?? defaults$2.connectionAllowedVerifier;
5295
5366
  return {
5296
5367
  connectionPreprocessor: config.connectionPreprocessor ?? defaults$2.connectionPreprocessor,
5297
- connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$2.connectionAllowedVerifier,
5368
+ connectionAllowedVerifier,
5298
5369
  mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$2.mouseDownEventVerifier,
5299
5370
  mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$2.mouseUpEventVerifier,
5300
5371
  draggingEdgeResolver: config.draggingEdgeResolver ?? defaultDraggingEdgeResolver,
5301
5372
  draggingEdgeShapeFactory: config.draggingEdgeShape !== void 0 ? resolveEdgeShapeFactory(config.draggingEdgeShape) : null,
5302
5373
  onAfterEdgeReattached: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeReattached) ?? noopFn,
5303
5374
  onEdgeReattachInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeReattachInterrupted) ?? noopFn,
5304
- onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? noopFn
5375
+ onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? noopFn,
5376
+ draggingPortDirectionResolver: resolveDraggingPortDirectionResolver(
5377
+ config.dragPortDirection,
5378
+ graph,
5379
+ connectionAllowedVerifier
5380
+ )
5305
5381
  };
5306
5382
  };
5307
5383
  const createVirtualScrollParams = (config) => {
@@ -6923,7 +6999,7 @@ class CanvasBuilder {
6923
6999
  const params = createConnectablePortsParams(
6924
7000
  this.connectablePortsConfig,
6925
7001
  graphControllerParams.edges.shapeFactory,
6926
- graphControllerParams.ports.direction
7002
+ canvas.graph
6927
7003
  );
6928
7004
  UserConnectablePortsConfigurator.configure(
6929
7005
  canvas,