orcasvn-react-diagrams 0.1.55 → 0.1.56

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/cjs/index.js CHANGED
@@ -808,6 +808,7 @@ var EVENT_PORT_MOUSE_DOWN = 'portMouseDown';
808
808
  var EVENT_PORT_MOUSE_UP = 'portMouseUp';
809
809
  var EVENT_PORT_MOVED = 'portMoved';
810
810
  var EVENT_PORT_SELECTED = 'portSelected';
811
+ var EVENT_PORT_CONTEXT_MENU = 'portContextMenu';
811
812
  var EVENT_ELEMENT_CONTEXT_MENU = 'elementContextMenu';
812
813
  var EVENT_ELEMENT_MOVED = 'elementMoved';
813
814
  var EVENT_ELEMENT_RESIZED = 'elementResized';
@@ -981,6 +982,13 @@ var EditorContext = /** @class */ (function () {
981
982
  EditorContext.prototype.onPortSelectedHandler = function (port, element) {
982
983
  this._eventEmitter.emit(EVENT_PORT_SELECTED, port, element);
983
984
  };
985
+ EditorContext.prototype.onPortContextMenu = function (callback) {
986
+ return this.addEventListener(EVENT_PORT_CONTEXT_MENU, callback);
987
+ };
988
+ /** @internal */
989
+ EditorContext.prototype.onPortContextMenuHandler = function (port, element, mouseEvent) {
990
+ this._eventEmitter.emit(EVENT_PORT_CONTEXT_MENU, port, element, mouseEvent);
991
+ };
984
992
  EditorContext.prototype.onElementContextMenu = function (callback) {
985
993
  return this.addEventListener(EVENT_ELEMENT_CONTEXT_MENU, callback);
986
994
  };
@@ -7688,8 +7696,9 @@ var SelectionFrame = function (props) {
7688
7696
  var circleHandleMouseDown = function (event) {
7689
7697
  event.stopPropagation();
7690
7698
  if (!draggingRect) {
7691
- setStartX(event.clientX);
7692
- setStartY(event.clientY);
7699
+ // const paperPosition = getMousePosition(event);
7700
+ // setStartX(paperPosition.x);
7701
+ // setStartY(paperPosition.y);
7693
7702
  setDraggingCircle(true);
7694
7703
  }
7695
7704
  };
@@ -7705,24 +7714,30 @@ var SelectionFrame = function (props) {
7705
7714
  var circleHandleMouseMove = function (event) {
7706
7715
  var mouseEvent = event;
7707
7716
  if (draggingCircle) {
7708
- var offsetX = mouseEvent.clientX - startX;
7709
- var offsetY = mouseEvent.clientY - startY;
7717
+ var mousePosition = getMousePosition(mouseEvent);
7718
+ // let offsetX = mouseEvent.clientX - startX;
7719
+ // let offsetY = mouseEvent.clientY - startY;
7710
7720
  if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7711
7721
  return;
7712
7722
  }
7713
- setStartX(mouseEvent.clientX);
7714
- setStartY(mouseEvent.clientY);
7723
+ // setStartX(mouseEvent.clientX);
7724
+ // setStartY(mouseEvent.clientY);
7715
7725
  setLastMoveTime(Date.now());
7716
- var newWidth = width;
7717
- var newHeight = height;
7726
+ var newWidth = mousePosition.x - curX;
7727
+ var newHeight = mousePosition.y - curY;
7718
7728
  if (propResizability.keepRatio) {
7719
- var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7720
- var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7721
- offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7722
- offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7723
- }
7724
- newWidth += offsetX;
7725
- newHeight += offsetY;
7729
+ var ratio = Math.max(Math.abs(newWidth / width), Math.abs(newHeight / height));
7730
+ newWidth = newWidth > 0 ? ratio * width : -ratio * width;
7731
+ newHeight = newHeight > 0 ? ratio * height : -ratio * height;
7732
+ }
7733
+ // if (propResizability.keepRatio) {
7734
+ // let resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7735
+ // const increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7736
+ // offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7737
+ // offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7738
+ // }
7739
+ // newWidth += offsetX;
7740
+ // newHeight += offsetY;
7726
7741
  if (newWidth < MIN_ELEMENT_SIZE) {
7727
7742
  newWidth = MIN_ELEMENT_SIZE;
7728
7743
  }
@@ -8280,7 +8295,7 @@ var Text = React.forwardRef(function (_a, ref) {
8280
8295
  var Text$1 = React.memo(Text);
8281
8296
 
8282
8297
  var Port1 = React.forwardRef(function (props, ref) {
8283
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
8298
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle, onContextMenu = props.onContextMenu,
8284
8299
  // onManuallyTriggerRenderHandler,
8285
8300
  renderShape = props.renderShape, children = props.children;
8286
8301
  var textRef = React.useRef(null);
@@ -8304,10 +8319,10 @@ var Port1 = React.forwardRef(function (props, ref) {
8304
8319
  var renderedShape = React.useMemo(function () {
8305
8320
  if (renderShape) {
8306
8321
  var RenderShape = renderShape;
8307
- return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
8322
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); } }), children));
8308
8323
  }
8309
8324
  else {
8310
- return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8325
+ return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8311
8326
  }
8312
8327
  }, [props]);
8313
8328
  return (React.createElement(React.Fragment, null,
@@ -8658,7 +8673,7 @@ var ElementWrapper = React.forwardRef(function (_a, ref) {
8658
8673
  });
8659
8674
 
8660
8675
  var Element = React.forwardRef(function (props, forwardedRef) {
8661
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated;
8676
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated, onPortContextMenu = props.onPortContextMenu; props.onPortsChanged;
8662
8677
  var _a = React.useState(), selectedPort = _a[0], setSelectedPort = _a[1];
8663
8678
  var _b = React.useState(), hoveredPort = _b[0], setHoveredPort = _b[1];
8664
8679
  var _c = React.useState([]), ports = _c[0], setPorts = _c[1];
@@ -8746,24 +8761,39 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8746
8761
  var eventListener = _paperEventEmitterContext.onPaperClicked(function (ev) {
8747
8762
  setSelectedPort(undefined);
8748
8763
  });
8764
+ return function () {
8765
+ eventListener.off();
8766
+ };
8767
+ }, []);
8768
+ //Normalize port position
8769
+ var normalizePortPosition = React.useCallback(function (tempNewPosition) {
8770
+ var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8771
+ return newPosition || tempNewPosition;
8772
+ }, [width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current]);
8773
+ React.useEffect(function () {
8749
8774
  //listen element resize to update position of the ports by element size.
8750
8775
  var eleResizeListener = _paperEventEmitterContext.onElementResized(id, function () {
8776
+ var _a;
8777
+ var isChanged = false;
8751
8778
  var newPorts = portsRef.current.map(function (port) {
8752
8779
  var newPosition = normalizePortPosition({ x: port.position.x, y: port.position.y });
8753
8780
  //Check port moved
8754
8781
  if (port.position.x !== newPosition.x || port.position.y !== newPosition.y) {
8755
- onPortMoved === null || onPortMoved === void 0 ? void 0 : onPortMoved(port, id, port.position, newPosition);
8782
+ isChanged = true;
8756
8783
  _paperEventEmitterContext.emitPortMoved(port, id, port.position, newPosition);
8757
8784
  }
8758
- return __assign(__assign({}, port), { position: newPosition });
8785
+ port.position = newPosition;
8786
+ return port;
8759
8787
  });
8760
8788
  setPorts(newPorts);
8789
+ if (isChanged) {
8790
+ (_a = props.onPortsChanged) === null || _a === void 0 ? void 0 : _a.call(props, newPorts, id);
8791
+ }
8761
8792
  });
8762
8793
  return function () {
8763
- eventListener.off();
8764
8794
  eleResizeListener.off();
8765
8795
  };
8766
- }, [onPortMoved]);
8796
+ }, [onPortMoved, normalizePortPosition, width, height, portMoveableAreas, portSlideRailSVGClassName]);
8767
8797
  //Listen creating element link started, ended.
8768
8798
  React.useEffect(function () {
8769
8799
  var elementStartedListener = _paperEventEmitterContext.onElementLinkStarted(function (tempLink) {
@@ -8836,11 +8866,6 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8836
8866
  var slideRailSVG = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(portSlideRailSVGClassName));
8837
8867
  return slideRailSVG;
8838
8868
  }, []);
8839
- //Normalize port position
8840
- var normalizePortPosition = function (tempNewPosition) {
8841
- var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8842
- return newPosition || tempNewPosition;
8843
- };
8844
8869
  var handlePortMove = function (newX, newY) {
8845
8870
  if (!selectedPort)
8846
8871
  return;
@@ -8987,6 +9012,14 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8987
9012
  if (someElementLinkStarted)
8988
9013
  setHoveredPort(undefined);
8989
9014
  }, [someElementLinkStarted]);
9015
+ //Handle when context menu is opened on port
9016
+ var handlePortContextMenu = React.useCallback(function (portId, e) {
9017
+ e.preventDefault();
9018
+ var port = portsRef.current.find(function (p) { return p.id === portId; });
9019
+ if (!port)
9020
+ return;
9021
+ onPortContextMenu === null || onPortContextMenu === void 0 ? void 0 : onPortContextMenu(port, id, e);
9022
+ }, [onPortContextMenu, id]);
8990
9023
  //Get rotate angle of port by port direction is defined.
8991
9024
  var rotatePort = React.useCallback(function (x, y) {
8992
9025
  // logger.info('calculating port rotation', x, y)
@@ -9027,7 +9060,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
9027
9060
  break;
9028
9061
  }
9029
9062
  return rotationAngle;
9030
- }, [portSlideRailSVGClassName, portDirection, getSlideRailSVG]);
9063
+ }, [width, height, portSlideRailSVGClassName, portDirection, getSlideRailSVG, normalizePortPosition]);
9031
9064
  var renderedShape = React.useMemo(function () {
9032
9065
  if (renderShape)
9033
9066
  return renderShape(props);
@@ -9051,15 +9084,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
9051
9084
  : React.createElement("rect", { x: potentialPortPosition.x - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, y: potentialPortPosition.y - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, width: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, height: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, rx: PORT_PLACEHOLDER_DEFAULT_SIZE, ry: PORT_PLACEHOLDER_DEFAULT_SIZE, stroke: PORT_PLACEHOLDER_DEFAULT_STROKE, fill: "none", strokeWidth: 3 })), ports === null || ports === void 0 ? void 0 :
9052
9085
  ports.map(function (p, index) {
9053
9086
  var _a, _b, _c, _d, _e, _f, _g, _h;
9054
- return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container,
9055
- // rotation={rotatePort(p)}
9056
- calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove,
9057
- // onMouseEnter={() => {
9058
- // if (someElementLinkStarted) setHoveredPort(p)
9059
- // }}
9060
- onMouseLeave: handlePortMouseLeave,
9061
- // onManuallyTriggerRenderHandler={p.manuallyTriggerRenderHandler?.bind(p)}
9062
- renderShape: p.renderShape },
9087
+ return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container, calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove, onMouseLeave: handlePortMouseLeave, onContextMenu: handlePortContextMenu, renderShape: p.renderShape },
9063
9088
  selectedPort && selectedPort.id === p.id && (hoveredPort === null || hoveredPort === void 0 ? void 0 : hoveredPort.id) !== p.id &&
9064
9089
  (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_g = selectedPort === null || selectedPort === void 0 ? void 0 : selectedPort.ref) === null || _g === void 0 ? void 0 : _g.current) || undefined, resizability: {
9065
9090
  enabled: false,
@@ -10026,6 +10051,14 @@ var Paper = function (props) {
10026
10051
  }
10027
10052
  setMouseDownedOnPaper(false);
10028
10053
  }, [paperEventEmitter]);
