@dschz/solid-flow 1.0.0-next.7 → 1.0.0-next.8
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/index/index.d.ts +30 -5
- package/dist/index/index.js +321 -220
- package/dist/index/index.jsx +265 -169
- package/dist/styles/index.css +16 -4
- package/package.json +1 -1
package/dist/index/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dynamic, Portal, addEvent, claimElement, className, createComponent, delegateEvents, effect, insert, isServer, memo, mergeProps, ref, setAttribute, setStyleProperty, spread, style, template } from "@solidjs/web";
|
|
2
|
-
import { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, Position as Position$1, ResizeControlVariant, SelectionMode as SelectionMode$1, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, addEdge as addEdge$1, areConnectionMapsEqual, calcAutoPan, calculateNodePosition, clampPosition, clampPositionToParent, createDevWarn, createMarkerIds, elementSelectionKeys, evaluateAbsolutePosition, fitViewport, getBezierEdgeCenter as getBezierEdgeCenter$1, getBezierPath, getBezierPath as getBezierPath$1, getBoundsOfRects, getConnectedEdges, getConnectionStatus, getDimensions, getEdgeCenter as getEdgeCenter$1, getEdgePosition, getEdgeToolbarTransform, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getInternalNodesBounds, getMarkerId, getNodeDimensions, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesBounds as getNodesBounds$1, getNodesInside, getOutgoers, getOverlappingArea, getSmoothStepPath, getSmoothStepPath as getSmoothStepPath$1, getStraightPath, getStraightPath as getStraightPath$1, getViewportForBounds, getViewportForBounds as getViewportForBounds$1, handleConnectionChange, infiniteExtent, initialConnection, isCoordinateExtent, isEdgeBase, isInputDOMNode, isMacOs, isNodeBase, isNumeric, isRectObject, mergeAriaLabelConfig, nodeHasDimensions, nodeToRect, panBy, pointToRendererPoint, rendererPointToPoint, shallowNodeData, snapPosition } from "@xyflow/system";
|
|
2
|
+
import { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, Position as Position$1, ResizeControlVariant, SelectionMode as SelectionMode$1, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, addEdge as addEdge$1, areConnectionMapsEqual, calcAutoPan, calculateNodePosition, clampPosition, clampPositionToParent, createDevWarn, createMarkerIds, elementSelectionKeys, errorMessages, evaluateAbsolutePosition, fitViewport, getBezierEdgeCenter as getBezierEdgeCenter$1, getBezierPath, getBezierPath as getBezierPath$1, getBoundsOfRects, getConnectedEdges, getConnectionStatus, getDimensions, getEdgeCenter as getEdgeCenter$1, getEdgePosition, getEdgeToolbarTransform, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getInternalNodesBounds, getMarkerId, getNodeDimensions, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesBounds as getNodesBounds$1, getNodesInside, getOutgoers, getOverlappingArea, getSmoothStepPath, getSmoothStepPath as getSmoothStepPath$1, getStraightPath, getStraightPath as getStraightPath$1, getViewportForBounds, getViewportForBounds as getViewportForBounds$1, handleConnectionChange, infiniteExtent, initialConnection, isCoordinateExtent, isEdgeBase, isInputDOMNode, isMacOs, isNodeBase, isNumeric, isRectObject, mergeAriaLabelConfig, nodeHasDimensions, nodeToRect, panBy, pointToRendererPoint, rendererPointToPoint, shallowNodeData, snapPosition } from "@xyflow/system";
|
|
3
3
|
import { For, Show, createContext, createEffect, createMemo, createProjection, createSignal, createStore, flush, mapArray, merge, omit, onCleanup, onSettled, snapshot, untrack, useContext } from "solid-js";
|
|
4
4
|
import { createMediaQuery } from "@solid-primitives/media";
|
|
5
5
|
import { createEventListener, createEventListenerMap } from "@solid-primitives/event-listener";
|
|
@@ -65,7 +65,9 @@ function propDefaults(props, defaults) {
|
|
|
65
65
|
const getEdgeId = (connection) => {
|
|
66
66
|
let { source, sourceHandle, target, targetHandle } = connection;
|
|
67
67
|
return `xy-edge__${source}${sourceHandle || ""}-${target}${targetHandle || ""}`;
|
|
68
|
-
}, isEdgeSelectable = (edge, store) => edge.selectable ?? store.defaultEdgeOptions.selectable ?? store.elementsSelectable,
|
|
68
|
+
}, isEdgeSelectable = (edge, store) => edge.selectable ?? store.defaultEdgeOptions.selectable ?? store.elementsSelectable, emitFlowError = (onError, id, message) => {
|
|
69
|
+
onError && onError(id, message);
|
|
70
|
+
}, EdgeLabelRenderer = (props) => {
|
|
69
71
|
let { store } = useInternalSolidFlow(), labelNode = () => store.domNode?.querySelector(".solid-flow__edge-labels");
|
|
70
72
|
return createComponent(Show, {
|
|
71
73
|
get when() {
|
|
@@ -92,7 +94,7 @@ const EdgeLabel = (props) => {
|
|
|
92
94
|
selectEdgeOnClick: !1,
|
|
93
95
|
transparent: !1,
|
|
94
96
|
style: {}
|
|
95
|
-
}), rest = omit(_props, "x", "y", "width", "height", "selectEdgeOnClick", "transparent", "children", "class", "style"), { actions } = useInternalSolidFlow(), id = useEdgeId(), zIndex = () => actions.
|
|
97
|
+
}), rest = omit(_props, "x", "y", "width", "height", "selectEdgeOnClick", "transparent", "children", "class", "style"), { actions } = useInternalSolidFlow(), id = useEdgeId(), zIndex = () => actions.getLayoutedEdge(id())?.zIndex;
|
|
96
98
|
return createComponent(EdgeLabelRenderer, { get children() {
|
|
97
99
|
var _el$ = _tmpl$$34();
|
|
98
100
|
return spread(_el$, mergeProps({
|
|
@@ -455,6 +457,30 @@ const armConnectionGestureLookup = (options) => {
|
|
|
455
457
|
doc.removeEventListener("mousemove", update, !0), doc.removeEventListener("touchmove", update, !0), doc.removeEventListener("mouseup", dispose, !0), doc.removeEventListener("touchend", dispose, !0), lookup.disarm();
|
|
456
458
|
};
|
|
457
459
|
return doc.addEventListener("mousemove", update, !0), doc.addEventListener("touchmove", update, !0), doc.addEventListener("mouseup", dispose, !0), doc.addEventListener("touchend", dispose, !0), lookup;
|
|
460
|
+
}, buildConnectionGestureParams = (options) => {
|
|
461
|
+
let { event, store, actions, gestureLookup } = options;
|
|
462
|
+
return {
|
|
463
|
+
lib: store.lib,
|
|
464
|
+
flowId: store.id,
|
|
465
|
+
domNode: store.domNode,
|
|
466
|
+
autoPanOnConnect: store.autoPanOnConnect,
|
|
467
|
+
autoPanSpeed: store.autoPanSpeed,
|
|
468
|
+
connectionMode: store.connectionMode,
|
|
469
|
+
connectionRadius: store.connectionRadius,
|
|
470
|
+
nodeLookup: gestureLookup,
|
|
471
|
+
cancelConnection: actions.cancelConnection,
|
|
472
|
+
panBy: actions.panBy,
|
|
473
|
+
updateConnection: ((connection) => {
|
|
474
|
+
actions.setConnection(connection), flush();
|
|
475
|
+
}),
|
|
476
|
+
isValidConnection: store.isValidConnection,
|
|
477
|
+
onConnectStart: store.onConnectStart,
|
|
478
|
+
onConnectEnd: store.onConnectEnd,
|
|
479
|
+
getTransform: () => store.transform,
|
|
480
|
+
getFromHandle: () => store.connection.fromHandle,
|
|
481
|
+
dragThreshold: store.connectionDragThreshold,
|
|
482
|
+
handleDomNode: event.currentTarget
|
|
483
|
+
};
|
|
458
484
|
};
|
|
459
485
|
//#endregion
|
|
460
486
|
//#region src/components/edge/EdgeReconnectAnchor.tsx
|
|
@@ -488,25 +514,16 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
488
514
|
connectionRadius: store.connectionRadius
|
|
489
515
|
});
|
|
490
516
|
XYHandle.onPointerDown(event, {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
517
|
+
...buildConnectionGestureParams({
|
|
518
|
+
event,
|
|
519
|
+
store,
|
|
520
|
+
actions,
|
|
521
|
+
gestureLookup
|
|
522
|
+
}),
|
|
494
523
|
nodeId: opposite.nodeId,
|
|
495
524
|
handleId: opposite.handleId,
|
|
496
|
-
autoPanOnConnect: store.autoPanOnConnect,
|
|
497
|
-
connectionMode: store.connectionMode,
|
|
498
|
-
connectionRadius: store.connectionRadius,
|
|
499
|
-
nodeLookup: gestureLookup,
|
|
500
525
|
isTarget: opposite.type === "target",
|
|
501
526
|
edgeUpdaterType: opposite.type,
|
|
502
|
-
cancelConnection: actions.cancelConnection,
|
|
503
|
-
panBy: actions.panBy,
|
|
504
|
-
updateConnection: (connection) => {
|
|
505
|
-
actions.setConnection(connection), flush();
|
|
506
|
-
},
|
|
507
|
-
isValidConnection: store.isValidConnection,
|
|
508
|
-
onConnectStart: store.onConnectStart,
|
|
509
|
-
onConnectEnd: store.onConnectEnd,
|
|
510
527
|
onConnect: (connection) => {
|
|
511
528
|
let newEdge = {
|
|
512
529
|
...edge(),
|
|
@@ -516,12 +533,7 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
516
533
|
},
|
|
517
534
|
onReconnectEnd: (event, connectionState) => {
|
|
518
535
|
setReconnectingState(!1), store.onReconnectEnd?.(event, edge(), opposite.type, connectionState);
|
|
519
|
-
}
|
|
520
|
-
getTransform: () => store.transform,
|
|
521
|
-
getFromHandle: () => store.connection.fromHandle,
|
|
522
|
-
autoPanSpeed: store.autoPanSpeed,
|
|
523
|
-
dragThreshold: store.connectionDragThreshold,
|
|
524
|
-
handleDomNode: event.currentTarget
|
|
536
|
+
}
|
|
525
537
|
});
|
|
526
538
|
};
|
|
527
539
|
return createComponent(EdgeLabel, mergeProps({
|
|
@@ -630,14 +642,22 @@ const A11yDescriptions = () => {
|
|
|
630
642
|
addSelectedEdges,
|
|
631
643
|
handleNodeSelection: (id, unselect, nodeRef) => {
|
|
632
644
|
let node = store.nodes.find((n) => n.id === id);
|
|
633
|
-
|
|
645
|
+
if (!node) {
|
|
646
|
+
emitFlowError(store.onError, "012", errorMessages.error012(id));
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
setSelectionRect(void 0), setSelectionRectMode(void 0), node.selected ? (unselect || node.selected && store.multiselectionKeyPressed) && (unselectNodesAndEdges({
|
|
634
650
|
nodes: [node],
|
|
635
651
|
edges: []
|
|
636
|
-
}), requestAnimationFrame(() => nodeRef?.blur())) : addSelectedNodes([id])
|
|
652
|
+
}), requestAnimationFrame(() => nodeRef?.blur())) : addSelectedNodes([id]);
|
|
637
653
|
},
|
|
638
654
|
handleEdgeSelection: (id) => {
|
|
639
655
|
let edge = edgeLookup[id];
|
|
640
|
-
|
|
656
|
+
if (!edge) {
|
|
657
|
+
emitFlowError(store.onError, "012", errorMessages.error012(id));
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
isEdgeSelectable(edge, store) && (setSelectionRect(void 0), setSelectionRectMode(void 0), edge.selected ? edge.selected && store.multiselectionKeyPressed && unselectNodesAndEdges({
|
|
641
661
|
nodes: [],
|
|
642
662
|
edges: [edge]
|
|
643
663
|
}) : addSelectedEdges([id]));
|
|
@@ -854,7 +874,20 @@ const createMeasurementIngest = ({ setMeasurementsStore, setNodesStore, nodes })
|
|
|
854
874
|
let out = {};
|
|
855
875
|
for (let edge of source.edges) out[edge.id] = edge;
|
|
856
876
|
return out;
|
|
857
|
-
}, {}, { key: "id" })
|
|
877
|
+
}, {}, { key: "id" }), createRowRecordProjection = (rowStores) => {
|
|
878
|
+
let assigned = /* @__PURE__ */ new Map();
|
|
879
|
+
return createProjection((draft) => {
|
|
880
|
+
let seen = /* @__PURE__ */ new Set();
|
|
881
|
+
for (let { id, store } of rowStores()) {
|
|
882
|
+
let row = store.row;
|
|
883
|
+
row && (seen.add(id), assigned.get(id) !== row && (assigned.set(id, row), draft[id] = row));
|
|
884
|
+
}
|
|
885
|
+
for (let id of assigned.keys()) seen.has(id) || (assigned.delete(id), delete draft[id]);
|
|
886
|
+
}, {}, {
|
|
887
|
+
key: null,
|
|
888
|
+
shallow: !0
|
|
889
|
+
});
|
|
890
|
+
};
|
|
858
891
|
function isManualZIndexMode(zIndexMode) {
|
|
859
892
|
return zIndexMode === "manual";
|
|
860
893
|
}
|
|
@@ -898,7 +931,7 @@ const EMPTY_AUTO_INDEX = /* @__PURE__ */ new Map(), createInternalNodes = (sourc
|
|
|
898
931
|
x,
|
|
899
932
|
y
|
|
900
933
|
}, row.internals.z = z;
|
|
901
|
-
} else source.nodes.length;
|
|
934
|
+
} else source.nodes.length, emitFlowError(source.onError, "parent-missing", `Parent node ${userNode.parentId} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);
|
|
902
935
|
}
|
|
903
936
|
return { row };
|
|
904
937
|
}, {}, { key: "id" }), entry = {
|
|
@@ -911,19 +944,8 @@ const EMPTY_AUTO_INDEX = /* @__PURE__ */ new Map(), createInternalNodes = (sourc
|
|
|
911
944
|
id,
|
|
912
945
|
store
|
|
913
946
|
};
|
|
914
|
-
}, { keyed: (userNode) => userNode.id })
|
|
915
|
-
return
|
|
916
|
-
let seen = /* @__PURE__ */ new Set();
|
|
917
|
-
for (let { id, store } of rowStores()) {
|
|
918
|
-
seen.add(id);
|
|
919
|
-
let row = store.row;
|
|
920
|
-
assigned.get(id) !== row && (assigned.set(id, row), draft[id] = row);
|
|
921
|
-
}
|
|
922
|
-
for (let id of assigned.keys()) seen.has(id) || (assigned.delete(id), delete draft[id]);
|
|
923
|
-
}, {}, {
|
|
924
|
-
key: null,
|
|
925
|
-
shallow: !0
|
|
926
|
-
});
|
|
947
|
+
}, { keyed: (userNode) => userNode.id });
|
|
948
|
+
return createRowRecordProjection(rowStores);
|
|
927
949
|
};
|
|
928
950
|
function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, selectedNodeZ, zIndexMode) {
|
|
929
951
|
let { x: parentX, y: parentY } = parentNode.internals.positionAbsolute, childDimensions = getNodeDimensions(childNode), positionWithOrigin = getNodePositionWithOrigin(childNode, nodeOrigin), clampedPosition = isCoordinateExtent(childNode.extent) ? clampPosition(positionWithOrigin, childNode.extent, childDimensions) : positionWithOrigin, absolutePosition = clampPosition({
|
|
@@ -971,18 +993,8 @@ const createLayoutedEdges = (source) => {
|
|
|
971
993
|
let edge = edgeAccessor();
|
|
972
994
|
return { row: buildRow(source, edge) };
|
|
973
995
|
}, { row: null }, { key: "id" })
|
|
974
|
-
}), { keyed: (edge) => edge.id })
|
|
975
|
-
return
|
|
976
|
-
let seen = /* @__PURE__ */ new Set();
|
|
977
|
-
for (let { id, store } of rowStores()) {
|
|
978
|
-
let row = store.row;
|
|
979
|
-
row && (seen.add(id), assigned.get(id) !== row && (assigned.set(id, row), draft[id] = row));
|
|
980
|
-
}
|
|
981
|
-
for (let id of assigned.keys()) seen.has(id) || (assigned.delete(id), delete draft[id]);
|
|
982
|
-
}, {}, {
|
|
983
|
-
key: null,
|
|
984
|
-
shallow: !0
|
|
985
|
-
});
|
|
996
|
+
}), { keyed: (edge) => edge.id });
|
|
997
|
+
return createRowRecordProjection(rowStores);
|
|
986
998
|
}, buildRow = (source, edge) => {
|
|
987
999
|
let sourceNode = source.nodeLookup.get(edge.source), targetNode = source.nodeLookup.get(edge.target);
|
|
988
1000
|
if (!sourceNode || !targetNode) return null;
|
|
@@ -1070,6 +1082,9 @@ const createLayoutedEdges = (source) => {
|
|
|
1070
1082
|
},
|
|
1071
1083
|
get zIndexMode() {
|
|
1072
1084
|
return config().zIndexMode;
|
|
1085
|
+
},
|
|
1086
|
+
get onError() {
|
|
1087
|
+
return config().onFlowError;
|
|
1073
1088
|
}
|
|
1074
1089
|
}), nodeLookup = new RecordMapFacade(internalNodes), initialViewport = getInitialViewport(_props.fitView, _props.initialViewport, _props.width ?? 0, _props.height ?? 0, nodeLookup), [viewportStore, setViewportStore] = createStore(_props.viewport ?? initialViewport);
|
|
1075
1090
|
createEffect(() => config().viewport, (next) => {
|
|
@@ -1097,6 +1112,10 @@ const createLayoutedEdges = (source) => {
|
|
|
1097
1112
|
let state = connection(), toHandle = state.inProgress ? state.toHandle : null, key = toHandle ? connectionKey(toHandle.nodeId, toHandle.type, toHandle.id ?? null) : null;
|
|
1098
1113
|
for (let existing of Object.keys(draft)) existing !== key && delete draft[existing];
|
|
1099
1114
|
key && (draft[key] = state.isValid ? "valid" : "invalid");
|
|
1115
|
+
}, {}, { key: null }), connectionOriginByHandle = createProjection((draft) => {
|
|
1116
|
+
let fromHandle = connection().fromHandle ?? clickConnectStartHandle(), fromKey = fromHandle ? connectionKey(fromHandle.nodeId, fromHandle.type, fromHandle.id ?? null) : null, siblingKey = fromHandle ? connectionKey(fromHandle.nodeId, fromHandle.type === "source" ? "target" : "source", fromHandle.id ?? null) : null;
|
|
1117
|
+
for (let existing of Object.keys(draft)) existing !== fromKey && existing !== siblingKey && delete draft[existing];
|
|
1118
|
+
fromKey && (draft[fromKey] = "from"), siblingKey && (draft[siblingKey] = "excluded");
|
|
1100
1119
|
}, {}, { key: null }), mergedNodeTypes = createMemo(() => ({
|
|
1101
1120
|
...initialNodeTypes,
|
|
1102
1121
|
...config().nodeTypes
|
|
@@ -1128,6 +1147,9 @@ const createLayoutedEdges = (source) => {
|
|
|
1128
1147
|
get connectionTargetByHandle() {
|
|
1129
1148
|
return connectionTargetByHandle;
|
|
1130
1149
|
},
|
|
1150
|
+
get connectionOriginByHandle() {
|
|
1151
|
+
return connectionOriginByHandle;
|
|
1152
|
+
},
|
|
1131
1153
|
get domNode() {
|
|
1132
1154
|
return domNode();
|
|
1133
1155
|
},
|
|
@@ -1266,7 +1288,7 @@ const createLayoutedEdges = (source) => {
|
|
|
1266
1288
|
return store.onError;
|
|
1267
1289
|
},
|
|
1268
1290
|
nodeLookup
|
|
1269
|
-
}), visibleEdgeIds = createMemo(() => Object.keys(layoutedEdges)),
|
|
1291
|
+
}), visibleEdgeIds = createMemo(() => Object.keys(layoutedEdges)), getLayoutedEdge = (id) => layoutedEdges[id], fitView = async (options) => store.panZoom ? await fitViewport({
|
|
1270
1292
|
nodes: nodeLookup,
|
|
1271
1293
|
width: store.width,
|
|
1272
1294
|
height: store.height,
|
|
@@ -1613,7 +1635,7 @@ const createLayoutedEdges = (source) => {
|
|
|
1613
1635
|
parentIds,
|
|
1614
1636
|
connections,
|
|
1615
1637
|
actions: {
|
|
1616
|
-
|
|
1638
|
+
getLayoutedEdge,
|
|
1617
1639
|
applyInitialFitView,
|
|
1618
1640
|
applyMeasurementWrites,
|
|
1619
1641
|
applyNodeChanges,
|
|
@@ -1670,7 +1692,14 @@ const createLayoutedEdges = (source) => {
|
|
|
1670
1692
|
var _tmpl$$30 = /* @__PURE__ */ template("<svg class=solid-flow__edge-wrapper><g>");
|
|
1671
1693
|
/** Internal per-edge wrapper: interaction, a11y, viewport culling, and the dynamic edge component. */
|
|
1672
1694
|
const EdgeWrapper = (props) => {
|
|
1673
|
-
let edgeRef, { store, actions } = useInternalSolidFlow(), edgeId = () => props.edgeId, edge = () => actions.
|
|
1695
|
+
let edgeRef, { store, actions } = useInternalSolidFlow(), edgeId = () => props.edgeId, edge = () => actions.getLayoutedEdge(edgeId()), edgeType = () => edge().type ?? "default", selectable = () => isEdgeSelectable(edge(), store), focusable = () => edge().focusable ?? store.edgesFocusable, edgeTypeValid = () => edgeType() in store.edgeTypes, edgeComponent = () => store.edgeTypes[edgeTypeValid() ? edgeType() : "default"];
|
|
1696
|
+
createEffect(() => ({
|
|
1697
|
+
valid: edgeTypeValid(),
|
|
1698
|
+
edgeType: edgeType()
|
|
1699
|
+
}), ({ valid, edgeType }) => {
|
|
1700
|
+
valid || emitFlowError(store.onError, "011", errorMessages.error011(edgeType));
|
|
1701
|
+
});
|
|
1702
|
+
let markerStartUrl = () => edge().markerStart ? `url('#${getMarkerId(edge().markerStart, store.id)}')` : void 0, markerEndUrl = () => edge().markerEnd ? `url('#${getMarkerId(edge().markerEnd, store.id)}')` : void 0, onClick = (event) => {
|
|
1674
1703
|
selectable() && actions.handleEdgeSelection(edgeId()), props.onEdgeClick?.({
|
|
1675
1704
|
edge: edge(),
|
|
1676
1705
|
event
|
|
@@ -2110,10 +2139,7 @@ const Handle = (props) => {
|
|
|
2110
2139
|
position: "top",
|
|
2111
2140
|
isConnectableStart: !0,
|
|
2112
2141
|
isConnectableEnd: !0
|
|
2113
|
-
}), { store, nodeLookup, connections, actions } = useInternalSolidFlow(), rest = omit(_props, "id", "type", "position", "isConnectable", "isConnectableStart", "isConnectableEnd", "isValidConnection", "onConnect", "onDisconnect", "children", "class", "style"), nodeId = useNodeId(), nodeConnectable = useNodeConnectable(), connectable = () => _props.isConnectable ?? nodeConnectable(), isTarget = () => _props.type === "target", handleId = () => _props.id ?? null,
|
|
2114
|
-
let fromHandle = store.connectionFromHandle;
|
|
2115
|
-
return fromHandle && fromHandle.nodeId === nodeId() && fromHandle.type === _props.type && fromHandle.id === handleId();
|
|
2116
|
-
}, targetState = () => store.connectionTargetByHandle[connectionKey(nodeId(), _props.type, handleId())], connectingTo = () => targetState() !== void 0, isPossibleTargetHandle = () => store.connectionMode === "strict" ? store.connectionFromHandle?.type !== _props.type : nodeId() !== store.connectionFromHandle?.nodeId || handleId() !== store.connectionFromHandle?.id, valid = () => targetState() === "valid", prevConnections = null;
|
|
2142
|
+
}), { store, nodeLookup, connections, actions } = useInternalSolidFlow(), rest = omit(_props, "id", "type", "position", "isConnectable", "isConnectableStart", "isConnectableEnd", "isValidConnection", "onConnect", "onDisconnect", "children", "class", "style"), nodeId = useNodeId(), nodeConnectable = useNodeConnectable(), connectable = () => _props.isConnectable ?? nodeConnectable(), isTarget = () => _props.type === "target", handleId = () => _props.id ?? null, originState = () => store.connectionOriginByHandle[connectionKey(nodeId(), _props.type, handleId())], connectingFrom = () => originState() === "from", targetState = () => store.connectionTargetByHandle[connectionKey(nodeId(), _props.type, handleId())], connectingTo = () => targetState() !== void 0, valid = () => targetState() === "valid", prevConnections = null;
|
|
2117
2143
|
createEffect(() => {
|
|
2118
2144
|
if (!_props.onConnect && !_props.onDisconnect) return null;
|
|
2119
2145
|
let rec = connections[connectionKey(nodeId(), _props.type, _props.id)], map = /* @__PURE__ */ new Map();
|
|
@@ -2139,36 +2165,17 @@ const Handle = (props) => {
|
|
|
2139
2165
|
connectionRadius: store.connectionRadius
|
|
2140
2166
|
});
|
|
2141
2167
|
XYHandle.onPointerDown(event, {
|
|
2168
|
+
...buildConnectionGestureParams({
|
|
2169
|
+
event,
|
|
2170
|
+
store,
|
|
2171
|
+
actions,
|
|
2172
|
+
gestureLookup
|
|
2173
|
+
}),
|
|
2142
2174
|
handleId: handleId(),
|
|
2143
2175
|
nodeId: nodeId(),
|
|
2144
2176
|
isTarget: isTarget(),
|
|
2145
|
-
connectionRadius: store.connectionRadius,
|
|
2146
|
-
domNode: store.domNode,
|
|
2147
|
-
nodeLookup: gestureLookup,
|
|
2148
|
-
connectionMode: store.connectionMode,
|
|
2149
|
-
lib: store.lib,
|
|
2150
|
-
autoPanOnConnect: store.autoPanOnConnect,
|
|
2151
|
-
flowId: store.id,
|
|
2152
2177
|
isValidConnection: _props.isValidConnection ?? store.isValidConnection,
|
|
2153
|
-
|
|
2154
|
-
actions.setConnection(connection), flush();
|
|
2155
|
-
}),
|
|
2156
|
-
cancelConnection: actions.cancelConnection,
|
|
2157
|
-
panBy: actions.panBy,
|
|
2158
|
-
onConnect: onConnectExtended,
|
|
2159
|
-
onConnectStart: (event, startParams) => {
|
|
2160
|
-
store.onConnectStart?.(event, {
|
|
2161
|
-
nodeId: startParams.nodeId,
|
|
2162
|
-
handleId: startParams.handleId,
|
|
2163
|
-
handleType: startParams.handleType
|
|
2164
|
-
});
|
|
2165
|
-
},
|
|
2166
|
-
onConnectEnd: store.onConnectEnd,
|
|
2167
|
-
getTransform: () => store.transform,
|
|
2168
|
-
getFromHandle: () => store.connection.fromHandle,
|
|
2169
|
-
autoPanSpeed: store.autoPanSpeed,
|
|
2170
|
-
dragThreshold: store.connectionDragThreshold,
|
|
2171
|
-
handleDomNode: event.currentTarget
|
|
2178
|
+
onConnect: onConnectExtended
|
|
2172
2179
|
});
|
|
2173
2180
|
}, onClick = (event) => {
|
|
2174
2181
|
if (!nodeId() || !store.clickConnectStartHandle && !_props.isConnectableStart) return;
|
|
@@ -2203,7 +2210,7 @@ const Handle = (props) => {
|
|
|
2203
2210
|
isValid && connection && onConnectExtended(connection);
|
|
2204
2211
|
let connectionClone = structuredClone(snapshot(store.connection));
|
|
2205
2212
|
delete connectionClone.inProgress, connectionClone.toPosition = connectionClone.toHandle ? connectionClone.toHandle.position : null, store.onClickConnectEnd?.(event, connectionClone), actions.setClickConnectStartHandle(void 0);
|
|
2206
|
-
}
|
|
2213
|
+
};
|
|
2207
2214
|
var _el$ = _tmpl$$29();
|
|
2208
2215
|
return spread(_el$, mergeProps(rest, {
|
|
2209
2216
|
role: "button",
|
|
@@ -2246,7 +2253,7 @@ const Handle = (props) => {
|
|
|
2246
2253
|
connectablestart: _props.isConnectableStart,
|
|
2247
2254
|
connectableend: _props.isConnectableEnd,
|
|
2248
2255
|
connectable: !!connectable(),
|
|
2249
|
-
|
|
2256
|
+
excluded: !!originState()
|
|
2250
2257
|
}
|
|
2251
2258
|
];
|
|
2252
2259
|
}
|
|
@@ -2374,7 +2381,7 @@ const NodeWrapper = (props) => {
|
|
|
2374
2381
|
let el = nodeRef();
|
|
2375
2382
|
el && props.resizeObserver?.unobserve(el);
|
|
2376
2383
|
});
|
|
2377
|
-
let nodeId = () => node().id, nodeType = () => node().type ?? "default", deletable = () => node().deletable ?? !0, selectable = () => node().selectable ?? store.elementsSelectable, focusable = () => node().focusable ?? store.nodesFocusable, draggable = () => node().draggable ?? store.nodesDraggable, connectable = () => node().connectable ?? store.nodesConnectable, userNode = () => node().internals.userNode, nodeTypeValid = () => nodeType() in store.nodeTypes, nodeComponent = () => store.nodeTypes[nodeType()], isParentNode = () => !!parentIds[node().id], transform = () => {
|
|
2384
|
+
let nodeId = () => node().id, nodeType = () => node().type ?? "default", deletable = () => node().deletable ?? !0, selectable = () => node().selectable ?? store.elementsSelectable, focusable = () => node().focusable ?? store.nodesFocusable, draggable = () => node().draggable ?? store.nodesDraggable, connectable = () => node().connectable ?? store.nodesConnectable, userNode = () => node().internals.userNode, nodeTypeValid = () => nodeType() in store.nodeTypes, nodeComponent = () => store.nodeTypes[nodeTypeValid() ? nodeType() : "default"], isParentNode = () => !!parentIds[node().id], transform = () => {
|
|
2378
2385
|
let { x, y } = node().internals.positionAbsolute;
|
|
2379
2386
|
return `translate(${x}px, ${y}px)`;
|
|
2380
2387
|
}, sizeStyle = () => {
|
|
@@ -2394,7 +2401,9 @@ const NodeWrapper = (props) => {
|
|
|
2394
2401
|
createEffect(() => ({
|
|
2395
2402
|
valid: nodeTypeValid(),
|
|
2396
2403
|
nodeType: nodeType()
|
|
2397
|
-
}), ({ valid, nodeType }) => {
|
|
2404
|
+
}), ({ valid, nodeType }) => {
|
|
2405
|
+
valid || emitFlowError(store.onError, "003", errorMessages.error003(nodeType));
|
|
2406
|
+
}), createEffect(() => ({
|
|
2398
2407
|
id: node().id,
|
|
2399
2408
|
nodeElement: nodeRef(),
|
|
2400
2409
|
nodeType: nodeType(),
|
|
@@ -2771,21 +2780,29 @@ function useInternalSolidFlow() {
|
|
|
2771
2780
|
var _tmpl$$26 = /* @__PURE__ */ template("<svg class=\"solid-flow__container solid-flow__connectionline\"><g>"), _tmpl$2$2 = /* @__PURE__ */ template("<svg><path class=solid-flow__connection-path fill=none></svg>", 2);
|
|
2772
2781
|
/** Internal component rendering the in-progress connection line. */
|
|
2773
2782
|
const ConnectionLine = (props) => {
|
|
2774
|
-
let { store } = useInternalSolidFlow(), connectionStatus = () => getConnectionStatus(store.connection.isValid)
|
|
2783
|
+
let { store } = useInternalSolidFlow(), connectionStatus = () => getConnectionStatus(store.connection.isValid), inProgress = createMemo(() => {
|
|
2784
|
+
let state = store.connection;
|
|
2785
|
+
return state.inProgress ? state : null;
|
|
2786
|
+
});
|
|
2775
2787
|
return createComponent(Show, {
|
|
2776
2788
|
get when() {
|
|
2777
|
-
return
|
|
2789
|
+
return inProgress();
|
|
2778
2790
|
},
|
|
2779
|
-
|
|
2791
|
+
children: (connection) => (() => {
|
|
2780
2792
|
var _el$ = _tmpl$$26(), _el$2 = _el$.firstChild;
|
|
2781
2793
|
return insert(_el$2, createComponent(Show, {
|
|
2782
2794
|
get when() {
|
|
2783
2795
|
return props.component;
|
|
2784
2796
|
},
|
|
2785
2797
|
get fallback() {
|
|
2786
|
-
return createComponent(InternalConnectionLine, {
|
|
2787
|
-
|
|
2788
|
-
|
|
2798
|
+
return createComponent(InternalConnectionLine, {
|
|
2799
|
+
get style() {
|
|
2800
|
+
return props.style;
|
|
2801
|
+
},
|
|
2802
|
+
get connection() {
|
|
2803
|
+
return connection();
|
|
2804
|
+
}
|
|
2805
|
+
});
|
|
2789
2806
|
},
|
|
2790
2807
|
children: (CustomComponent) => {
|
|
2791
2808
|
let UserConnectionLine = CustomComponent();
|
|
@@ -2797,37 +2814,37 @@ const ConnectionLine = (props) => {
|
|
|
2797
2814
|
return props.style;
|
|
2798
2815
|
},
|
|
2799
2816
|
get fromNode() {
|
|
2800
|
-
return
|
|
2817
|
+
return connection().fromNode;
|
|
2801
2818
|
},
|
|
2802
2819
|
get fromHandle() {
|
|
2803
|
-
return
|
|
2820
|
+
return connection().fromHandle;
|
|
2804
2821
|
},
|
|
2805
2822
|
get fromX() {
|
|
2806
|
-
return
|
|
2823
|
+
return connection().from.x;
|
|
2807
2824
|
},
|
|
2808
2825
|
get fromY() {
|
|
2809
|
-
return
|
|
2826
|
+
return connection().from.y;
|
|
2810
2827
|
},
|
|
2811
2828
|
get toX() {
|
|
2812
|
-
return
|
|
2829
|
+
return connection().to.x;
|
|
2813
2830
|
},
|
|
2814
2831
|
get toY() {
|
|
2815
|
-
return
|
|
2832
|
+
return connection().to.y;
|
|
2816
2833
|
},
|
|
2817
2834
|
get fromPosition() {
|
|
2818
|
-
return
|
|
2835
|
+
return connection().fromPosition;
|
|
2819
2836
|
},
|
|
2820
2837
|
get toPosition() {
|
|
2821
|
-
return
|
|
2838
|
+
return connection().toPosition;
|
|
2822
2839
|
},
|
|
2823
2840
|
get connectionStatus() {
|
|
2824
2841
|
return connectionStatus();
|
|
2825
2842
|
},
|
|
2826
2843
|
get toNode() {
|
|
2827
|
-
return
|
|
2844
|
+
return connection().toNode;
|
|
2828
2845
|
},
|
|
2829
2846
|
get toHandle() {
|
|
2830
|
-
return
|
|
2847
|
+
return connection().toHandle;
|
|
2831
2848
|
}
|
|
2832
2849
|
});
|
|
2833
2850
|
}
|
|
@@ -2839,18 +2856,17 @@ const ConnectionLine = (props) => {
|
|
|
2839
2856
|
}), ({ e, t, a, o }, _p$) => {
|
|
2840
2857
|
e !== _p$?.e && setAttribute(_el$, "width", e), t !== _p$?.t && setAttribute(_el$, "height", t), style(_el$, a, _p$?.a), className(_el$2, o, _p$?.o);
|
|
2841
2858
|
}), _el$;
|
|
2842
|
-
}
|
|
2859
|
+
})()
|
|
2843
2860
|
});
|
|
2844
2861
|
}, InternalConnectionLine = (props) => {
|
|
2845
2862
|
let { store } = useInternalSolidFlow(), path = () => {
|
|
2846
|
-
if (!store.connection.inProgress) return;
|
|
2847
2863
|
let pathParams = {
|
|
2848
|
-
sourceX:
|
|
2849
|
-
sourceY:
|
|
2850
|
-
sourcePosition:
|
|
2851
|
-
targetX:
|
|
2852
|
-
targetY:
|
|
2853
|
-
targetPosition:
|
|
2864
|
+
sourceX: props.connection.from.x,
|
|
2865
|
+
sourceY: props.connection.from.y,
|
|
2866
|
+
sourcePosition: props.connection.fromPosition,
|
|
2867
|
+
targetX: props.connection.to.x,
|
|
2868
|
+
targetY: props.connection.to.y,
|
|
2869
|
+
targetPosition: props.connection.toPosition
|
|
2854
2870
|
};
|
|
2855
2871
|
switch (store.connectionLineType) {
|
|
2856
2872
|
case "default": {
|
|
@@ -2950,25 +2966,32 @@ const MarkerDefinition = () => {
|
|
|
2950
2966
|
})), _el$;
|
|
2951
2967
|
}
|
|
2952
2968
|
});
|
|
2969
|
+
}, createFocusedIdTracker = () => {
|
|
2970
|
+
let [focusedId, setFocusedId] = createSignal(null);
|
|
2971
|
+
return {
|
|
2972
|
+
focusedId,
|
|
2973
|
+
onFocusIn: (event) => {
|
|
2974
|
+
let element = event.target.closest("[data-id]");
|
|
2975
|
+
setFocusedId(element?.getAttribute("data-id") ?? null);
|
|
2976
|
+
},
|
|
2977
|
+
onFocusOut: () => setFocusedId(null)
|
|
2978
|
+
};
|
|
2953
2979
|
};
|
|
2954
2980
|
//#endregion
|
|
2955
2981
|
//#region src/components/container/EdgeRenderer.tsx
|
|
2956
2982
|
var _tmpl$$23 = /* @__PURE__ */ template("<div class=solid-flow__edges><!><!>");
|
|
2957
2983
|
/** Internal renderer iterating the edge id list into `EdgeWrapper`s. */
|
|
2958
2984
|
const EdgeRenderer = (props) => {
|
|
2959
|
-
let { store, actions } = useInternalSolidFlow(),
|
|
2960
|
-
let edgeElement = event.target.closest("[data-id]");
|
|
2961
|
-
setFocusedEdgeId(edgeElement?.getAttribute("data-id") ?? null);
|
|
2962
|
-
};
|
|
2985
|
+
let { store, actions } = useInternalSolidFlow(), { focusedId: focusedEdgeId, onFocusIn, onFocusOut } = createFocusedIdTracker();
|
|
2963
2986
|
var _el$ = _tmpl$$23(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
|
|
2964
|
-
return _el
|
|
2987
|
+
return addEvent(_el$, "focusout", onFocusOut, !0), addEvent(_el$, "focusin", onFocusIn, !0), insert(_el$, createComponent(MarkerDefinition, {}), _el$2), insert(_el$, createComponent(For, {
|
|
2965
2988
|
get each() {
|
|
2966
2989
|
return store.visibleEdgeIds;
|
|
2967
2990
|
},
|
|
2968
2991
|
children: (edgeId) => {
|
|
2969
2992
|
let unmounted = createMemo(() => {
|
|
2970
2993
|
if (!store.onlyRenderVisibleElements || focusedEdgeId() === edgeId) return !1;
|
|
2971
|
-
let edge = actions.
|
|
2994
|
+
let edge = actions.getLayoutedEdge(edgeId);
|
|
2972
2995
|
return !!edge && isEdgeCulled(edge, store.cullingViewport);
|
|
2973
2996
|
});
|
|
2974
2997
|
return createComponent(Show, {
|
|
@@ -3015,12 +3038,9 @@ const NodeRenderer = (props) => {
|
|
|
3015
3038
|
onCleanup(() => {
|
|
3016
3039
|
resizeObserver?.disconnect();
|
|
3017
3040
|
});
|
|
3018
|
-
let
|
|
3019
|
-
let nodeElement = event.target.closest("[data-id]");
|
|
3020
|
-
setFocusedNodeId(nodeElement?.getAttribute("data-id") ?? null);
|
|
3021
|
-
};
|
|
3041
|
+
let { focusedId: focusedNodeId, onFocusIn, onFocusOut } = createFocusedIdTracker();
|
|
3022
3042
|
var _el$ = _tmpl$$22();
|
|
3023
|
-
return _el
|
|
3043
|
+
return addEvent(_el$, "focusout", onFocusOut, !0), addEvent(_el$, "focusin", onFocusIn, !0), insert(_el$, createComponent(For, {
|
|
3024
3044
|
get each() {
|
|
3025
3045
|
return store.visibleNodeIds;
|
|
3026
3046
|
},
|
|
@@ -3083,7 +3103,7 @@ const isSetEqual = (a, b) => {
|
|
|
3083
3103
|
let { store, nodeLookup, edgeLookup, connections, actions } = useInternalSolidFlow(), [containerRef, setContainerRef] = createSignal(), container, containerBounds = null, connectionEndedOnPane = !1, selectionInProgress = !1, selectionSpatialLookup = new GestureSpatialLookup(nodeLookup, 400), selectedNodeIds = /* @__PURE__ */ new Set(), selectedEdgeIds = /* @__PURE__ */ new Set(), autoPanId = 0, position = {
|
|
3084
3104
|
x: 0,
|
|
3085
3105
|
y: 0
|
|
3086
|
-
}, autoPanStarted = !1, autoPanOnSelection = () => props.autoPanOnSelection ?? !0, paneClickDistance = () => props.paneClickDistance ??
|
|
3106
|
+
}, autoPanStarted = !1, autoPanOnSelection = () => props.autoPanOnSelection ?? !0, paneClickDistance = () => props.paneClickDistance ?? 0, _panOnDrag = () => store.panActivationKeyPressed || props.panOnDrag, isSelecting = () => store.selectionKeyPressed || !!store.selectionRect || props.selectionOnDrag && _panOnDrag() !== !0, isSelectionEnabled = () => store.elementsSelectable && (isSelecting() || store.selectionRectMode === "user"), onClick = (event) => {
|
|
3087
3107
|
if (event.target === container) {
|
|
3088
3108
|
if (selectionInProgress || store.connection.inProgress || connectionEndedOnPane) {
|
|
3089
3109
|
selectionInProgress = !1, connectionEndedOnPane = !1;
|
|
@@ -3468,29 +3488,13 @@ const Attribution = (props) => createComponent(Show, {
|
|
|
3468
3488
|
}
|
|
3469
3489
|
});
|
|
3470
3490
|
}
|
|
3471
|
-
})
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
* `flow` and `commands` are stable identities, so destructuring them is safe:
|
|
3479
|
-
* `const { flow, commands } = useSolidFlow()`.
|
|
3480
|
-
*
|
|
3481
|
-
* @public
|
|
3482
|
-
* @returns the flow's read struct and write surface
|
|
3483
|
-
*/
|
|
3484
|
-
function useSolidFlow() {
|
|
3485
|
-
let { flow, commands } = useInternalSolidFlow();
|
|
3486
|
-
return {
|
|
3487
|
-
...commands,
|
|
3488
|
-
flow,
|
|
3489
|
-
commands
|
|
3490
|
-
};
|
|
3491
|
-
}
|
|
3492
|
-
//#endregion
|
|
3493
|
-
//#region src/components/utility/KeyHandler.ts
|
|
3491
|
+
}), MODIFIER_FLAG = {
|
|
3492
|
+
alt: "altKey",
|
|
3493
|
+
control: "ctrlKey",
|
|
3494
|
+
ctrl: "ctrlKey",
|
|
3495
|
+
meta: "metaKey",
|
|
3496
|
+
shift: "shiftKey"
|
|
3497
|
+
};
|
|
3494
3498
|
function isKeyObject(key) {
|
|
3495
3499
|
return typeof key == "object" && !!key;
|
|
3496
3500
|
}
|
|
@@ -3522,18 +3526,13 @@ function matchesKey(event, keyDef) {
|
|
|
3522
3526
|
function matchesKeyArray(event, keyDefs) {
|
|
3523
3527
|
return keyDefs ? (Array.isArray(keyDefs) ? keyDefs : [keyDefs]).some((keyDef) => matchesKey(event, keyDef)) : !1;
|
|
3524
3528
|
}
|
|
3525
|
-
const MODIFIER_FLAG = {
|
|
3526
|
-
alt: "altKey",
|
|
3527
|
-
control: "ctrlKey",
|
|
3528
|
-
ctrl: "ctrlKey",
|
|
3529
|
-
meta: "metaKey",
|
|
3530
|
-
shift: "shiftKey"
|
|
3531
|
-
};
|
|
3532
3529
|
/**
|
|
3533
3530
|
* Whether an event's modifier flags PROVE this key definition cannot be held
|
|
3534
3531
|
* right now: the key itself is a modifier whose flag is off, or one of its
|
|
3535
3532
|
* required modifiers is off. Definitions built on non-modifier keys are never
|
|
3536
|
-
* contradicted (their state isn't derivable from flags).
|
|
3533
|
+
* contradicted (their state isn't derivable from flags). This is the
|
|
3534
|
+
* self-heal for OS overlays that swallow keyups without blurring the window
|
|
3535
|
+
* (upstream xyflow#5679).
|
|
3537
3536
|
*/
|
|
3538
3537
|
function isContradicted(flags, keyDef) {
|
|
3539
3538
|
let keyFlag = MODIFIER_FLAG[getKeyString(keyDef).toLowerCase()];
|
|
@@ -3550,6 +3549,28 @@ function allContradicted(flags, keyDefs) {
|
|
|
3550
3549
|
let keys = Array.isArray(keyDefs) ? keyDefs : [keyDefs];
|
|
3551
3550
|
return keys.length > 0 && keys.every((keyDef) => isContradicted(flags, keyDef));
|
|
3552
3551
|
}
|
|
3552
|
+
//#endregion
|
|
3553
|
+
//#region src/hooks/useSolidFlow.ts
|
|
3554
|
+
/**
|
|
3555
|
+
* Hook for accessing the flow instance: `{ flow, commands }` plus the
|
|
3556
|
+
* commands spread at the top level for upstream familiarity.
|
|
3557
|
+
*
|
|
3558
|
+
* `flow` and `commands` are stable identities, so destructuring them is safe:
|
|
3559
|
+
* `const { flow, commands } = useSolidFlow()`.
|
|
3560
|
+
*
|
|
3561
|
+
* @public
|
|
3562
|
+
* @returns the flow's read struct and write surface
|
|
3563
|
+
*/
|
|
3564
|
+
function useSolidFlow() {
|
|
3565
|
+
let { flow, commands } = useInternalSolidFlow();
|
|
3566
|
+
return {
|
|
3567
|
+
...commands,
|
|
3568
|
+
flow,
|
|
3569
|
+
commands
|
|
3570
|
+
};
|
|
3571
|
+
}
|
|
3572
|
+
//#endregion
|
|
3573
|
+
//#region src/components/utility/KeyHandler.ts
|
|
3553
3574
|
const KeyHandler = (props) => {
|
|
3554
3575
|
let { store, actions } = useInternalSolidFlow(), { deleteElements } = useSolidFlow(), _props = {
|
|
3555
3576
|
get selectionKey() {
|
|
@@ -3660,7 +3681,13 @@ const SolidFlow = (props) => {
|
|
|
3660
3681
|
"solid-flow",
|
|
3661
3682
|
"solid-flow__container",
|
|
3662
3683
|
_props.class,
|
|
3663
|
-
store.colorMode
|
|
3684
|
+
store.colorMode,
|
|
3685
|
+
{
|
|
3686
|
+
connecting: !!store.connectionFromHandle || !!store.clickConnectStartHandle,
|
|
3687
|
+
"connecting-from-source": (store.connectionFromHandle ?? store.clickConnectStartHandle)?.type === "source",
|
|
3688
|
+
"connecting-from-target": (store.connectionFromHandle ?? store.clickConnectStartHandle)?.type === "target",
|
|
3689
|
+
"connection-strict": store.connectionMode === "strict"
|
|
3690
|
+
}
|
|
3664
3691
|
];
|
|
3665
3692
|
},
|
|
3666
3693
|
get style() {
|
|
@@ -3928,8 +3955,8 @@ function useConnection() {
|
|
|
3928
3955
|
* @returns store with an array of nodes
|
|
3929
3956
|
*/
|
|
3930
3957
|
function useNodes() {
|
|
3931
|
-
let {
|
|
3932
|
-
return () =>
|
|
3958
|
+
let { flow } = useInternalSolidFlow();
|
|
3959
|
+
return () => flow.nodes;
|
|
3933
3960
|
}
|
|
3934
3961
|
/**
|
|
3935
3962
|
* Hook for getting the current edges from the store.
|
|
@@ -3938,8 +3965,8 @@ function useNodes() {
|
|
|
3938
3965
|
* @returns store with an array of edges
|
|
3939
3966
|
*/
|
|
3940
3967
|
function useEdges() {
|
|
3941
|
-
let {
|
|
3942
|
-
return () =>
|
|
3968
|
+
let { flow } = useInternalSolidFlow();
|
|
3969
|
+
return () => flow.edges;
|
|
3943
3970
|
}
|
|
3944
3971
|
/**
|
|
3945
3972
|
* Hook for getting the current viewport from the store.
|
|
@@ -3997,6 +4024,52 @@ function useInternalNode(id) {
|
|
|
3997
4024
|
return () => flow.internalNodes[id()];
|
|
3998
4025
|
}
|
|
3999
4026
|
//#endregion
|
|
4027
|
+
//#region src/hooks/useKeyPress.ts
|
|
4028
|
+
/**
|
|
4029
|
+
* Reactive "is this key (combo) held right now?" — the Solid Flow
|
|
4030
|
+
* counterpart of React Flow's `useKeyPress`, usable anywhere (no flow
|
|
4031
|
+
* context required).
|
|
4032
|
+
*
|
|
4033
|
+
* The definition is an Accessor per house convention — `useKeyPress(() =>
|
|
4034
|
+
* "a")`, `useKeyPress(() => ["a", "d"])`, or `useKeyPress(() => ({ key:
|
|
4035
|
+
* "s", modifier: ["meta"] }))`; swapping the definition resets the state.
|
|
4036
|
+
*
|
|
4037
|
+
* Hardened beyond upstream:
|
|
4038
|
+
* - Combos re-activate when the base key is re-pressed while the modifier
|
|
4039
|
+
* stays held (upstream's oldest open key bug, xyflow#2248).
|
|
4040
|
+
* - Stuck modifiers self-heal from the flags later keyboard/pointer/wheel
|
|
4041
|
+
* events carry (OS overlays swallow keyups without blurring — the macOS
|
|
4042
|
+
* screenshot HUD; xyflow#5679), and window blur resets.
|
|
4043
|
+
*/
|
|
4044
|
+
function useKeyPress(keys) {
|
|
4045
|
+
let [pressed, setPressed] = createSignal(!1);
|
|
4046
|
+
if (createEffect(() => keys(), () => {
|
|
4047
|
+
setPressed(!1);
|
|
4048
|
+
}, { defer: !0 }), !isServer) {
|
|
4049
|
+
let reconcile = (event) => {
|
|
4050
|
+
pressed() && allContradicted(event, keys()) && (setPressed(!1), flush());
|
|
4051
|
+
};
|
|
4052
|
+
createEventListenerMap(window, {
|
|
4053
|
+
keydown: (event) => {
|
|
4054
|
+
reconcile(event), matchesKeyArray(event, keys()) && (setPressed(!0), flush());
|
|
4055
|
+
},
|
|
4056
|
+
keyup: (event) => {
|
|
4057
|
+
reconcile(event), matchesKeyArray(event, keys()) && (setPressed(!1), flush());
|
|
4058
|
+
},
|
|
4059
|
+
blur: () => {
|
|
4060
|
+
setPressed(!1), flush();
|
|
4061
|
+
}
|
|
4062
|
+
}), createEventListenerMap(window, {
|
|
4063
|
+
pointerdown: reconcile,
|
|
4064
|
+
wheel: reconcile
|
|
4065
|
+
}, {
|
|
4066
|
+
capture: !0,
|
|
4067
|
+
passive: !0
|
|
4068
|
+
});
|
|
4069
|
+
}
|
|
4070
|
+
return pressed;
|
|
4071
|
+
}
|
|
4072
|
+
//#endregion
|
|
4000
4073
|
//#region src/hooks/useNodeConnections.ts
|
|
4001
4074
|
/**
|
|
4002
4075
|
* Hook to retrieve all edges connected to a node. Can be filtered by handle type and id.
|
|
@@ -4366,7 +4439,7 @@ delegateEvents(["click"]);
|
|
|
4366
4439
|
//#endregion
|
|
4367
4440
|
//#region src/plugins/minimap/MiniMap.tsx
|
|
4368
4441
|
var _tmpl$$3 = /* @__PURE__ */ template("<svg class=solid-flow__minimap-svg role=img><title></title><path class=solid-flow__minimap-mask fill-rule=evenodd pointer-events=none>");
|
|
4369
|
-
const getAttrFunction = (
|
|
4442
|
+
const getAttrFunction = (value) => value instanceof Function ? value : () => value, MiniMap = (props) => {
|
|
4370
4443
|
let { store, nodeLookup } = useInternalSolidFlow(), _props = propDefaults(props, {
|
|
4371
4444
|
position: "bottom-right",
|
|
4372
4445
|
nodeClass: "",
|
|
@@ -4376,19 +4449,41 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4376
4449
|
width: 200,
|
|
4377
4450
|
height: 150,
|
|
4378
4451
|
nodeBorderRadius: 5,
|
|
4452
|
+
offsetScale: 5,
|
|
4379
4453
|
nodeStrokeWidth: 2,
|
|
4380
4454
|
style: {}
|
|
4381
|
-
}), paneProps = omit(_props, "class", "style", "position", "nodeClass", "nodeStrokeColor", "nodeColor", "pannable", "zoomable", "inversePan", "zoomStep", "bgColor", "width", "height", "maskColor", "maskStrokeColor", "maskStrokeWidth", "nodeBorderRadius", "nodeStrokeWidth", "nodeComponent", "onClick", "onNodeClick"), nodeColorFunc = () => _props.nodeColor === void 0 ? void 0 : getAttrFunction(_props.nodeColor), nodeStrokeColorFunc = () => getAttrFunction(_props.nodeStrokeColor), nodeClassFunc = () => getAttrFunction(_props.nodeClass), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision", labelledBy = createMemo(() => `solid-flow__minimap-desc-${store.id}`), viewBB = createMemo(() => ({
|
|
4455
|
+
}), paneProps = omit(_props, "class", "style", "position", "nodeClass", "nodeStrokeColor", "nodeColor", "pannable", "zoomable", "inversePan", "zoomStep", "offsetScale", "bgColor", "width", "height", "maskColor", "maskStrokeColor", "maskStrokeWidth", "nodeBorderRadius", "nodeStrokeWidth", "nodeComponent", "onClick", "onNodeClick"), nodeColorFunc = () => _props.nodeColor === void 0 ? void 0 : getAttrFunction(_props.nodeColor), nodeStrokeColorFunc = () => getAttrFunction(_props.nodeStrokeColor), nodeClassFunc = () => getAttrFunction(_props.nodeClass), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision", labelledBy = createMemo(() => `solid-flow__minimap-desc-${store.id}`), viewBB = createMemo(() => ({
|
|
4382
4456
|
x: -store.viewport.x / store.viewport.zoom,
|
|
4383
4457
|
y: -store.viewport.y / store.viewport.zoom,
|
|
4384
4458
|
width: store.width / store.viewport.zoom,
|
|
4385
4459
|
height: store.height / store.viewport.zoom
|
|
4386
|
-
})),
|
|
4387
|
-
|
|
4388
|
-
if (nodeLookup.size === 0) return view;
|
|
4460
|
+
})), rectsEqual = (a, b) => a === b || !!a && !!b && a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height, sampleBounds = () => untrack(() => {
|
|
4461
|
+
if (nodeLookup.size === 0) return null;
|
|
4389
4462
|
let bounds = getInternalNodesBounds(nodeLookup);
|
|
4390
|
-
return
|
|
4391
|
-
}),
|
|
4463
|
+
return Number.isFinite(bounds.x) && Number.isFinite(bounds.width) ? bounds : null;
|
|
4464
|
+
}), [graphBounds, setGraphBounds] = createSignal(sampleBounds(), { equals: rectsEqual });
|
|
4465
|
+
createEffect(() => store.dragging, (dragging) => {
|
|
4466
|
+
if (!dragging) {
|
|
4467
|
+
setGraphBounds(sampleBounds());
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
let raf = requestAnimationFrame(function tick() {
|
|
4471
|
+
setGraphBounds(sampleBounds()), raf = requestAnimationFrame(tick);
|
|
4472
|
+
});
|
|
4473
|
+
return () => cancelAnimationFrame(raf);
|
|
4474
|
+
}), createEffect(() => ({
|
|
4475
|
+
count: store.nodes.length,
|
|
4476
|
+
initialized: store.nodesInitialized
|
|
4477
|
+
}), () => {
|
|
4478
|
+
setGraphBounds(sampleBounds());
|
|
4479
|
+
}), createEffect(() => null, () => {
|
|
4480
|
+
let interval = setInterval(() => setGraphBounds(sampleBounds()), 500);
|
|
4481
|
+
return () => clearInterval(interval);
|
|
4482
|
+
});
|
|
4483
|
+
let boundingRect = createMemo(() => {
|
|
4484
|
+
let view = viewBB(), bounds = graphBounds();
|
|
4485
|
+
return bounds ? getBoundsOfRects(bounds, view) : view;
|
|
4486
|
+
}), viewScale = createMemo(() => Math.max(boundingRect().width / _props.width, boundingRect().height / _props.height)), getViewWidth = () => viewScale() * _props.width, getViewHeight = () => viewScale() * _props.height, getOffset = () => _props.offsetScale * viewScale(), getX = () => {
|
|
4392
4487
|
let rect = boundingRect();
|
|
4393
4488
|
return rect.x - (getViewWidth() - rect.width) / 2 - getOffset();
|
|
4394
4489
|
}, getY = () => {
|
|
@@ -4462,56 +4557,62 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4462
4557
|
return nodeIds();
|
|
4463
4558
|
},
|
|
4464
4559
|
children: (nodeId) => {
|
|
4465
|
-
let
|
|
4560
|
+
let visibleNode = createMemo(() => {
|
|
4561
|
+
let row = nodeLookup.get(nodeId());
|
|
4562
|
+
return row && nodeHasDimensions(row) && !row.hidden ? row : null;
|
|
4563
|
+
});
|
|
4466
4564
|
return createComponent(Show, {
|
|
4467
4565
|
get when() {
|
|
4468
|
-
return
|
|
4566
|
+
return visibleNode();
|
|
4469
4567
|
},
|
|
4470
|
-
children: (
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4568
|
+
children: (node) => {
|
|
4569
|
+
let dimensions = () => getNodeDimensions(node()), userNode = () => node().internals.userNode;
|
|
4570
|
+
return createComponent(Dynamic, {
|
|
4571
|
+
get component() {
|
|
4572
|
+
return _props.nodeComponent ?? MiniMapNode;
|
|
4573
|
+
},
|
|
4574
|
+
get id() {
|
|
4575
|
+
return nodeId();
|
|
4576
|
+
},
|
|
4577
|
+
get x() {
|
|
4578
|
+
return node().internals.positionAbsolute.x;
|
|
4579
|
+
},
|
|
4580
|
+
get y() {
|
|
4581
|
+
return node().internals.positionAbsolute.y;
|
|
4582
|
+
},
|
|
4583
|
+
get borderRadius() {
|
|
4584
|
+
return _props.nodeBorderRadius;
|
|
4585
|
+
},
|
|
4586
|
+
get strokeWidth() {
|
|
4587
|
+
return _props.nodeStrokeWidth;
|
|
4588
|
+
},
|
|
4589
|
+
shapeRendering,
|
|
4590
|
+
get width() {
|
|
4591
|
+
return dimensions().width;
|
|
4592
|
+
},
|
|
4593
|
+
get height() {
|
|
4594
|
+
return dimensions().height;
|
|
4595
|
+
},
|
|
4596
|
+
get selected() {
|
|
4597
|
+
return node().selected;
|
|
4598
|
+
},
|
|
4599
|
+
get color() {
|
|
4600
|
+
return nodeColorFunc()?.call(null, userNode());
|
|
4601
|
+
},
|
|
4602
|
+
get strokeColor() {
|
|
4603
|
+
return nodeStrokeColorFunc().call(null, userNode());
|
|
4604
|
+
},
|
|
4605
|
+
get class() {
|
|
4606
|
+
return nodeClassFunc().call(null, userNode());
|
|
4607
|
+
},
|
|
4608
|
+
get style() {
|
|
4609
|
+
return node().style;
|
|
4610
|
+
},
|
|
4611
|
+
get onClick() {
|
|
4612
|
+
return _props.onNodeClick ? onSvgNodeClick : void 0;
|
|
4613
|
+
}
|
|
4614
|
+
});
|
|
4615
|
+
}
|
|
4515
4616
|
});
|
|
4516
4617
|
}
|
|
4517
4618
|
}), _el$2.nextSibling), effect(() => ({
|
|
@@ -4710,7 +4811,7 @@ const EdgeToolbar = (props) => {
|
|
|
4710
4811
|
var _tmpl$ = /* @__PURE__ */ template("<div>");
|
|
4711
4812
|
/** Toolbar attached to a node, rendered above the graph so it does not scale with zoom. */
|
|
4712
4813
|
const NodeToolbar = (props) => {
|
|
4713
|
-
let { store
|
|
4814
|
+
let { store, flow, commands } = useInternalSolidFlow(), _props = propDefaults(props, {
|
|
4714
4815
|
offset: 10,
|
|
4715
4816
|
position: "top",
|
|
4716
4817
|
align: "center",
|
|
@@ -4722,7 +4823,7 @@ const NodeToolbar = (props) => {
|
|
|
4722
4823
|
let node = flow.internalNodes[nodeId];
|
|
4723
4824
|
return node && res.push(node), res;
|
|
4724
4825
|
}, []), transform = () => {
|
|
4725
|
-
let nodeRect = getNodesBounds(toolbarNodes());
|
|
4826
|
+
let nodeRect = commands.getNodesBounds(toolbarNodes());
|
|
4726
4827
|
return nodeRect ? getNodeToolbarTransform(nodeRect, store.viewport, _props.position, _props.offset, _props.align) : "";
|
|
4727
4828
|
}, zIndex = () => {
|
|
4728
4829
|
let nodes = toolbarNodes();
|
|
@@ -4762,4 +4863,4 @@ const NodeToolbar = (props) => {
|
|
|
4762
4863
|
});
|
|
4763
4864
|
}, SelectionMode = SelectionMode$1, getEdgeCenter = getEdgeCenter$1, getBezierEdgeCenter = getBezierEdgeCenter$1;
|
|
4764
4865
|
//#endregion
|
|
4765
|
-
export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, MiniMapNode, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection, useEdgeId, useEdges, useInternalNode, useNodeConnections, useNodeId, useNodes, useNodesData, useNodesInitialized, useSolidFlow, useUpdateNodeInternals, useViewport, useViewportInitialized };
|
|
4866
|
+
export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, MiniMapNode, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection, useEdgeId, useEdges, useInternalNode, useKeyPress, useNodeConnections, useNodeId, useNodes, useNodesData, useNodesInitialized, useSolidFlow, useUpdateNodeInternals, useViewport, useViewportInitialized };
|