orcasvn-react-diagrams 0.1.81 → 0.1.82

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
@@ -869,8 +869,18 @@ var EVENT_MANUALLY_TRIGGER_DRAGGING_ELEMENT = 'manuallyTriggerDraggingElement';
869
869
  var EVENT_LINK_SELECTED = 'linkSelected';
870
870
  var EVENT_TEXT_SELECTED = 'textSelected';
871
871
  var EVENT_MANUALLY_TRIGGER_STARTED_LINKING = 'manuallyTriggerStartedLinking';
872
+ var INITIAL_EDITOR_CONFIGURATION = {
873
+ paperBounds: {
874
+ minX: -1500,
875
+ minY: -1500,
876
+ maxX: 1500,
877
+ maxY: 1500
878
+ },
879
+ paperOrigin: { x: 0, y: 0 }
880
+ };
872
881
  var EditorContext = /** @class */ (function () {
873
882
  function EditorContext(elements, links, texts, configuration) {
883
+ if (configuration === void 0) { configuration = INITIAL_EDITOR_CONFIGURATION; }
874
884
  var _this = this;
875
885
  /** @internal */
876
886
  this.onEditorContextUpdated = function (callback) {
@@ -883,7 +893,7 @@ var EditorContext = /** @class */ (function () {
883
893
  this._elements = elements;
884
894
  this._links = links;
885
895
  this._texts = texts;
886
- this._configuration = configuration || {};
896
+ this._configuration = Object.assign({}, INITIAL_EDITOR_CONFIGURATION, configuration);
887
897
  this._eventEmitter = new EventEmitter();
888
898
  }
889
899
  EditorContext.prototype.addEventListener = function (event, callback) {
@@ -7636,14 +7646,14 @@ var correctPortPositionInElement = function (elementRelativePosition, elementWid
7636
7646
  }
7637
7647
  return newPosition || elementRelativePosition;
7638
7648
  };
7639
- var windowsPositionToPaperPosition = function (clientPosition, paperElement, zoom) {
7649
+ var windowsPositionToPaperPosition = function (clientPosition, paperElement, zoom, paperBounds) {
7640
7650
  var paperRect = paperElement.getBoundingClientRect();
7641
7651
  // Calculate the position relative to the paper element
7642
- var xPosOnPaper = (clientPosition.x - paperRect.left) / zoom;
7643
- var yPosOnPaper = (clientPosition.y - paperRect.top) / zoom;
7652
+ var xPosOnPaper = Math.round((clientPosition.x - paperRect.left) / zoom) + paperBounds.minX;
7653
+ var yPosOnPaper = Math.round((clientPosition.y - paperRect.top) / zoom) + paperBounds.minY;
7644
7654
  return {
7645
- x: Math.round(xPosOnPaper),
7646
- y: Math.round(yPosOnPaper),
7655
+ x: xPosOnPaper,
7656
+ y: yPosOnPaper,
7647
7657
  };
7648
7658
  };
7649
7659
 
@@ -7763,11 +7773,22 @@ var automationAddPointsToLink = function (eleLink, elements, limitPoint) {
7763
7773
  return eleLink;
7764
7774
  };
7765
7775
 
7776
+ var editorConfigurationContext = React.createContext(null);
7777
+ var useEditorConfiguration = function () {
7778
+ var context = React.useContext(editorConfigurationContext);
7779
+ if (!context) {
7780
+ throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
7781
+ }
7782
+ return context;
7783
+ };
7784
+ var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
7785
+
7766
7786
  // import { paperEventEmitterContext } from '../../contexts/paperEventEmitterContext';
7767
7787
  var SelectionFrame = function (props) {
7768
7788
  var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
7769
7789
  // movingOffsetThreshold: propMovingOffsetThreshold,
7770
7790
  propMovingRate = props.movingRate, propOnMouseDown = props.onMouseDown, propOnMouseUp = props.onMouseUp, propOnMove = props.onMove, propContainer = props.container, propResizability = props.resizability, propOnResize = props.onResize, draggingByDefault = props.draggingByDefault, PropDragDropHandlerElement = props.dragDropHandlerElement, propStrokeWidth = props.strokeWidth, propAnchor = props.anchor, zoom = props.zoom;
7791
+ var paperBounds = useEditorConfiguration().paperBounds;
7771
7792
  var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
7772
7793
  var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
7773
7794
  var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
@@ -7815,7 +7836,7 @@ var SelectionFrame = function (props) {
7815
7836
  var position = windowsPositionToPaperPosition({
7816
7837
  x: event.clientX,
7817
7838
  y: event.clientY
7818
- }, propContainer, zoom);
7839
+ }, propContainer, zoom, paperBounds);
7819
7840
  return position;
7820
7841
  }, [propContainer, zoom]);
7821
7842
  var addRectHandleMouseDown = function (event) {
@@ -8226,39 +8247,136 @@ var paperEventEmitterContext = React.createContext({
8226
8247
  onCommandRenderPort: onCommandRenderPort,
8227
8248
  });
8228
8249
 
8229
- var editorConfigurationContext = React.createContext(null);
8230
- var useEditorConfiguration = function () {
8231
- var context = React.useContext(editorConfigurationContext);
8232
- if (!context) {
8233
- throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
8234
- }
8235
- return context;
8236
- };
8237
- var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
8238
-
8239
8250
  /**
8240
8251
  * Zoom context to manage zoom level and related state.
8241
8252
  * This context can be used to provide zoom functionality across the application.
8242
8253
  */
8243
- var zoomContext = React.createContext(null);
8244
- var ZoomContextProvider = function (_a) {
8245
- var children = _a.children;
8254
+ var zoomPanContext = React.createContext(null);
8255
+ var ZoomPanContextProvider = function (_a) {
8256
+ var paperOrigin = _a.paperOrigin, children = _a.children, bounds = _a.bounds, onExpandBounds = _a.onExpandBounds;
8246
8257
  var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
8247
8258
  var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
8248
8259
  var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
8260
+ var _e = React.useState(false), isPanning = _e[0], setIsPanning = _e[1];
8249
8261
  var wrapperRef = React.useRef(null);
8250
8262
  var contentRef = React.useRef(null);
8251
- var handleWheel = function (e) {
8252
- // Chỉ zoom khi giữ Ctrl
8253
- if (!e.ctrlKey)
8263
+ var originalWidth = bounds.maxX - bounds.minX;
8264
+ var originalHeight = bounds.maxY - bounds.minY;
8265
+ // Width and height of the content area based on zoom and bounds
8266
+ var contentWidth = Math.min(originalWidth, originalWidth * zoom);
8267
+ var contentHeight = Math.min(originalHeight, originalHeight * zoom);
8268
+ React.useLayoutEffect(function () {
8269
+ var _a;
8270
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
8271
+ left: scrollLeft,
8272
+ top: scrollTop,
8273
+ });
8274
+ }, [scrollLeft, scrollTop]);
8275
+ // Pan to paper origin on initial load
8276
+ React.useLayoutEffect(function () {
8277
+ var initialScrollLeft = Math.abs(bounds.minX) + (paperOrigin ? paperOrigin.x : 0);
8278
+ var initialScrollTop = Math.abs(bounds.minY) + (paperOrigin ? paperOrigin.y : 0);
8279
+ setScrollLeft(initialScrollLeft);
8280
+ setScrollTop(initialScrollTop);
8281
+ }, [paperOrigin === null || paperOrigin === void 0 ? void 0 : paperOrigin.x, paperOrigin === null || paperOrigin === void 0 ? void 0 : paperOrigin.y]);
8282
+ var resetZoom = function () {
8283
+ setZoom(1);
8284
+ };
8285
+ React.useEffect(function () {
8286
+ var preventBrowserZoom = function (e) {
8287
+ if (e.ctrlKey || e.metaKey) {
8288
+ e.preventDefault();
8289
+ }
8290
+ };
8291
+ window.addEventListener("wheel", preventBrowserZoom, { passive: false });
8292
+ return function () {
8293
+ window.removeEventListener("wheel", preventBrowserZoom);
8294
+ };
8295
+ }, []);
8296
+ var handleMouseDown = function (e) {
8297
+ if (e.button === 0) { // Left mouse button
8298
+ setIsPanning(true);
8299
+ }
8300
+ };
8301
+ var handleMouseUp = function (e) {
8302
+ setIsPanning(false);
8303
+ };
8304
+ // Throttle function to limit the frequency of handleMouseMove calls
8305
+ var throttle = React.useCallback(function (func, delay) {
8306
+ var timeoutId = null;
8307
+ var lastExecTime = 0;
8308
+ return function () {
8309
+ var args = [];
8310
+ for (var _i = 0; _i < arguments.length; _i++) {
8311
+ args[_i] = arguments[_i];
8312
+ }
8313
+ var currentTime = Date.now();
8314
+ if (currentTime - lastExecTime > delay) {
8315
+ func.apply(void 0, args);
8316
+ lastExecTime = currentTime;
8317
+ }
8318
+ else {
8319
+ if (timeoutId)
8320
+ clearTimeout(timeoutId);
8321
+ timeoutId = setTimeout(function () {
8322
+ func.apply(void 0, args);
8323
+ lastExecTime = Date.now();
8324
+ }, delay - (currentTime - lastExecTime));
8325
+ }
8326
+ };
8327
+ }, []);
8328
+ var handleMouseMoveCore = React.useCallback(function (e) {
8329
+ if (!isPanning || !wrapperRef.current)
8254
8330
  return;
8331
+ if (e.movementX === 0 && e.movementY === 0)
8332
+ return; // Ignore if there's no movement
8333
+ var newScrollLeft = wrapperRef.current.scrollLeft - e.movementX;
8334
+ var newScrollTop = wrapperRef.current.scrollTop - e.movementY;
8335
+ setScrollLeft(newScrollLeft);
8336
+ setScrollTop(newScrollTop);
8337
+ var increment = 100;
8338
+ var newBounds = __assign({}, bounds);
8339
+ var isChangedBounds = false;
8340
+ // If pan reaches the right edge and mouse is moving right
8341
+ if (newScrollLeft + wrapperRef.current.clientWidth > wrapperRef.current.scrollWidth &&
8342
+ e.movementX < 0) {
8343
+ newBounds.maxX += increment;
8344
+ isChangedBounds = true;
8345
+ }
8346
+ // If pan reaches the left edge and mouse is moving left
8347
+ if (newScrollLeft < 0 && e.movementX > 0) {
8348
+ newBounds.minX -= increment;
8349
+ isChangedBounds = true;
8350
+ }
8351
+ // If pan reaches the bottom edge and mouse is moving down
8352
+ if (newScrollTop + wrapperRef.current.clientHeight > wrapperRef.current.scrollHeight &&
8353
+ e.movementY < 0) {
8354
+ newBounds.maxY += increment;
8355
+ isChangedBounds = true;
8356
+ }
8357
+ // If pan reaches the top edge and mouse is moving up
8358
+ if (newScrollTop < 0 && e.movementY > 0) {
8359
+ newBounds.minY -= increment;
8360
+ isChangedBounds = true;
8361
+ }
8362
+ if (isChangedBounds && onExpandBounds) {
8363
+ onExpandBounds(newBounds);
8364
+ }
8365
+ }, [isPanning, bounds, onExpandBounds]);
8366
+ // Throttled version of handleMouseMove (16ms = ~60fps)
8367
+ var handleMouseMove = React.useCallback(throttle(handleMouseMoveCore, 16), [throttle, handleMouseMoveCore, bounds]);
8368
+ var handleWheelCore = React.useCallback(function (e) {
8255
8369
  e.preventDefault();
8256
- var delta = -e.deltaY;
8257
- var zoomFactor = 0.05;
8258
- var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
8259
- newZoom = Math.max(0.1, Math.min(newZoom, 4));
8370
+ // Only zoom when Ctrl key is pressed
8371
+ if (!e.ctrlKey)
8372
+ return;
8260
8373
  if (!wrapperRef.current || !contentRef.current)
8261
8374
  return;
8375
+ var delta = -e.deltaY;
8376
+ // Adjust zoom factor as needed
8377
+ var zoomFactor = 0.02;
8378
+ var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
8379
+ newZoom = Math.max(0.1, Math.min(newZoom, 4)); // Clamp zoom between 0.1 and 4
8262
8380
  var wrapper = wrapperRef.current;
8263
8381
  var content = contentRef.current;
8264
8382
  // Get bounding rectangle of the content
@@ -8267,55 +8385,49 @@ var ZoomContextProvider = function (_a) {
8267
8385
  var offsetY = e.clientY - rect.top;
8268
8386
  var percentX = offsetX / (content.offsetWidth);
8269
8387
  var percentY = offsetY / (content.offsetHeight);
8270
- console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
8271
8388
  // Old width and height of content
8272
8389
  var prevWidth = content.offsetWidth * zoom;
8273
8390
  var prevHeight = content.offsetHeight * zoom;
8274
8391
  var newWidth = content.offsetWidth * newZoom;
8275
8392
  var newHeight = content.offsetHeight * newZoom;
8393
+ // Calculate new scroll positions to keep the point under the cursor stationary
8276
8394
  var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
8277
8395
  var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
8278
8396
  setZoom(newZoom);
8279
8397
  setScrollLeft(scrollLeft);
8280
8398
  setScrollTop(scrollTop);
8281
- };
8282
- React.useLayoutEffect(function () {
8283
- var _a;
8284
- (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
8285
- left: scrollLeft,
8286
- top: scrollTop,
8287
- });
8288
- }, [zoom, scrollLeft, scrollTop]);
8289
- var resetZoom = function () {
8290
- setZoom(1);
8291
- };
8292
- React.useEffect(function () {
8293
- var preventBrowserZoom = function (e) {
8294
- if (e.ctrlKey || e.metaKey) {
8399
+ }, [zoom]);
8400
+ // Throttled version of handleWheel (16ms = ~60fps)
8401
+ var handleWheel = React.useCallback(throttle(handleWheelCore, 16), [throttle, handleWheelCore]);
8402
+ var value = {
8403
+ zoom: zoom,
8404
+ isPanning: isPanning,
8405
+ wrapperContainer: wrapperRef.current,
8406
+ setZoom: setZoom,
8407
+ resetZoom: resetZoom
8408
+ };
8409
+ return (React.createElement(zoomPanContext.Provider, { value: value },
8410
+ React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseMove: handleMouseMove,
8411
+ // onScroll={handleScroll}
8412
+ onContextMenu: function (e) {
8295
8413
  e.preventDefault();
8296
- }
8297
- };
8298
- window.addEventListener("wheel", preventBrowserZoom, { passive: false });
8299
- return function () {
8300
- window.removeEventListener("wheel", preventBrowserZoom);
8301
- };
8302
- }, []);
8303
- return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
8304
- React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
8414
+ }, style: {
8305
8415
  width: "100vw",
8306
8416
  height: "92vh",
8307
8417
  overflow: "auto",
8418
+ cursor: isPanning ? "grabbing" : "default",
8308
8419
  } },
8309
8420
  React.createElement("div", { ref: contentRef, style: {
8310
8421
  transform: "scale(".concat(zoom, ")"),
8311
8422
  transformOrigin: "top left",
8312
- // transition: "transform 0.1s linear",
8423
+ width: contentWidth,
8424
+ height: contentHeight,
8313
8425
  } }, children))));
8314
8426
  };
8315
- var useZoomContext = function () {
8316
- var context = React.useContext(zoomContext);
8427
+ var useZoomPanContext = function () {
8428
+ var context = React.useContext(zoomPanContext);
8317
8429
  if (!context) {
8318
- throw new Error("useZoomContext must be used within a ZoomContextProvider");
8430
+ throw new Error("useZoomPanContext must be used within a ZoomPanContextProvider");
8319
8431
  }
8320
8432
  return context;
8321
8433
  };
@@ -8325,7 +8437,7 @@ var Text = React.forwardRef(function (_a, ref) {
8325
8437
  var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
8326
8438
  var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
8327
8439
  var textFontSize = useEditorConfiguration().textFontSize;
8328
- var zoom = useZoomContext().zoom;
8440
+ var zoom = useZoomPanContext().zoom;
8329
8441
  var absolutePosition = React.useMemo(function () {
8330
8442
  var _a, _b;
8331
8443
  return {
@@ -8533,7 +8645,8 @@ var IElementLink = function (_a) {
8533
8645
  }), selectedLabelRef = _k[0], setSelectedLabelRef = _k[1];
8534
8646
  var _l = React.useState(false), isSelectedLink = _l[0], setIsSelectedLink = _l[1];
8535
8647
  var _m = React.useContext(paperEventEmitterContext), onPaperClicked = _m.onPaperClicked, onElementSelected = _m.onElementSelected;
8536
- var zoom = useZoomContext().zoom;
8648
+ var zoom = useZoomPanContext().zoom;
8649
+ var paperBounds = useEditorConfiguration().paperBounds;
8537
8650
  var pathRef = React.useRef(null);
8538
8651
  var labelRef = React.useRef(null);
8539
8652
  var sourceLabelRef = React.useRef(null);
@@ -8658,7 +8771,7 @@ var IElementLink = function (_a) {
8658
8771
  var paperPosition_1 = windowsPositionToPaperPosition({
8659
8772
  x: mouseEvent.clientX,
8660
8773
  y: mouseEvent.clientY
8661
- }, container, zoom);
8774
+ }, container, zoom, paperBounds);
8662
8775
  if (draggingPointIndexRef.current !== undefined) { // If dragging a point
8663
8776
  setPoints(function (prev) {
8664
8777
  var temp = __spreadArray([], prev, true);
@@ -8688,7 +8801,7 @@ var IElementLink = function (_a) {
8688
8801
  container === null || container === void 0 ? void 0 : container.removeEventListener('mousemove', handleMouseMove);
8689
8802
  container === null || container === void 0 ? void 0 : container.removeEventListener('mouseup', mouseUp);
8690
8803
  };
8691
- }, [container, isDragging, zoom, points, id, addMovingPoint]);
8804
+ }, [container, isDragging, zoom, points, id, addMovingPoint, paperBounds]);
8692
8805
  React.useEffect(function () {
8693
8806
  console.info("Container changed in link", id);
8694
8807
  }, [addMovingPoint]);
@@ -8824,24 +8937,35 @@ function configureLogger(_a) {
8824
8937
  }
8825
8938
 
8826
8939
  var Ruler = function (_a) {
8827
- var squareSize = _a.squareSize, border = _a.border;
8828
- var numColumns = Math.ceil(3000 / squareSize);
8829
- var numRows = Math.ceil(3000 / squareSize);
8830
- var tableWidth = numColumns * squareSize;
8831
- return (React.createElement("table", { style: { position: 'absolute', zIndex: -1, top: 0, left: 0, borderCollapse: 'collapse', width: tableWidth } },
8832
- React.createElement("tbody", null, Array.from({ length: numRows }).map(function (_, rowIndex) { return (React.createElement("tr", { key: rowIndex, style: { margin: 0, padding: 0 } }, Array.from({ length: numColumns }).map(function (_, colIndex) { return (React.createElement("td", { key: colIndex, style: {
8833
- width: squareSize,
8834
- height: squareSize,
8835
- border: border,
8836
- margin: 0,
8837
- padding: 0,
8838
- boxSizing: 'border-box',
8839
- verticalAlign: 'top',
8840
- position: 'relative',
8841
- fontSize: 12,
8842
- } },
8843
- rowIndex === 0 ? React.createElement("span", { style: { marginLeft: "-12px" } }, colIndex * squareSize) : "",
8844
- colIndex === 0 ? React.createElement("span", { style: { top: "-9px", position: "absolute" } }, rowIndex * squareSize) : "")); }))); }))));
8940
+ // const [offsetX, setOffsetX] = React.useState(0);
8941
+ // const [offsetY, setOffsetY] = React.useState(0);
8942
+ var squareSize = _a.squareSize, _b = _a.gridStroke, gridStroke = _b === void 0 ? 'grey' : _b, bounds = _a.bounds;
8943
+ var minX = bounds.minX, minY = bounds.minY, maxX = bounds.maxX, maxY = bounds.maxY;
8944
+ // const numColumnsInNegative = Math.ceil(Math.abs(minX) / squareSize);
8945
+ // const numRowsInNegative = Math.ceil(Math.abs(minY) / squareSize);
8946
+ var width = maxX - minX;
8947
+ var height = maxY - minY;
8948
+ var cellSize = squareSize;
8949
+ var gridStrokeWidth = 1;
8950
+ var borderStroke = '#000000';
8951
+ var borderStrokeWidth = 2;
8952
+ var patternId = "svg-grid-".concat(cellSize, "-").concat(gridStroke.replace(/[#(), ]/g, ""));
8953
+ // When scrolling/panning/wheeling/zooming, we need to update the offsets of the grid so that it appears fixed relative to the content
8954
+ // Update offsets when bounds change
8955
+ // useLayoutEffect(() => {
8956
+ // console.count("Updating ruler offsets due to bounds/zoom/scrollOffset change");
8957
+ // const newOffsetX = scrollOffset.x / zoom;
8958
+ // const newOffsetY = scrollOffset.y / zoom;
8959
+ // setOffsetX(newOffsetX);
8960
+ // setOffsetY(newOffsetY);
8961
+ // }, [minX, minY, maxX, maxY, zoom, scrollOffset.x, scrollOffset.y]);
8962
+ return (React.createElement("div", { style: { width: width, height: height, position: 'absolute', top: 0, left: 0, zIndex: -1 } },
8963
+ React.createElement("svg", { viewBox: "0 0 ".concat(width, " ").concat(height), width: "100%", height: "100%", preserveAspectRatio: "xMinYMin meet", role: "img", "aria-label": "Grid ".concat(width, " by ").concat(height, " with cell ").concat(cellSize) },
8964
+ React.createElement("defs", null,
8965
+ React.createElement("pattern", { id: patternId, width: cellSize, height: cellSize, patternUnits: "userSpaceOnUse" },
8966
+ React.createElement("path", { d: "M ".concat(cellSize, " 0 L 0 0 0 ").concat(cellSize), fill: "none", stroke: gridStroke, strokeWidth: gridStrokeWidth }))),
8967
+ React.createElement("rect", { x: 0, y: 0, width: width, height: height, fill: "url(#".concat(patternId, ")") }),
8968
+ React.createElement("rect", { x: 0, y: 0, width: width, height: height, fill: "none", stroke: borderStroke, strokeWidth: borderStrokeWidth }))));
8845
8969
  };
8846
8970
 
8847
8971
  var ElementWrapper = React.forwardRef(function (_a, ref) {
@@ -8873,6 +8997,7 @@ var transformPositionToAnchoredPosition = function (position, elementSize, ancho
8873
8997
  };
8874
8998
  var Element = React.forwardRef(function (props, forwardedRef) {
8875
8999
  var _paperEventEmitterContext = React.useContext(paperEventEmitterContext);
9000
+ var paperBounds = useEditorConfiguration().paperBounds;
8876
9001
  // const elementObj = props.element;
8877
9002
  var beingSelected = props.beingSelected, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, onMoving = props.onMoving, onMoved = props.onMoved, onResized = props.onResized, onPortMoved = props.onPortMoved, onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onClick = props.onClick, onContextMenu = props.onContextMenu, onPortContextMenu = props.onPortContextMenu, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onManuallyTriggerRenderPort = props.onManuallyTriggerRenderPort, draggingByDefault = props.draggingByDefault, parentDOM = props.parentDOM;
8878
9003
  var _a = props.element, id = _a.id, cssClass = _a.cssClass; _a.textsPlaceHolderClassName; var portSlideRailSVGClassName = _a.portSlideRailSVGClassName, portMoveableAreas = _a.portMoveableAreas, portDirection = _a.portDirection, defaultPortSize = _a.defaultPortSize; _a.textsPlaceHolderFlexStyle; _a.textsPlaceHolderFlexboxPosition; var resizability = _a.resizability, renderShape = _a.renderShape;
@@ -8888,8 +9013,8 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8888
9013
  var _h = React.useState(false), someElementLinkStarted = _h[0], setSomeElementLinkStarted = _h[1];
8889
9014
  var _j = React.useState(), potentialPortPosition = _j[0], setPotentialPortPosition = _j[1];
8890
9015
  //Zoom
8891
- var zoom = useZoomContext().zoom;
8892
- var zoomRef = React.useRef(zoom);
9016
+ var zoom = useZoomPanContext().zoom;
9017
+ React.useRef(zoom);
8893
9018
  var elementRef = React.useRef(null);
8894
9019
  React.useImperativeHandle(forwardedRef, function () { return elementRef.current; });
8895
9020
  var elementLinkStarted = React.useRef();
@@ -9217,7 +9342,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
9217
9342
  var paper = windowsPositionToPaperPosition({
9218
9343
  x: ev.clientX,
9219
9344
  y: ev.clientY
9220
- }, container, zoom);
9345
+ }, container, zoom, paperBounds);
9221
9346
  var elementAbsPosition_1 = getElementAbsPosition();
9222
9347
  var mousePositionOnElement = {
9223
9348
  x: paper.x - elementAbsPosition_1.x,
@@ -9389,16 +9514,24 @@ var Element = React.forwardRef(function (props, forwardedRef) {
9389
9514
  }, objectX: elementAbsPosition === null || elementAbsPosition === void 0 ? void 0 : elementAbsPosition.x, objectY: elementAbsPosition === null || elementAbsPosition === void 0 ? void 0 : elementAbsPosition.y, width: size.width, height: size.height, zoom: zoom, draggingByDefault: draggingByDefault,
9390
9515
  //movingOffsetThreshold: ELEMENT_MOVING_OFFSET_THRESHOLD,
9391
9516
  onMouseDown: function (ev) {
9392
- windowsPositionToPaperPosition({
9393
- x: ev.clientX,
9394
- y: ev.clientY
9395
- }, container, zoomRef.current);
9517
+ // const paperPosition = windowsPositionToPaperPosition(
9518
+ // {
9519
+ // x: ev.clientX,
9520
+ // y: ev.clientY
9521
+ // },
9522
+ // container as Element,
9523
+ // zoomRef.current
9524
+ // )
9396
9525
  onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(ev, id);
9397
9526
  }, onMouseUp: function (ev) {
9398
- windowsPositionToPaperPosition({
9399
- x: ev.clientX,
9400
- y: ev.clientY
9401
- }, container, zoomRef.current);
9527
+ // const paperPosition = windowsPositionToPaperPosition(
9528
+ // {
9529
+ // x: ev.clientX,
9530
+ // y: ev.clientY
9531
+ // },
9532
+ // container as Element,
9533
+ // zoomRef.current
9534
+ // )
9402
9535
  onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(ev, id);
9403
9536
  }, onMove: function (newX, newY) {
9404
9537
  var _a;
@@ -9710,14 +9843,16 @@ var Paper = function (props) {
9710
9843
  var _j = React.useState(null), selectedElementSVG = _j[0], setSelectedElementSVG = _j[1];
9711
9844
  var _k = React.useState(false), mouseDownedOnPaper = _k[0], setMouseDownedOnPaper = _k[1];
9712
9845
  var paperEventEmitter = React.useContext(paperEventEmitterContext);
9713
- var zoom = useZoomContext().zoom;
9846
+ var zoom = useZoomPanContext().zoom;
9847
+ var paperBounds = useEditorConfiguration().paperBounds;
9848
+ var paperWidth = paperBounds.maxX - paperBounds.minX;
9849
+ var paperHeight = paperBounds.maxY - paperBounds.minY;
9714
9850
  var zoomRef = React.useRef(zoom);
9715
9851
  var paperContainerRef = React.useRef(null);
9716
9852
  var tempLinkRef = React.useRef(tempLink); //Cache tempLink to avoid re-render when tempLink changed
9717
9853
  //const elementsRef = useRef<IElementState[]>([]); //Cache elements to avoid re-render when elements changed
9718
9854
  var linksRef = React.useRef(links); //Cache links to avoid re-render when links changed
9719
9855
  var textsRef = React.useRef(texts); //Cache texts to avoid re-render when texts changed
9720
- var size = props.size;
9721
9856
  var onPortMoved = props.onPortMoved, onPortSelected = props.onPortSelected, onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp,
9722
9857
  //onPortsChanged,
9723
9858
  onPortContextMenu = props.onPortContextMenu, onElementSelected = props.onElementSelected, onElementsChanged = props.onElementsChanged, onElementResized = props.onElementResized, onElementContextMenu = props.onElementContextMenu, onElementMouseUp = props.onElementMouseUp, onElementMouseDown = props.onElementMouseDown, onElementMouseMove = props.onElementMouseMove, onElementMoved = props.onElementMoved, onElementMouseLeave = props.onElementMouseLeave, onElementDeleted = props.onElementDeleted, onLinksChanged = props.onLinksChanged, onLinkSelected = props.onLinkSelected, onTextSelected = props.onTextSelected, onTextsChanged = props.onTextsChanged, manuallyTriggerRenderElementsHandler = props.manuallyTriggerRenderElementsHandler, manuallyTriggerRenderElementHandler = props.manuallyTriggerRenderElementHandler, manuallyTriggerRenderPortHandler = props.manuallyTriggerRenderPortHandler, onCreatingPortByLinking = props.onCreatingPortByLinking, onCreatingLink = props.onCreatingLink, onElementMoving = props.onElementMoving, manuallySelectElementHandler = props.manuallySelectElementHandler, manuallyTriggerDraggingElementHandler = props.manuallyTriggerDraggingElementHandler, manuallyTriggerStartedLinkingHandler = props.manuallyTriggerStartedLinkingHandler;
@@ -10002,7 +10137,7 @@ var Paper = function (props) {
10002
10137
  var _b = windowsPositionToPaperPosition({
10003
10138
  x: ev.clientX,
10004
10139
  y: ev.clientY
10005
- }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
10140
+ }, paperContainerRef.current, zoom, paperBounds), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
10006
10141
  //if there is a temp link, update the temp target point
10007
10142
  if (tempLink) {
10008
10143
  var sourceElementAbsPosition = getAbsolutePosition(tempLink.sourceElement);
@@ -10028,7 +10163,7 @@ var Paper = function (props) {
10028
10163
  var _c = windowsPositionToPaperPosition({
10029
10164
  x: ev.clientX,
10030
10165
  y: ev.clientY
10031
- }, paperContainerRef.current, zoom), xPosOnPaper = _c.x, yPosOnPaper = _c.y;
10166
+ }, paperContainerRef.current, zoom, paperBounds), xPosOnPaper = _c.x, yPosOnPaper = _c.y;
10032
10167
  setMouseDownedOnPaper(true);
10033
10168
  (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
10034
10169
  x: xPosOnPaper,
@@ -10047,7 +10182,7 @@ var Paper = function (props) {
10047
10182
  var _b = windowsPositionToPaperPosition({
10048
10183
  x: ev.clientX,
10049
10184
  y: ev.clientY
10050
- }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
10185
+ }, paperContainerRef.current, zoom, paperBounds), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
10051
10186
  if (mouseDownedOnPaper) {
10052
10187
  setSelectedElement(undefined);
10053
10188
  setSelectedElementSVG(null);
@@ -10196,7 +10331,7 @@ var Paper = function (props) {
10196
10331
  var paperPosition = windowsPositionToPaperPosition({
10197
10332
  x: ev.clientX,
10198
10333
  y: ev.clientY
10199
- }, paperContainerRef.current, zoomRef.current);
10334
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10200
10335
  //broadcast port mouse down to parent component
10201
10336
  if (element) {
10202
10337
  onPortMouseDown === null || onPortMouseDown === void 0 ? void 0 : onPortMouseDown(port, element, paperPosition);
@@ -10212,7 +10347,7 @@ var Paper = function (props) {
10212
10347
  setTempLink(newLink);
10213
10348
  paperEventEmitter.emitElementLinkStarted(newLink);
10214
10349
  }
10215
- }, [paperEventEmitter, elementsState, onPortMouseDown]);
10350
+ }, [paperEventEmitter, elementsState, paperBounds, onPortMouseDown]);
10216
10351
  var createElementLink = React.useCallback(function (sourcePort, sourceElement, targetPort, targetElement) {
10217
10352
  //if no onCreatingLink prop, no link will be created
10218
10353
  if (!onCreatingLink) {
@@ -10234,7 +10369,7 @@ var Paper = function (props) {
10234
10369
  var paperPosition = windowsPositionToPaperPosition({
10235
10370
  x: ev.clientX,
10236
10371
  y: ev.clientY
10237
- }, paperContainerRef.current, zoomRef.current);
10372
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10238
10373
  //broadcast port mouse down to parent component
10239
10374
  if (element) {
10240
10375
  onPortMouseUp === null || onPortMouseUp === void 0 ? void 0 : onPortMouseUp(port, element, paperPosition);
@@ -10263,7 +10398,7 @@ var Paper = function (props) {
10263
10398
  }
10264
10399
  setTempLink(null);
10265
10400
  }
10266
- }, [paperEventEmitter, elementsState, createElementLink, onPortMouseUp, onLinksChanged]);
10401
+ }, [paperEventEmitter, elementsState, paperBounds, createElementLink, onPortMouseUp, onLinksChanged]);
10267
10402
  // const handlePortsChanged = useCallback((ports: IPort[], elementId: string) => {
10268
10403
  // const element = elementsRef.current.find(e => e.id === elementId);
10269
10404
  // if (element) {
@@ -10484,41 +10619,41 @@ var Paper = function (props) {
10484
10619
  var paperPosition = windowsPositionToPaperPosition({
10485
10620
  x: ev.clientX,
10486
10621
  y: ev.clientY
10487
- }, paperContainerRef.current, zoomRef.current);
10622
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10488
10623
  if (element) {
10489
10624
  onElementMouseUp === null || onElementMouseUp === void 0 ? void 0 : onElementMouseUp(ev, element, paperPosition);
10490
10625
  }
10491
- }, [onElementMouseUp, elementsState]);
10626
+ }, [onElementMouseUp, elementsState, paperBounds]);
10492
10627
  var handleMouseDown = React.useCallback(function (ev, elementId) {
10493
10628
  var element = elementsState.elements.find(function (ele) { return ele.id === elementId; });
10494
10629
  var paperPosition = windowsPositionToPaperPosition({
10495
10630
  x: ev.clientX,
10496
10631
  y: ev.clientY
10497
- }, paperContainerRef.current, zoomRef.current);
10632
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10498
10633
  if (element) {
10499
10634
  onElementMouseDown === null || onElementMouseDown === void 0 ? void 0 : onElementMouseDown(ev, element, paperPosition);
10500
10635
  }
10501
- }, [onElementMouseDown, elementsState]);
10636
+ }, [onElementMouseDown, elementsState, paperBounds]);
10502
10637
  var handleMouseMove = React.useCallback(function (ev, elementId) {
10503
10638
  var element = elementsState.elements.find(function (ele) { return ele.id === elementId; });
10504
10639
  var paperPosition = windowsPositionToPaperPosition({
10505
10640
  x: ev.clientX,
10506
10641
  y: ev.clientY
10507
- }, paperContainerRef.current, zoomRef.current);
10642
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10508
10643
  if (element) {
10509
10644
  onElementMouseMove === null || onElementMouseMove === void 0 ? void 0 : onElementMouseMove(ev, element, paperPosition);
10510
10645
  }
10511
- }, [onElementMouseMove, elementsState]);
10646
+ }, [onElementMouseMove, elementsState, paperBounds]);
10512
10647
  var handleMouseLeave = React.useCallback(function (ev, elementId) {
10513
10648
  var element = elementsState.elements.find(function (ele) { return ele.id === elementId; });
10514
10649
  var paperPosition = windowsPositionToPaperPosition({
10515
10650
  x: ev.clientX,
10516
10651
  y: ev.clientY
10517
- }, paperContainerRef.current, zoomRef.current);
10652
+ }, paperContainerRef.current, zoomRef.current, paperBounds);
10518
10653
  if (element) {
10519
10654
  onElementMouseLeave === null || onElementMouseLeave === void 0 ? void 0 : onElementMouseLeave(ev, element, paperPosition);
10520
10655
  }
10521
- }, [onElementMouseLeave, elementsState]);
10656
+ }, [onElementMouseLeave, elementsState, paperBounds]);
10522
10657
  var renderElementInTree = React.useCallback(function (element) {
10523
10658
  var _a;
10524
10659
  logger.info("Rendering element tree for element ".concat(element.id));
@@ -10556,8 +10691,8 @@ var Paper = function (props) {
10556
10691
  });
10557
10692
  }, [elementsState.elementsInTree, renderElementInTree]);
10558
10693
  return (React.createElement("div", { style: { position: "relative" } },
10559
- React.createElement(Ruler, { squareSize: 100, border: '1px dashed grey' }),
10560
- React.createElement("svg", { tabIndex: 0, width: size.width, height: size.height, ref: paperContainerRef, id: "paper-container", onMouseMove: handlePaperMouseMove, onMouseDown: handleMouseDownOnPaper, onMouseUp: handleMouseUpOnPaper },
10694
+ React.createElement(Ruler, { bounds: paperBounds, squareSize: 100 }),
10695
+ React.createElement("svg", { tabIndex: 0, width: paperWidth, height: paperHeight, viewBox: "".concat(paperBounds.minX, " ").concat(paperBounds.minY, " ").concat(paperWidth, " ").concat(paperHeight), ref: paperContainerRef, id: "paper-container", onMouseMove: handlePaperMouseMove, onMouseDown: handleMouseDownOnPaper, onMouseUp: handleMouseUpOnPaper },
10561
10696
  paperContainerRef.current ? ElementsInTree : "",
10562
10697
  links && links.map(function (link, index) {
10563
10698
  if (!link.targetElement || !link.targetPort)
@@ -10576,16 +10711,11 @@ var Paper = function (props) {
10576
10711
  var Paper$1 = React.memo(Paper);
10577
10712
 
10578
10713
  var Editor = function (_a) {
10579
- var editorContext = _a.editorContext, width = _a.width, height = _a.height;
10714
+ var editorContext = _a.editorContext; _a.width; _a.height;
10580
10715
  var _b = React.useState([]), elements = _b[0], setElements = _b[1];
10581
10716
  var _c = React.useState([]), links = _c[0], setLinks = _c[1];
10582
10717
  var _d = React.useState([]), texts = _d[0], setTexts = _d[1];
10583
- if (!width) {
10584
- width = 3000;
10585
- }
10586
- if (!height) {
10587
- height = 3000;
10588
- }
10718
+ var _e = React.useState(editorContext.configuration.paperBounds), bounds = _e[0], setBounds = _e[1];
10589
10719
  var setEditorStates = React.useCallback(function (ctx) {
10590
10720
  setElements(__spreadArray([], ctx.elements, true));
10591
10721
  setLinks(__spreadArray([], ctx.links, true));
@@ -10696,8 +10826,11 @@ var Editor = function (_a) {
10696
10826
  editorContext.onElementRemovedHandler(element.id, parentElementId);
10697
10827
  }, [editorContext]);
10698
10828
  return (React.createElement(EditorConfigurationContextProvider, { value: editorContext.configuration },
10699
- React.createElement(ZoomContextProvider, null,
10700
- 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,
10829
+ React.createElement(ZoomPanContextProvider, { bounds: bounds, paperOrigin: editorContext.configuration.paperOrigin, onExpandBounds: function (bounds) {
10830
+ editorContext.configuration.paperBounds = bounds;
10831
+ setBounds(bounds);
10832
+ } },
10833
+ React.createElement(Paper$1, { key: "paper", elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected,
10701
10834
  //onPortsChanged={handlePortsChanged}
10702
10835
  onPortContextMenu: handlePortContextMenu, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementDeleted: handleElementRemoved, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onElementMoving: handleOnElementMoving, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, manuallyTriggerRenderElementsHandler: editorContext.manuallyTriggerRenderElementsHandler.bind(editorContext), manuallyTriggerRenderElementHandler: editorContext.manuallyTriggerRenderElementHandler.bind(editorContext), manuallyTriggerRenderPortHandler: editorContext.manuallyTriggerRenderPortHandler.bind(editorContext), manuallySelectElementHandler: editorContext.manuallySelectElementHandler.bind(editorContext), manuallyTriggerDraggingElementHandler: editorContext.manuallyTriggerDraggingElementHandler.bind(editorContext), manuallyTriggerStartedLinkingHandler: editorContext.manuallyTriggerStartedLinkingHandler.bind(editorContext) }))));
10703
10836
  };