10054
+ var handlePortContextMenu = React.useCallback(function (port, elementId, e) {
10055
+ var _a;
10056
+ e.preventDefault();
10057
+ var element = elementsRef.current.find(function (e) { return e.id === elementId; });
10058
+ if (element) {
10059
+ (_a = props.onPortContextMenu) === null || _a === void 0 ? void 0 : _a.call(props, port, element, e);
10060
+ }
10061
+ }, [props.onPortContextMenu]);
10029
10062
  var handleContextMenu = React.useCallback(function (elementId, e, ref) {
10030
10063
  var _a;
10031
10064
  e.preventDefault();
@@ -10083,7 +10116,7 @@ var Paper = function (props) {
10083
10116
  //use the defined react element or the default Element component
10084
10117
  var ReactElement = element.reactElement || Element$1;
10085
10118
  return (React.createElement("g", { id: "group-of-element-".concat(element.id), key: element.id },
10086
- React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged,
10119
+ React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged, onPortContextMenu: handlePortContextMenu,
10087
10120
  // portPlaceholderShape={(<Circle x={0} y={0} width={10} height={10} fill='red' positioningAnchor={PositioningAnchor.Center} />)}
10088
10121
  onMouseUpAtLinkedPortPlaceholder: handleMouseUpAtLinkedPortPlaceholder, onTextUpdated: handleElementTextChange, onManuallyTriggerRenderPort: props.onManuallyTriggerRenderPort, textsPlaceHolderClassName: element.textsPlaceHolderClassName, textsPlaceHolderFlexStyle: element.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition: element.textsPlaceHolderFlexboxPosition, parentAbsolutePosition: element.parentElement ? getAbsolutePosition(element.parentElement) : undefined },
10089
10122
  element.childrenElementsInTree && element.childrenElementsInTree.map(renderElementInTree),
@@ -10261,11 +10294,13 @@ var Editor = function (_a) {
10261
10294
  var handlePortsChanged = React.useCallback(function (ports, element) {
10262
10295
  element.ports = ports;
10263
10296
  }, [editorContext]);
10297
+ var handlePortContextMenu = React.useCallback(function (port, element, event) {
10298
+ editorContext.onPortContextMenuHandler(port, element, event);
10299
+ }, [editorContext]);
10264
10300
  var handleElementContextMenu = React.useCallback(function (element, event) {
10265
10301
  editorContext.onElementContextMenuHandler(element, event);
10266
10302
  }, [editorContext]);
10267
10303
  var handleElementMoved = React.useCallback(function (relativePosition, element) {
10268
- console.count('SelectionFrame: handleElementMoved');
10269
10304
  editorContext.onElementMovedHandler(relativePosition, element);
10270
10305
  }, [editorContext]);
10271
10306
  var handleElementResized = React.useCallback(function (size, element) {
@@ -10324,7 +10359,7 @@ var Editor = function (_a) {
10324
10359
  }, [editorContext]);
10325
10360
  return (React.createElement(EditorConfigurationContextProvider, { value: editorContext.configuration },
10326
10361
  React.createElement(ZoomContextProvider, null,
10327
- React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) }))));
10362
+ React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onPortContextMenu: handlePortContextMenu, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) }))));
10328
10363
  };
