@xyflow/system 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +123 -93
- package/dist/esm/index.mjs +123 -93
- package/dist/esm/types/edges.d.ts +2 -2
- package/dist/esm/types/edges.d.ts.map +1 -1
- package/dist/esm/types/nodes.d.ts +15 -23
- package/dist/esm/types/nodes.d.ts.map +1 -1
- package/dist/esm/utils/edges/general.d.ts +2 -2
- package/dist/esm/utils/edges/general.d.ts.map +1 -1
- package/dist/esm/utils/edges/positions.d.ts.map +1 -1
- package/dist/esm/utils/general.d.ts +5 -0
- package/dist/esm/utils/general.d.ts.map +1 -1
- package/dist/esm/utils/graph.d.ts +6 -6
- package/dist/esm/utils/graph.d.ts.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/shallow-node-data.d.ts +5 -0
- package/dist/esm/utils/shallow-node-data.d.ts.map +1 -0
- package/dist/esm/xydrag/XYDrag.d.ts +1 -2
- package/dist/esm/xydrag/XYDrag.d.ts.map +1 -1
- package/dist/esm/xyhandle/XYHandle.d.ts.map +1 -1
- package/dist/esm/xyhandle/utils.d.ts +0 -1
- package/dist/esm/xyhandle/utils.d.ts.map +1 -1
- package/dist/esm/xyresizer/XYResizer.d.ts +2 -1
- package/dist/esm/xyresizer/XYResizer.d.ts.map +1 -1
- package/dist/esm/xyresizer/utils.d.ts +5 -3
- package/dist/esm/xyresizer/utils.d.ts.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/types/edges.d.ts +2 -2
- package/dist/umd/types/edges.d.ts.map +1 -1
- package/dist/umd/types/nodes.d.ts +15 -23
- package/dist/umd/types/nodes.d.ts.map +1 -1
- package/dist/umd/utils/edges/general.d.ts +2 -2
- package/dist/umd/utils/edges/general.d.ts.map +1 -1
- package/dist/umd/utils/edges/positions.d.ts.map +1 -1
- package/dist/umd/utils/general.d.ts +5 -0
- package/dist/umd/utils/general.d.ts.map +1 -1
- package/dist/umd/utils/graph.d.ts +6 -6
- package/dist/umd/utils/graph.d.ts.map +1 -1
- package/dist/umd/utils/index.d.ts +1 -0
- package/dist/umd/utils/index.d.ts.map +1 -1
- package/dist/umd/utils/shallow-node-data.d.ts +5 -0
- package/dist/umd/utils/shallow-node-data.d.ts.map +1 -0
- package/dist/umd/xydrag/XYDrag.d.ts +1 -2
- package/dist/umd/xydrag/XYDrag.d.ts.map +1 -1
- package/dist/umd/xyhandle/XYHandle.d.ts.map +1 -1
- package/dist/umd/xyhandle/utils.d.ts +0 -1
- package/dist/umd/xyhandle/utils.d.ts.map +1 -1
- package/dist/umd/xyresizer/XYResizer.d.ts +2 -1
- package/dist/umd/xyresizer/XYResizer.d.ts.map +1 -1
- package/dist/umd/xyresizer/utils.d.ts +5 -3
- package/dist/umd/xyresizer/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -173,8 +173,9 @@ const getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
|
|
|
173
173
|
},
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
const
|
|
177
|
-
const
|
|
176
|
+
const { width, height } = getNodeDimensions(node);
|
|
177
|
+
const offsetX = width * nodeOrigin[0];
|
|
178
|
+
const offsetY = height * nodeOrigin[1];
|
|
178
179
|
const position = {
|
|
179
180
|
x: node.position.x - offsetX,
|
|
180
181
|
y: node.position.y - offsetY,
|
|
@@ -206,8 +207,7 @@ const getNodesBounds = (nodes, params = { nodeOrigin: [0, 0], useRelativePositio
|
|
|
206
207
|
const nodePos = getNodePositionWithOrigin(node, node.origin || params.nodeOrigin);
|
|
207
208
|
return getBoundsOfBoxes(currBox, rectToBox({
|
|
208
209
|
...nodePos[params.useRelativePosition ? 'position' : 'positionAbsolute'],
|
|
209
|
-
|
|
210
|
-
height: node.computed?.height ?? node.height ?? 0,
|
|
210
|
+
...getNodeDimensions(node),
|
|
211
211
|
}));
|
|
212
212
|
}, { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity });
|
|
213
213
|
return boxToRect(box);
|
|
@@ -222,8 +222,8 @@ excludeNonSelectableNodes = false, nodeOrigin = [0, 0]) => {
|
|
|
222
222
|
};
|
|
223
223
|
const visibleNodes = nodes.reduce((res, node) => {
|
|
224
224
|
const { computed, selectable = true, hidden = false } = node;
|
|
225
|
-
const width = computed?.width ?? node.width ?? null;
|
|
226
|
-
const height = computed?.height ?? node.height ?? null;
|
|
225
|
+
const width = computed?.width ?? node.width ?? node.initialWidth ?? null;
|
|
226
|
+
const height = computed?.height ?? node.height ?? node.initialHeight ?? null;
|
|
227
227
|
if ((excludeNonSelectableNodes && !selectable) || hidden) {
|
|
228
228
|
return res;
|
|
229
229
|
}
|
|
@@ -517,6 +517,16 @@ const isMacOs = () => typeof navigator !== 'undefined' && navigator?.userAgent?.
|
|
|
517
517
|
function isCoordinateExtent(extent) {
|
|
518
518
|
return extent !== undefined && extent !== 'parent';
|
|
519
519
|
}
|
|
520
|
+
function getNodeDimensions(node) {
|
|
521
|
+
return {
|
|
522
|
+
width: node.computed?.width ?? node.width ?? node.initialWidth ?? 0,
|
|
523
|
+
height: node.computed?.height ?? node.height ?? node.initialHeight ?? 0,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function nodeHasDimensions(node) {
|
|
527
|
+
return ((node.computed?.width ?? node.width ?? node.initialWidth) !== undefined &&
|
|
528
|
+
(node.computed?.height ?? node.height ?? node.initialHeight) !== undefined);
|
|
529
|
+
}
|
|
520
530
|
|
|
521
531
|
function getPointerPosition(event, { snapGrid = [0, 0], snapToGrid = false, transform }) {
|
|
522
532
|
const { x, y } = getEventPosition(event);
|
|
@@ -838,8 +848,8 @@ function getPoints({ source, sourcePosition = Position.Bottom, target, targetPos
|
|
|
838
848
|
});
|
|
839
849
|
// opposite handle positions, default case
|
|
840
850
|
if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {
|
|
841
|
-
centerX = center.x
|
|
842
|
-
centerY = center.y
|
|
851
|
+
centerX = center.x ?? defaultCenterX;
|
|
852
|
+
centerY = center.y ?? defaultCenterY;
|
|
843
853
|
// --->
|
|
844
854
|
// |
|
|
845
855
|
// >---
|
|
@@ -983,7 +993,8 @@ function getSmoothStepPath({ sourceX, sourceY, sourcePosition = Position.Bottom,
|
|
|
983
993
|
}
|
|
984
994
|
|
|
985
995
|
function isNodeInitialized(node) {
|
|
986
|
-
return !!(node?.[internalsSymbol]?.handleBounds || node?.handles?.length) &&
|
|
996
|
+
return (!!(node?.[internalsSymbol]?.handleBounds || node?.handles?.length) &&
|
|
997
|
+
!!(node?.computed?.width || node?.width || node?.initialWidth));
|
|
987
998
|
}
|
|
988
999
|
function getEdgePosition(params) {
|
|
989
1000
|
const { sourceNode, targetNode } = params;
|
|
@@ -1026,8 +1037,8 @@ function toHandleBounds(handles) {
|
|
|
1026
1037
|
const source = [];
|
|
1027
1038
|
const target = [];
|
|
1028
1039
|
for (const handle of handles) {
|
|
1029
|
-
handle.width = handle.width
|
|
1030
|
-
handle.height = handle.height
|
|
1040
|
+
handle.width = handle.width ?? 1;
|
|
1041
|
+
handle.height = handle.height ?? 1;
|
|
1031
1042
|
if (handle.type === 'source') {
|
|
1032
1043
|
source.push(handle);
|
|
1033
1044
|
}
|
|
@@ -1043,8 +1054,7 @@ function toHandleBounds(handles) {
|
|
|
1043
1054
|
function getHandlePosition(position, node, handle = null) {
|
|
1044
1055
|
const x = (handle?.x ?? 0) + (node.computed?.positionAbsolute?.x ?? 0);
|
|
1045
1056
|
const y = (handle?.y ?? 0) + (node.computed?.positionAbsolute?.y ?? 0);
|
|
1046
|
-
const width = handle
|
|
1047
|
-
const height = handle?.height || (node?.computed?.height ?? node?.height ?? 0);
|
|
1057
|
+
const { width, height } = handle ?? getNodeDimensions(node);
|
|
1048
1058
|
switch (position) {
|
|
1049
1059
|
case Position.Top:
|
|
1050
1060
|
return [x + width / 2, y];
|
|
@@ -1285,6 +1295,20 @@ function updateConnectionLookup(connectionLookup, edgeLookup, edges) {
|
|
|
1285
1295
|
}
|
|
1286
1296
|
}
|
|
1287
1297
|
|
|
1298
|
+
function shallowNodeData(a, b) {
|
|
1299
|
+
const _a = Array.isArray(a) ? a : [a];
|
|
1300
|
+
const _b = Array.isArray(b) ? b : [b];
|
|
1301
|
+
if (_a.length !== _b.length) {
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
for (let i = 0; i < _a.length; i++) {
|
|
1305
|
+
if (_a[i].id !== _b[i].id || _a[i].type !== _b[i].type || !Object.is(_a[i].data, _b[i].data)) {
|
|
1306
|
+
return false;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
return true;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1288
1312
|
function wrapSelectionDragFunc(selectionFunc) {
|
|
1289
1313
|
return (event, _, nodes) => selectionFunc?.(event, nodes);
|
|
1290
1314
|
}
|
|
@@ -1359,19 +1383,19 @@ function getEventHandlerParams({ nodeId, dragItems, nodeLookup, }) {
|
|
|
1359
1383
|
}
|
|
1360
1384
|
|
|
1361
1385
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1362
|
-
function XYDrag({
|
|
1386
|
+
function XYDrag({ onNodeMouseDown, getStoreItems, onDragStart, onDrag, onDragStop, }) {
|
|
1363
1387
|
let lastPos = { x: null, y: null };
|
|
1364
1388
|
let autoPanId = 0;
|
|
1365
1389
|
let dragItems = [];
|
|
1366
1390
|
let autoPanStarted = false;
|
|
1367
1391
|
let mousePosition = { x: 0, y: 0 };
|
|
1368
|
-
let dragEvent = null;
|
|
1369
1392
|
let containerBounds = null;
|
|
1370
1393
|
let dragStarted = false;
|
|
1371
|
-
|
|
1394
|
+
let d3Selection = null;
|
|
1372
1395
|
// public functions
|
|
1373
1396
|
function update({ noDragClassName, handleSelector, domNode, isSelectable, nodeId }) {
|
|
1374
|
-
|
|
1397
|
+
d3Selection = select(domNode);
|
|
1398
|
+
function updateNodes({ x, y }, dragEvent) {
|
|
1375
1399
|
const { nodeLookup, nodeExtent, snapGrid, snapToGrid, nodeOrigin, onNodeDrag, onSelectionDrag, onError, updateNodePositions, } = getStoreItems();
|
|
1376
1400
|
lastPos = { x, y };
|
|
1377
1401
|
let hasChange = false;
|
|
@@ -1417,15 +1441,18 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1417
1441
|
return;
|
|
1418
1442
|
}
|
|
1419
1443
|
updateNodePositions(dragItems, true);
|
|
1420
|
-
|
|
1421
|
-
if (dragEvent && (onDrag || onNodeOrSelectionDrag)) {
|
|
1444
|
+
if (dragEvent && (onDrag || onNodeDrag || (!nodeId && onSelectionDrag))) {
|
|
1422
1445
|
const [currentNode, currentNodes] = getEventHandlerParams({
|
|
1423
1446
|
nodeId,
|
|
1424
1447
|
dragItems,
|
|
1425
1448
|
nodeLookup,
|
|
1426
1449
|
});
|
|
1427
1450
|
onDrag?.(dragEvent, dragItems, currentNode, currentNodes);
|
|
1428
|
-
|
|
1451
|
+
onNodeDrag?.(dragEvent, currentNode, currentNodes);
|
|
1452
|
+
if (!nodeId) {
|
|
1453
|
+
const _onSelectionDrag = wrapSelectionDragFunc(onSelectionDrag);
|
|
1454
|
+
_onSelectionDrag(dragEvent, currentNode, currentNodes);
|
|
1455
|
+
}
|
|
1429
1456
|
}
|
|
1430
1457
|
}
|
|
1431
1458
|
function autoPan() {
|
|
@@ -1438,7 +1465,7 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1438
1465
|
lastPos.x = (lastPos.x ?? 0) - xMovement / transform[2];
|
|
1439
1466
|
lastPos.y = (lastPos.y ?? 0) - yMovement / transform[2];
|
|
1440
1467
|
if (panBy({ x: xMovement, y: yMovement })) {
|
|
1441
|
-
updateNodes(lastPos);
|
|
1468
|
+
updateNodes(lastPos, null);
|
|
1442
1469
|
}
|
|
1443
1470
|
}
|
|
1444
1471
|
autoPanId = requestAnimationFrame(autoPan);
|
|
@@ -1458,15 +1485,18 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1458
1485
|
const pointerPos = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
|
|
1459
1486
|
lastPos = pointerPos;
|
|
1460
1487
|
dragItems = getDragItems(nodes, nodesDraggable, pointerPos, nodeId);
|
|
1461
|
-
|
|
1462
|
-
if (dragItems.length > 0 && (onDragStart || onNodeOrSelectionDragStart)) {
|
|
1488
|
+
if (dragItems.length > 0 && (onDragStart || onNodeDragStart || (!nodeId && onSelectionDragStart))) {
|
|
1463
1489
|
const [currentNode, currentNodes] = getEventHandlerParams({
|
|
1464
1490
|
nodeId,
|
|
1465
1491
|
dragItems,
|
|
1466
1492
|
nodeLookup,
|
|
1467
1493
|
});
|
|
1468
1494
|
onDragStart?.(event.sourceEvent, dragItems, currentNode, currentNodes);
|
|
1469
|
-
|
|
1495
|
+
onNodeDragStart?.(event.sourceEvent, currentNode, currentNodes);
|
|
1496
|
+
if (!nodeId) {
|
|
1497
|
+
const _onSelectionDragStart = wrapSelectionDragFunc(onSelectionDragStart);
|
|
1498
|
+
_onSelectionDragStart(event.sourceEvent, currentNode, currentNodes);
|
|
1499
|
+
}
|
|
1470
1500
|
}
|
|
1471
1501
|
}
|
|
1472
1502
|
const d3DragInstance = drag()
|
|
@@ -1497,9 +1527,9 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1497
1527
|
}
|
|
1498
1528
|
// skip events without movement
|
|
1499
1529
|
if ((lastPos.x !== pointerPos.xSnapped || lastPos.y !== pointerPos.ySnapped) && dragItems && dragStarted) {
|
|
1500
|
-
dragEvent = event.sourceEvent;
|
|
1530
|
+
// dragEvent = event.sourceEvent as MouseEvent;
|
|
1501
1531
|
mousePosition = getEventPosition(event.sourceEvent, containerBounds);
|
|
1502
|
-
updateNodes(pointerPos);
|
|
1532
|
+
updateNodes(pointerPos, event.sourceEvent);
|
|
1503
1533
|
}
|
|
1504
1534
|
})
|
|
1505
1535
|
.on('end', (event) => {
|
|
@@ -1511,16 +1541,19 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1511
1541
|
cancelAnimationFrame(autoPanId);
|
|
1512
1542
|
if (dragItems.length > 0) {
|
|
1513
1543
|
const { nodeLookup, updateNodePositions, onNodeDragStop, onSelectionDragStop } = getStoreItems();
|
|
1514
|
-
const onNodeOrSelectionDragStop = nodeId ? onNodeDragStop : wrapSelectionDragFunc(onSelectionDragStop);
|
|
1515
1544
|
updateNodePositions(dragItems, false);
|
|
1516
|
-
if (onDragStop ||
|
|
1545
|
+
if (onDragStop || onNodeDragStop || (!nodeId && onSelectionDragStop)) {
|
|
1517
1546
|
const [currentNode, currentNodes] = getEventHandlerParams({
|
|
1518
1547
|
nodeId,
|
|
1519
1548
|
dragItems,
|
|
1520
1549
|
nodeLookup,
|
|
1521
1550
|
});
|
|
1522
1551
|
onDragStop?.(event.sourceEvent, dragItems, currentNode, currentNodes);
|
|
1523
|
-
|
|
1552
|
+
onNodeDragStop?.(event.sourceEvent, currentNode, currentNodes);
|
|
1553
|
+
if (!nodeId) {
|
|
1554
|
+
const _onSelectionDragStop = wrapSelectionDragFunc(onSelectionDragStop);
|
|
1555
|
+
_onSelectionDragStop(event.sourceEvent, currentNode, currentNodes);
|
|
1556
|
+
}
|
|
1524
1557
|
}
|
|
1525
1558
|
}
|
|
1526
1559
|
})
|
|
@@ -1534,7 +1567,7 @@ function XYDrag({ domNode, onNodeMouseDown, getStoreItems, onDragStart, onDrag,
|
|
|
1534
1567
|
d3Selection.call(d3DragInstance);
|
|
1535
1568
|
}
|
|
1536
1569
|
function destroy() {
|
|
1537
|
-
d3Selection
|
|
1570
|
+
d3Selection?.on('.drag', null);
|
|
1538
1571
|
}
|
|
1539
1572
|
return {
|
|
1540
1573
|
update,
|
|
@@ -1561,7 +1594,7 @@ function getHandles(node, handleBounds, type, currentHandle) {
|
|
|
1561
1594
|
function getClosestHandle(pos, connectionRadius, handles) {
|
|
1562
1595
|
let closestHandles = [];
|
|
1563
1596
|
let minDistance = Infinity;
|
|
1564
|
-
|
|
1597
|
+
for (const handle of handles) {
|
|
1565
1598
|
const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2));
|
|
1566
1599
|
if (distance <= connectionRadius) {
|
|
1567
1600
|
if (distance < minDistance) {
|
|
@@ -1573,7 +1606,7 @@ function getClosestHandle(pos, connectionRadius, handles) {
|
|
|
1573
1606
|
}
|
|
1574
1607
|
minDistance = distance;
|
|
1575
1608
|
}
|
|
1576
|
-
}
|
|
1609
|
+
}
|
|
1577
1610
|
if (!closestHandles.length) {
|
|
1578
1611
|
return null;
|
|
1579
1612
|
}
|
|
@@ -1609,9 +1642,6 @@ function getHandleType(edgeUpdaterType, handleDomNode) {
|
|
|
1609
1642
|
}
|
|
1610
1643
|
return null;
|
|
1611
1644
|
}
|
|
1612
|
-
function resetRecentHandle(handleDomNode, lib) {
|
|
1613
|
-
handleDomNode?.classList.remove('valid', 'connecting', `${lib}-flow__handle-valid`, `${lib}-flow__handle-connecting`);
|
|
1614
|
-
}
|
|
1615
1645
|
function getConnectionStatus(isInsideConnectionRadius, isHandleValid) {
|
|
1616
1646
|
let connectionStatus = null;
|
|
1617
1647
|
if (isHandleValid) {
|
|
@@ -1637,7 +1667,6 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
|
|
|
1637
1667
|
if (!containerBounds || !handleType) {
|
|
1638
1668
|
return;
|
|
1639
1669
|
}
|
|
1640
|
-
let prevActiveHandle;
|
|
1641
1670
|
let connectionPosition = getEventPosition(event, containerBounds);
|
|
1642
1671
|
let autoPanStarted = false;
|
|
1643
1672
|
let connection = null;
|
|
@@ -1705,16 +1734,6 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
|
|
|
1705
1734
|
connectionStatus: getConnectionStatus(!!closestHandle, isValid),
|
|
1706
1735
|
connectionEndHandle: result.endHandle,
|
|
1707
1736
|
});
|
|
1708
|
-
if (!closestHandle && !isValid && !handleDomNode) {
|
|
1709
|
-
return resetRecentHandle(prevActiveHandle, lib);
|
|
1710
|
-
}
|
|
1711
|
-
if (connection?.source !== connection?.target && handleDomNode) {
|
|
1712
|
-
resetRecentHandle(prevActiveHandle, lib);
|
|
1713
|
-
prevActiveHandle = handleDomNode;
|
|
1714
|
-
handleDomNode.classList.add('connecting', `${lib}-flow__handle-connecting`);
|
|
1715
|
-
handleDomNode.classList.toggle('valid', isValid);
|
|
1716
|
-
handleDomNode.classList.toggle(`${lib}-flow__handle-valid`, isValid);
|
|
1717
|
-
}
|
|
1718
1737
|
}
|
|
1719
1738
|
function onPointerUp(event) {
|
|
1720
1739
|
if ((closestHandle || handleDomNode) && connection && isValid) {
|
|
@@ -1726,7 +1745,6 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
|
|
|
1726
1745
|
if (edgeUpdaterType) {
|
|
1727
1746
|
onEdgeUpdateEnd?.(event);
|
|
1728
1747
|
}
|
|
1729
|
-
resetRecentHandle(prevActiveHandle, lib);
|
|
1730
1748
|
cancelConnection();
|
|
1731
1749
|
cancelAnimationFrame(autoPanId);
|
|
1732
1750
|
autoPanStarted = false;
|
|
@@ -2252,7 +2270,7 @@ function xor(a, b) {
|
|
|
2252
2270
|
}
|
|
2253
2271
|
/**
|
|
2254
2272
|
* Calculates new width & height and x & y of node after resize based on pointer position
|
|
2255
|
-
* @description - Buckle up, this is a chunky one
|
|
2273
|
+
* @description - Buckle up, this is a chunky one... If you want to determine the new dimensions of a node after a resize,
|
|
2256
2274
|
* you have to account for all possible restrictions: min/max width/height of the node, the maximum extent the node is allowed
|
|
2257
2275
|
* to move in (in this case: resize into) determined by the parent node, the minimal extent determined by child nodes
|
|
2258
2276
|
* with expandParent or extent: 'parent' set and oh yeah, these things also have to work with keepAspectRatio!
|
|
@@ -2260,6 +2278,8 @@ function xor(a, b) {
|
|
|
2260
2278
|
* strongest restriction. Because the resize affects x, y and width, height and width, height of a opposing side with keepAspectRatio,
|
|
2261
2279
|
* the resize amount is always kept in distX & distY amount (the distance in mouse movement)
|
|
2262
2280
|
* Instead of clamping each value, we first calculate the biggest 'clamp' (for the lack of a better name) and then apply it to all values.
|
|
2281
|
+
* To complicate things nodeOrigin has to be taken into account as well. This is done by offsetting the nodes as if their origin is [0, 0],
|
|
2282
|
+
* then calculating the restrictions as usual
|
|
2263
2283
|
* @param startValues - starting values of resize
|
|
2264
2284
|
* @param controlDirection - dimensions affected by the resize
|
|
2265
2285
|
* @param pointerPosition - the current pointer position corrected for snapping
|
|
@@ -2267,7 +2287,7 @@ function xor(a, b) {
|
|
|
2267
2287
|
* @param keepAspectRatio - prevent changes of asprect ratio
|
|
2268
2288
|
* @returns x, y, width and height of the node after resize
|
|
2269
2289
|
*/
|
|
2270
|
-
function getDimensionsAfterResize(startValues, controlDirection, pointerPosition, boundaries, keepAspectRatio, extent, childExtent) {
|
|
2290
|
+
function getDimensionsAfterResize(startValues, controlDirection, pointerPosition, boundaries, keepAspectRatio, nodeOrigin, extent, childExtent) {
|
|
2271
2291
|
let { affectsX, affectsY } = controlDirection;
|
|
2272
2292
|
const { isHorizontal, isVertical } = controlDirection;
|
|
2273
2293
|
const isDiagonal = isHorizontal && isVertical;
|
|
@@ -2278,6 +2298,8 @@ function getDimensionsAfterResize(startValues, controlDirection, pointerPosition
|
|
|
2278
2298
|
let distY = Math.floor(isVertical ? ySnapped - startValues.pointerY : 0);
|
|
2279
2299
|
const newWidth = startWidth + (affectsX ? -distX : distX);
|
|
2280
2300
|
const newHeight = startHeight + (affectsY ? -distY : distY);
|
|
2301
|
+
const originOffsetX = -nodeOrigin[0] * startWidth;
|
|
2302
|
+
const originOffsetY = -nodeOrigin[1] * startHeight;
|
|
2281
2303
|
// Check if maxWidth, minWWidth, maxHeight, minHeight are restricting the resize
|
|
2282
2304
|
let clampX = getSizeClamp(newWidth, minWidth, maxWidth);
|
|
2283
2305
|
let clampY = getSizeClamp(newHeight, minHeight, maxHeight);
|
|
@@ -2286,16 +2308,16 @@ function getDimensionsAfterResize(startValues, controlDirection, pointerPosition
|
|
|
2286
2308
|
let xExtentClamp = 0;
|
|
2287
2309
|
let yExtentClamp = 0;
|
|
2288
2310
|
if (affectsX && distX < 0) {
|
|
2289
|
-
xExtentClamp = getLowerExtentClamp(startX + distX, extent[0][0]);
|
|
2311
|
+
xExtentClamp = getLowerExtentClamp(startX + distX + originOffsetX, extent[0][0]);
|
|
2290
2312
|
}
|
|
2291
2313
|
else if (!affectsX && distX > 0) {
|
|
2292
|
-
xExtentClamp = getUpperExtentClamp(startX + newWidth, extent[1][0]);
|
|
2314
|
+
xExtentClamp = getUpperExtentClamp(startX + newWidth + originOffsetX, extent[1][0]);
|
|
2293
2315
|
}
|
|
2294
2316
|
if (affectsY && distY < 0) {
|
|
2295
|
-
yExtentClamp = getLowerExtentClamp(startY + distY, extent[0][1]);
|
|
2317
|
+
yExtentClamp = getLowerExtentClamp(startY + distY + originOffsetY, extent[0][1]);
|
|
2296
2318
|
}
|
|
2297
2319
|
else if (!affectsY && distY > 0) {
|
|
2298
|
-
yExtentClamp = getUpperExtentClamp(startY + newHeight, extent[1][1]);
|
|
2320
|
+
yExtentClamp = getUpperExtentClamp(startY + newHeight + originOffsetY, extent[1][1]);
|
|
2299
2321
|
}
|
|
2300
2322
|
clampX = Math.max(clampX, xExtentClamp);
|
|
2301
2323
|
clampY = Math.max(clampY, yExtentClamp);
|
|
@@ -2329,11 +2351,13 @@ function getDimensionsAfterResize(startValues, controlDirection, pointerPosition
|
|
|
2329
2351
|
if (extent) {
|
|
2330
2352
|
let aspectExtentClamp = 0;
|
|
2331
2353
|
if ((!affectsX && !affectsY) || (affectsX && !affectsY && isDiagonal)) {
|
|
2332
|
-
aspectExtentClamp =
|
|
2354
|
+
aspectExtentClamp =
|
|
2355
|
+
getUpperExtentClamp(startY + originOffsetY + newWidth / aspectRatio, extent[1][1]) * aspectRatio;
|
|
2333
2356
|
}
|
|
2334
2357
|
else {
|
|
2335
2358
|
aspectExtentClamp =
|
|
2336
|
-
getLowerExtentClamp(startY + (affectsX ? distX : -distX) / aspectRatio, extent[0][1]) *
|
|
2359
|
+
getLowerExtentClamp(startY + originOffsetY + (affectsX ? distX : -distX) / aspectRatio, extent[0][1]) *
|
|
2360
|
+
aspectRatio;
|
|
2337
2361
|
}
|
|
2338
2362
|
clampX = Math.max(clampX, aspectExtentClamp);
|
|
2339
2363
|
}
|
|
@@ -2357,11 +2381,13 @@ function getDimensionsAfterResize(startValues, controlDirection, pointerPosition
|
|
|
2357
2381
|
if (extent) {
|
|
2358
2382
|
let aspectExtentClamp = 0;
|
|
2359
2383
|
if ((!affectsX && !affectsY) || (affectsY && !affectsX && isDiagonal)) {
|
|
2360
|
-
aspectExtentClamp =
|
|
2384
|
+
aspectExtentClamp =
|
|
2385
|
+
getUpperExtentClamp(startX + newHeight * aspectRatio + originOffsetX, extent[1][0]) / aspectRatio;
|
|
2361
2386
|
}
|
|
2362
2387
|
else {
|
|
2363
2388
|
aspectExtentClamp =
|
|
2364
|
-
getLowerExtentClamp(startX + (affectsY ? distY : -distY) * aspectRatio, extent[0][0]) /
|
|
2389
|
+
getLowerExtentClamp(startX + (affectsY ? distY : -distY) * aspectRatio + originOffsetX, extent[0][0]) /
|
|
2390
|
+
aspectRatio;
|
|
2365
2391
|
}
|
|
2366
2392
|
clampY = Math.max(clampY, aspectExtentClamp);
|
|
2367
2393
|
}
|
|
@@ -2400,11 +2426,13 @@ function getDimensionsAfterResize(startValues, controlDirection, pointerPosition
|
|
|
2400
2426
|
}
|
|
2401
2427
|
}
|
|
2402
2428
|
}
|
|
2429
|
+
const x = affectsX ? startX + distX : startX;
|
|
2430
|
+
const y = affectsY ? startY + distY : startY;
|
|
2403
2431
|
return {
|
|
2404
2432
|
width: startWidth + (affectsX ? -distX : distX),
|
|
2405
2433
|
height: startHeight + (affectsY ? -distY : distY),
|
|
2406
|
-
x: affectsX ?
|
|
2407
|
-
y: affectsY ?
|
|
2434
|
+
x: nodeOrigin[0] * distX * (!affectsX ? 1 : -1) + x,
|
|
2435
|
+
y: nodeOrigin[1] * distY * (!affectsY ? 1 : -1) + y,
|
|
2408
2436
|
};
|
|
2409
2437
|
}
|
|
2410
2438
|
|
|
@@ -2431,13 +2459,16 @@ function nodeToParentExtent(node) {
|
|
|
2431
2459
|
[node.computed.width, node.computed.height],
|
|
2432
2460
|
];
|
|
2433
2461
|
}
|
|
2434
|
-
function nodeToChildExtent(child, parent) {
|
|
2462
|
+
function nodeToChildExtent(child, parent, nodeOrigin) {
|
|
2463
|
+
const x = parent.position.x + child.position.x;
|
|
2464
|
+
const y = parent.position.y + child.position.y;
|
|
2465
|
+
const width = child.computed.width ?? 0;
|
|
2466
|
+
const height = child.computed.height ?? 0;
|
|
2467
|
+
const originOffsetX = nodeOrigin[0] * width;
|
|
2468
|
+
const originOffsetY = nodeOrigin[1] * height;
|
|
2435
2469
|
return [
|
|
2436
|
-
[
|
|
2437
|
-
[
|
|
2438
|
-
parent.position.x + child.position.x + child.computed.width,
|
|
2439
|
-
parent.position.y + child.position.y + child.computed.height,
|
|
2440
|
-
],
|
|
2470
|
+
[x - originOffsetX, y - originOffsetY],
|
|
2471
|
+
[x + width - originOffsetX, y + height - originOffsetY],
|
|
2441
2472
|
];
|
|
2442
2473
|
}
|
|
2443
2474
|
function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
@@ -2453,7 +2484,7 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
|
2453
2484
|
let childExtent = undefined;
|
|
2454
2485
|
const dragHandler = drag()
|
|
2455
2486
|
.on('start', (event) => {
|
|
2456
|
-
const { nodeLookup, transform, snapGrid, snapToGrid } = getStoreItems();
|
|
2487
|
+
const { nodeLookup, transform, snapGrid, snapToGrid, nodeOrigin } = getStoreItems();
|
|
2457
2488
|
node = nodeLookup.get(nodeId);
|
|
2458
2489
|
if (node) {
|
|
2459
2490
|
const { xSnapped, ySnapped } = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
|
|
@@ -2488,7 +2519,7 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
|
2488
2519
|
extent: child.extent,
|
|
2489
2520
|
});
|
|
2490
2521
|
if (child.extent === 'parent' || child.expandParent) {
|
|
2491
|
-
const extent = nodeToChildExtent(child, node);
|
|
2522
|
+
const extent = nodeToChildExtent(child, node, child.origin ?? nodeOrigin);
|
|
2492
2523
|
if (childExtent) {
|
|
2493
2524
|
childExtent = [
|
|
2494
2525
|
[Math.min(extent[0][0], childExtent[0][0]), Math.min(extent[0][1], childExtent[0][1])],
|
|
@@ -2505,35 +2536,34 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
|
2505
2536
|
}
|
|
2506
2537
|
})
|
|
2507
2538
|
.on('drag', (event) => {
|
|
2508
|
-
const { transform, snapGrid, snapToGrid } = getStoreItems();
|
|
2539
|
+
const { transform, snapGrid, snapToGrid, nodeOrigin: storeNodeOrigin } = getStoreItems();
|
|
2509
2540
|
const pointerPosition = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
|
|
2510
2541
|
const childChanges = [];
|
|
2511
2542
|
if (node) {
|
|
2512
|
-
const change = { ...initChange };
|
|
2513
2543
|
const { x: prevX, y: prevY, width: prevWidth, height: prevHeight } = prevValues;
|
|
2514
|
-
const
|
|
2544
|
+
const change = { ...initChange };
|
|
2545
|
+
const nodeOrigin = node.origin ?? storeNodeOrigin;
|
|
2546
|
+
const { width, height, x, y } = getDimensionsAfterResize(startValues, controlDirection, pointerPosition, boundaries, keepAspectRatio, nodeOrigin, parentExtent, childExtent);
|
|
2515
2547
|
const isWidthChange = width !== prevWidth;
|
|
2516
2548
|
const isHeightChange = height !== prevHeight;
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
if (
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
startValues.y = startValues.y - change.y;
|
|
2536
|
-
}
|
|
2549
|
+
const isXPosChange = x !== prevX && isWidthChange;
|
|
2550
|
+
const isYPosChange = y !== prevY && isHeightChange;
|
|
2551
|
+
if (isXPosChange || isYPosChange || nodeOrigin[0] === 1 || nodeOrigin[1] == 1) {
|
|
2552
|
+
change.isXPosChange = isXPosChange;
|
|
2553
|
+
change.isYPosChange = isYPosChange;
|
|
2554
|
+
change.x = isXPosChange ? x : prevX;
|
|
2555
|
+
change.y = isYPosChange ? y : prevY;
|
|
2556
|
+
prevValues.x = change.x;
|
|
2557
|
+
prevValues.y = change.y;
|
|
2558
|
+
// Fix expandParent when resizing from top/left
|
|
2559
|
+
if (parentNode && node.expandParent) {
|
|
2560
|
+
if (change.x < 0) {
|
|
2561
|
+
prevValues.x = 0;
|
|
2562
|
+
startValues.x = startValues.x - change.x;
|
|
2563
|
+
}
|
|
2564
|
+
if (change.y < 0) {
|
|
2565
|
+
prevValues.y = 0;
|
|
2566
|
+
startValues.y = startValues.y - change.y;
|
|
2537
2567
|
}
|
|
2538
2568
|
}
|
|
2539
2569
|
if (childNodes.length > 0) {
|
|
@@ -2541,8 +2571,8 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
|
2541
2571
|
const yChange = y - prevY;
|
|
2542
2572
|
for (const childNode of childNodes) {
|
|
2543
2573
|
childNode.position = {
|
|
2544
|
-
x: childNode.position.x - xChange,
|
|
2545
|
-
y: childNode.position.y - yChange,
|
|
2574
|
+
x: childNode.position.x - xChange + nodeOrigin[0] * (width - prevWidth),
|
|
2575
|
+
y: childNode.position.y - yChange + nodeOrigin[1] * (height - prevHeight),
|
|
2546
2576
|
};
|
|
2547
2577
|
childChanges.push(childNode);
|
|
2548
2578
|
}
|
|
@@ -2590,4 +2620,4 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange }) {
|
|
|
2590
2620
|
};
|
|
2591
2621
|
}
|
|
2592
2622
|
|
|
2593
|
-
export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, ResizeControlVariant, SelectionMode, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, adoptUserProvidedNodes, areConnectionMapsEqual, boxToRect, calcAutoPan, calculateNodePosition, clamp, clampPosition, createMarkerIds, devWarn, elementSelectionKeys, errorMessages, fitView, getBezierEdgeCenter, getBezierPath, getBoundsOfBoxes, getBoundsOfRects, getConnectedEdges, getDimensions, getEdgeCenter, getEdgePosition, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getMarkerId, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesInside, getOutgoers, getOverlappingArea, getPointerPosition, getPositionWithOrigin, getSmoothStepPath, getStraightPath, getViewportForBounds, handleConnectionChange, infiniteExtent, internalsSymbol, isCoordinateExtent, isEdgeBase, isEdgeVisible, isInputDOMNode, isMacOs, isMouseEvent, isNodeBase, isNumeric, isRectObject, nodeToBox, nodeToRect, panBy, pointToRendererPoint, rectToBox, rendererPointToPoint, snapPosition, updateAbsolutePositions, updateConnectionLookup, updateEdge, updateNodeDimensions };
|
|
2623
|
+
export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, ResizeControlVariant, SelectionMode, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, adoptUserProvidedNodes, areConnectionMapsEqual, boxToRect, calcAutoPan, calculateNodePosition, clamp, clampPosition, createMarkerIds, devWarn, elementSelectionKeys, errorMessages, fitView, getBezierEdgeCenter, getBezierPath, getBoundsOfBoxes, getBoundsOfRects, getConnectedEdges, getDimensions, getEdgeCenter, getEdgePosition, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getMarkerId, getNodeDimensions, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesInside, getOutgoers, getOverlappingArea, getPointerPosition, getPositionWithOrigin, getSmoothStepPath, getStraightPath, getViewportForBounds, handleConnectionChange, infiniteExtent, internalsSymbol, isCoordinateExtent, isEdgeBase, isEdgeVisible, isInputDOMNode, isMacOs, isMouseEvent, isNodeBase, isNumeric, isRectObject, nodeHasDimensions, nodeToBox, nodeToRect, panBy, pointToRendererPoint, rectToBox, rendererPointToPoint, shallowNodeData, snapPosition, updateAbsolutePositions, updateConnectionLookup, updateEdge, updateNodeDimensions };
|