10329
10364
 
10330
10365
  exports.CircleRC = Circle;
@@ -22,6 +22,7 @@ interface PaperProps {
22
22
  onPortMoved?: (relativePosition: IPosition, port: IPort, element: IElement) => void;
23
23
  onPortSelected?: (port: IPort, element: IElement) => void;
24
24
  onPortsChanged: (ports: IPort[], element: IElement) => void;
25
+ onPortContextMenu?: (port: IPort, element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void;
25
26
  onElementContextMenu?: (element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void;
26
27
  onElementMoved?: (relativePosition: IPosition, element: IElement, index: number, paperPosition: IPosition) => void;
27
28
  onElementResized?: (size: ISize, element: IElement, index: number) => void;
@@ -21,6 +21,7 @@ export default interface IEditorContext {
21
21
  onPortMouseUp: (callback: (port: IPort, element: IElement, paperPosition: IPosition) => void) => (() => void);
22
22
  onPortMoved: (callback: (position: IPosition, port: IPort, element: IElement) => void) => (() => void);
23
23
  onPortSelected: (callback: (port: IPort, element: IElement) => void) => (() => void);
24
+ onPortContextMenu: (callback: (port: IPort, element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void) => (() => void);
24
25
  onElementContextMenu: (callback: (element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void) => (() => void);
25
26
  onElementMoved: (callback: (relativePosition: IPosition, element: IElement) => void) => (() => void);
26
27
  onElementResized: (callback: (size: ISize, element: IElement) => void) => (() => void);
@@ -35,6 +35,7 @@ interface IElementProps {
35
35
  onMouseLeave?: (event: React.MouseEvent, elementId: string) => void;
36
36
  onMouseDown?: (event: React.MouseEvent, elementId: string) => void;
37
37
  onMouseUp?: (event: React.MouseEvent, elementId: string) => void;
38
+ onPortContextMenu?: (port: IPort, elementId: string, event: React.MouseEvent<SVGElement>) => void;
38
39
  onMouseUpAtLinkedPortPlaceholder?: (link: IElementLink, position: IPosition, targetElementId: string) => void;
39
40
  onTextUpdated?: (elmentId: string, textId: string, newTextContent: string) => void;
40
41
  onManuallyTriggerRenderPort?: (callback: (portId: string, elementId: string) => void) => () => void;
@@ -16,6 +16,7 @@ export interface IPortProps {
16
16
  onSelected?: (portId: string, e: React.MouseEvent<SVGElement>, ref?: SVGSVGElement) => void;
17
17
  onMouseUp?: (portId: string, e: React.MouseEvent<SVGElement>) => void;
18
18
  onMouseDown?: (portId: string, e: React.MouseEvent<SVGElement>) => void;
19
+ onContextMenu?: (portId: string, e: React.MouseEvent<SVGElement>) => void;
19
20
  moveableAreas?: IPosition[][];
20
21
  label?: IText;
21
22
  onMouseEnter?: (ev: React.MouseEvent) => void;
@@ -41,6 +41,7 @@ export declare class EditorContext implements IEditorContext {
41
41
  onPortMouseUp(callback: (port: IPort, element: IElement, paperPosition: IPosition) => void): () => void;
42
42
  onPortMoved(callback: (position: IPosition, port: IPort, element: IElement) => void): () => void;
43
43
  onPortSelected(callback: (port: IPort, element: IElement) => void): () => void;
44
+ onPortContextMenu(callback: (port: IPort, element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void): () => void;
44
45
  onElementContextMenu(callback: (element: IElement, mouseEvent: React.MouseEvent<SVGElement>) => void): () => void;
45
46
  onElementMoved(callback: (relativePosition: IPosition, element: IElement) => void): () => void;
46
47
  onElementResized(callback: (size: ISize, element: IElement) => void): () => void;
package/dist/esm/index.js CHANGED
@@ -804,6 +804,7 @@ var EVENT_PORT_MOUSE_DOWN = 'portMouseDown';
804
804
  var EVENT_PORT_MOUSE_UP = 'portMouseUp';
805
805
  var EVENT_PORT_MOVED = 'portMoved';
806
806
  var EVENT_PORT_SELECTED = 'portSelected';
807
+ var EVENT_PORT_CONTEXT_MENU = 'portContextMenu';
807
808
  var EVENT_ELEMENT_CONTEXT_MENU = 'elementContextMenu';
808
809
  var EVENT_ELEMENT_MOVED = 'elementMoved';
809
810
  var EVENT_ELEMENT_RESIZED = 'elementResized';
@@ -977,6 +978,13 @@ var EditorContext = /** @class */ (function () {
977
978
  EditorContext.prototype.onPortSelectedHandler = function (port, element) {
978
979
  this._eventEmitter.emit(EVENT_PORT_SELECTED, port, element);
979
980
  };
981
+ EditorContext.prototype.onPortContextMenu = function (callback) {
982
+ return this.addEventListener(EVENT_PORT_CONTEXT_MENU, callback);
983
+ };
984
+ /** @internal */
985
+ EditorContext.prototype.onPortContextMenuHandler = function (port, element, mouseEvent) {
986
+ this._eventEmitter.emit(EVENT_PORT_CONTEXT_MENU, port, element, mouseEvent);
987
+ };
980
988
  EditorContext.prototype.onElementContextMenu = function (callback) {
981
989
  return this.addEventListener(EVENT_ELEMENT_CONTEXT_MENU, callback);
982
990
  };
@@ -7684,8 +7692,9 @@ var SelectionFrame = function (props) {
7684
7692
  var circleHandleMouseDown = function (event) {
7685
7693
  event.stopPropagation();
7686
7694
  if (!draggingRect) {
7687
- setStartX(event.clientX);
7688
- setStartY(event.clientY);
7695
+ // const paperPosition = getMousePosition(event);
7696
+ // setStartX(paperPosition.x);
7697
+ // setStartY(paperPosition.y);
7689
7698
  setDraggingCircle(true);
7690
7699
  }
7691
7700
  };
@@ -7701,24 +7710,30 @@ var SelectionFrame = function (props) {
7701
7710
  var circleHandleMouseMove = function (event) {
7702
7711
  var mouseEvent = event;
7703
7712
  if (draggingCircle) {
7704
- var offsetX = mouseEvent.clientX - startX;
7705
- var offsetY = mouseEvent.clientY - startY;
7713
+ var mousePosition = getMousePosition(mouseEvent);
7714
+ // let offsetX = mouseEvent.clientX - startX;
7715
+ // let offsetY = mouseEvent.clientY - startY;
7706
7716
  if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7707
7717
  return;
7708
7718
  }
7709
- setStartX(mouseEvent.clientX);
7710
- setStartY(mouseEvent.clientY);
7719
+ // setStartX(mouseEvent.clientX);
7720
+ // setStartY(mouseEvent.clientY);
7711
7721
  setLastMoveTime(Date.now());
7712
- var newWidth = width;
7713
- var newHeight = height;
7722
+ var newWidth = mousePosition.x - curX;
7723
+ var newHeight = mousePosition.y - curY;
7714
7724
  if (propResizability.keepRatio) {
7715
- var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7716
- var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7717
- offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7718
- offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7719
- }
7720
- newWidth += offsetX;
7721
- newHeight += offsetY;
7725
+ var ratio = Math.max(Math.abs(newWidth / width), Math.abs(newHeight / height));
7726
+ newWidth = newWidth > 0 ? ratio * width : -ratio * width;
7727
+ newHeight = newHeight > 0 ? ratio * height : -ratio * height;
7728
+ }
7729
+ // if (propResizability.keepRatio) {
7730
+ // let resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7731
+ // const increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7732
+ // offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7733
+ // offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7734
+ // }
7735
+ // newWidth += offsetX;
7736
+ // newHeight += offsetY;
7722
7737
  if (newWidth < MIN_ELEMENT_SIZE) {
7723
7738
  newWidth = MIN_ELEMENT_SIZE;
7724
7739
  }
@@ -8276,7 +8291,7 @@ var Text = forwardRef(function (_a, ref) {
8276
8291
  var Text$1 = memo(Text);
8277
8292
 
8278
8293
  var Port1 = forwardRef(function (props, ref) {
8279
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
8294
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle, onContextMenu = props.onContextMenu,
8280
8295
  // onManuallyTriggerRenderHandler,
8281
8296
  renderShape = props.renderShape, children = props.children;
8282
8297
  var textRef = useRef(null);
@@ -8300,10 +8315,10 @@ var Port1 = forwardRef(function (props, ref) {
8300
8315
  var renderedShape = useMemo(function () {
8301
8316
  if (renderShape) {
8302
8317
  var RenderShape = renderShape;
8303
- return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
8318
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); } }), children));
8304
8319
  }
8305
8320
  else {
8306
- return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8321
+ return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); }, ref: ref, x: x, y: y, positioningAnchor: PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8307
8322
  }
8308
8323
  }, [props]);
8309
8324
  return (React.createElement(React.Fragment, null,
@@ -8654,7 +8669,7 @@ var ElementWrapper = forwardRef(function (_a, ref) {
8654
8669
  });
8655
8670
 
8656
8671
  var Element = forwardRef(function (props, forwardedRef) {
8657
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated;
8672
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated, onPortContextMenu = props.onPortContextMenu; props.onPortsChanged;
8658
8673
  var _a = useState(), selectedPort = _a[0], setSelectedPort = _a[1];
8659
8674
  var _b = useState(), hoveredPort = _b[0], setHoveredPort = _b[1];
8660
8675
  var _c = useState([]), ports = _c[0], setPorts = _c[1];
@@ -8742,24 +8757,39 @@ var Element = forwardRef(function (props, forwardedRef) {
8742
8757
  var eventListener = _paperEventEmitterContext.onPaperClicked(function (ev) {
8743
8758
  setSelectedPort(undefined);
8744
8759
  });
8760
+ return function () {
8761
+ eventListener.off();
8762
+ };
8763
+ }, []);
8764
+ //Normalize port position
8765
+ var normalizePortPosition = useCallback(function (tempNewPosition) {
8766
+ var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8767
+ return newPosition || tempNewPosition;
8768
+ }, [width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current]);
8769
+ useEffect(function () {
8745
8770
  //listen element resize to update position of the ports by element size.
8746
8771
  var eleResizeListener = _paperEventEmitterContext.onElementResized(id, function () {
8772
+ var _a;
8773
+ var isChanged = false;
8747
8774
  var newPorts = portsRef.current.map(function (port) {
8748
8775
  var newPosition = normalizePortPosition({ x: port.position.x, y: port.position.y });
8749
8776
  //Check port moved
8750
8777
  if (port.position.x !== newPosition.x || port.position.y !== newPosition.y) {
8751
- onPortMoved === null || onPortMoved === void 0 ? void 0 : onPortMoved(port, id, port.position, newPosition);
8778
+ isChanged = true;
8752
8779
  _paperEventEmitterContext.emitPortMoved(port, id, port.position, newPosition);
8753
8780
  }
8754
- return __assign(__assign({}, port), { position: newPosition });
8781
+ port.position = newPosition;
8782
+ return port;
8755
8783
  });
8756
8784
  setPorts(newPorts);
8785
+ if (isChanged) {
8786
+ (_a = props.onPortsChanged) === null || _a === void 0 ? void 0 : _a.call(props, newPorts, id);
8787
+ }
8757
8788
  });
8758
8789
  return function () {
8759
- eventListener.off();
8760
8790
  eleResizeListener.off();
8761
8791
  };
8762
- }, [onPortMoved]);
8792
+ }, [onPortMoved, normalizePortPosition, width, height, portMoveableAreas, portSlideRailSVGClassName]);
8763
8793
  //Listen creating element link started, ended.
8764
8794
  useEffect(function () {
8765
8795
  var elementStartedListener = _paperEventEmitterContext.onElementLinkStarted(function (tempLink) {
@@ -8832,11 +8862,6 @@ var Element = forwardRef(function (props, forwardedRef) {
8832
8862
  var slideRailSVG = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(portSlideRailSVGClassName));
8833
8863
  return slideRailSVG;
8834
8864
  }, []);
8835
- //Normalize port position
8836
- var normalizePortPosition = function (tempNewPosition) {
8837
- var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8838
- return newPosition || tempNewPosition;
8839
- };
8840
8865
  var handlePortMove = function (newX, newY) {
8841
8866
  if (!selectedPort)
8842
8867
  return;
@@ -8983,6 +9008,14 @@ var Element = forwardRef(function (props, forwardedRef) {
8983
9008
  if (someElementLinkStarted)
8984
9009
  setHoveredPort(undefined);
8985
9010
  }, [someElementLinkStarted]);
9011
+ //Handle when context menu is opened on port
9012
+ var handlePortContextMenu = useCallback(function (portId, e) {
9013
+ e.preventDefault();
9014
+ var port = portsRef.current.find(function (p) { return p.id === portId; });
9015
+ if (!port)
9016
+ return;
9017
+ onPortContextMenu === null || onPortContextMenu === void 0 ? void 0 : onPortContextMenu(port, id, e);
9018
+ }, [onPortContextMenu, id]);
8986
9019
  //Get rotate angle of port by port direction is defined.
8987
9020
  var rotatePort = useCallback(function (x, y) {
8988
9021
  // logger.info('calculating port rotation', x, y)
@@ -9023,7 +9056,7 @@ var Element = forwardRef(function (props, forwardedRef) {
9023
9056
  break;
9024
9057
  }
9025
9058
  return rotationAngle;
9026
- }, [portSlideRailSVGClassName, portDirection, getSlideRailSVG]);
9059
+ }, [width, height, portSlideRailSVGClassName, portDirection, getSlideRailSVG, normalizePortPosition]);
9027
9060
  var renderedShape = useMemo(function () {
9028
9061
  if (renderShape)
9029
9062
  return renderShape(props);
@@ -9047,15 +9080,7 @@ var Element = forwardRef(function (props, forwardedRef) {
9047
9080
  : React.createElement("rect", { x: potentialPortPosition.x - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, y: potentialPortPosition.y - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, width: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, height: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, rx: PORT_PLACEHOLDER_DEFAULT_SIZE, ry: PORT_PLACEHOLDER_DEFAULT_SIZE, stroke: PORT_PLACEHOLDER_DEFAULT_STROKE, fill: "none", strokeWidth: 3 })), ports === null || ports === void 0 ? void 0 :
9048
9081
  ports.map(function (p, index) {
9049
9082
  var _a, _b, _c, _d, _e, _f, _g, _h;
9050
- return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container,
9051
- // rotation={rotatePort(p)}
9052
- calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove,
9053
- // onMouseEnter={() => {
9054
- // if (someElementLinkStarted) setHoveredPort(p)
9055
- // }}
9056
- onMouseLeave: handlePortMouseLeave,
9057
- // onManuallyTriggerRenderHandler={p.manuallyTriggerRenderHandler?.bind(p)}
9058
- renderShape: p.renderShape },
9083
+ return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container, calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove, onMouseLeave: handlePortMouseLeave, onContextMenu: handlePortContextMenu, renderShape: p.renderShape },
9059
9084
  selectedPort && selectedPort.id === p.id && (hoveredPort === null || hoveredPort === void 0 ? void 0 : hoveredPort.id) !== p.id &&
9060
9085
  (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_g = selectedPort === null || selectedPort === void 0 ? void 0 : selectedPort.ref) === null || _g === void 0 ? void 0 : _g.current) || undefined, resizability: {
9061
9086
  enabled: false,
@@ -10022,6 +10047,14 @@ var Paper = function (props) {
10022
10047
  }
10023
10048
  setMouseDownedOnPaper(false);
10024
10049
  }, [paperEventEmitter]);
10050
+ var handlePortContextMenu = useCallback(function (port, elementId, e) {
10051
+ var _a;
10052
+ e.preventDefault();
10053
+ var element = elementsRef.current.find(function (e) { return e.id === elementId; });
10054
+ if (element) {
10055
+ (_a = props.onPortContextMenu) === null || _a === void 0 ? void 0 : _a.call(props, port, element, e);
10056
+ }
10057
+ }, [props.onPortContextMenu]);
10025
10058
  var handleContextMenu = useCallback(function (elementId, e, ref) {
10026
10059
  var _a;
10027
10060
  e.preventDefault();
@@ -10079,7 +10112,7 @@ var Paper = function (props) {
10079
10112
  //use the defined react element or the default Element component
10080
10113
  var ReactElement = element.reactElement || Element$1;
10081
10114
  return (React.createElement("g", { id: "group-of-element-".concat(element.id), key: element.id },
10082
- React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged,
10115
+ React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged, onPortContextMenu: handlePortContextMenu,
10083
10116
  // portPlaceholderShape={(<Circle x={0} y={0} width={10} height={10} fill='red' positioningAnchor={PositioningAnchor.Center} />)}
10084
10117
  onMouseUpAtLinkedPortPlaceholder: handleMouseUpAtLinkedPortPlaceholder, onTextUpdated: handleElementTextChange, onManuallyTriggerRenderPort: props.onManuallyTriggerRenderPort, textsPlaceHolderClassName: element.textsPlaceHolderClassName, textsPlaceHolderFlexStyle: element.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition: element.textsPlaceHolderFlexboxPosition, parentAbsolutePosition: element.parentElement ? getAbsolutePosition(element.parentElement) : undefined },
10085
10118
  element.childrenElementsInTree && element.childrenElementsInTree.map(renderElementInTree),
@@ -10257,11 +10290,13 @@ var Editor = function (_a) {
10257
10290
  var handlePortsChanged = useCallback(function (ports, element) {
10258
10291
  element.ports = ports;
10259
10292
  }, [editorContext]);
10293
+ var handlePortContextMenu = useCallback(function (port, element, event) {
10294
+ editorContext.onPortContextMenuHandler(port, element, event);
10295
+ }, [editorContext]);
10260
10296
  var handleElementContextMenu = useCallback(function (element, event) {
10261
10297
  editorContext.onElementContextMenuHandler(element, event);
10262
10298
  }, [editorContext]);
10263
10299
  var handleElementMoved = useCallback(function (relativePosition, element) {
10264
- console.count('SelectionFrame: handleElementMoved');
10265
10300
  editorContext.onElementMovedHandler(relativePosition, element);
10266
10301
  }, [editorContext]);
10267
10302
  var handleElementResized = useCallback(function (size, element) {
@@ -10320,7 +10355,7 @@ var Editor = function (_a) {
10320
10355
  }, [editorContext]);
10321
10356
  return (React.createElement(EditorConfigurationContextProvider, { value: editorContext.configuration },
10322
10357
  React.createElement(ZoomContextProvider, null,
10323
- React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) }))));
10358
+ React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onPortContextMenu: handlePortContextMenu, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) }))));
10324
10359
  };
10325
10360
 
10326
10361
  export { Circle as CircleRC, Crescent as CrescentRC, CustomShape as CustomShapeRC, EditorContext, Element$2 as Element, ElementLink$1 as ElementLink, ElementLink as ElementLinkRC, Port$1 as Port, Port as PortRC, PositioningAnchor, Rectangle as RectangleRC, RectangularFrame as RectangularFrameRC, ResizingDirection, ShapeWrapper as ShapeWrapperRC, SubObjectDirection, Text$2 as Text, TextAlign, Text$1 as TextRC, addPointToList, calculateAngleWithOx, checkPointContainsPolygon, checkPositionOnLine, checkSamePosition, configureLogger, correctPortPositionInElement, createSmoothPathString, Editor as default, degreeToRadian, diamondEdgeInsideSquare, dist, findNearestPointOnSegment, findNearestPosition, findNearestProjectedPoint, generateSubstitutePosition, generateUniqueId, getAbsolutePosition, getCurvePathData, getElementRotationInfo, getFirstIntersection, getFourVertexesOfBBoxFromElement, getIntersectionPositions, getPointsFromPathData, getPointsFromPathElement, getPortAbsolutePosition, getRectangleCorners, getRotatedRectangleCoordinates, getRotatedSVGBBox, getSVGBBoxOutsideTransformedParent, makePolygonOfElement, pathDataToD, removeDuplicatePosition, transformAbsPositionToElementRelativePosition, transformAbsPositionToRelativePositionInsideElement, windowsPositionToPaperPosition };